Coverage Report

Created: 2026-11-09 07:20

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
1227
        /*
1228
         * A subquery needs the PHV as a whole, so any outer joins in
1229
         * its ph_eval_at must be formed first.  Other rels can
1230
         * compute the PHV's expression themselves, so they need only
1231
         * the baserels.
1232
         */
1233
0
        if (brel->rtekind == RTE_SUBQUERY)
1234
0
          lateral_relids = bms_add_members(lateral_relids,
1235
0
                           phinfo->ph_eval_at);
1236
0
        else
1237
0
          lateral_relids = bms_add_members(lateral_relids,
1238
0
                           bms_intersect(phinfo->ph_eval_at,
1239
0
                                   root->all_baserels));
1240
0
      }
1241
0
      else
1242
0
        Assert(false);
1243
0
    }
1244
1245
    /* We now have all the simple lateral refs from this rel */
1246
0
    brel->direct_lateral_relids = lateral_relids;
1247
0
    brel->lateral_relids = bms_copy(lateral_relids);
1248
0
  }
1249
1250
  /*
1251
   * Now check for lateral references within PlaceHolderVars, and mark their
1252
   * eval_at rels as having lateral references to the source rels.
1253
   *
1254
   * For a PHV that is due to be evaluated at a baserel, mark its source(s)
1255
   * as direct lateral dependencies of the baserel (adding onto the ones
1256
   * recorded above).  If it's due to be evaluated at a join, mark its
1257
   * source(s) as indirect lateral dependencies of each baserel in the join,
1258
   * ie put them into lateral_relids but not direct_lateral_relids.  This is
1259
   * appropriate because we can't put any such baserel on the outside of a
1260
   * join to one of the PHV's lateral dependencies, but on the other hand we
1261
   * also can't yet join it directly to the dependency.
1262
   */
1263
0
  foreach(lc, root->placeholder_list)
1264
0
  {
1265
0
    PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
1266
0
    Relids    eval_at = phinfo->ph_eval_at;
1267
0
    Relids    lateral_refs;
1268
0
    int     varno;
1269
1270
0
    if (phinfo->ph_lateral == NULL)
1271
0
      continue;     /* PHV is uninteresting if no lateral refs */
1272
1273
0
    found_laterals = true;
1274
1275
    /*
1276
     * Include only baserels not outer joins in the evaluation sites'
1277
     * lateral relids.  This avoids problems when outer join order gets
1278
     * rearranged, and it should still ensure that the lateral values are
1279
     * available when needed.
1280
     */
1281
0
    lateral_refs = bms_intersect(phinfo->ph_lateral, root->all_baserels);
1282
0
    Assert(!bms_is_empty(lateral_refs));
1283
1284
0
    if (bms_get_singleton_member(eval_at, &varno))
1285
0
    {
1286
      /* Evaluation site is a baserel */
1287
0
      RelOptInfo *brel = find_base_rel(root, varno);
1288
1289
0
      brel->direct_lateral_relids =
1290
0
        bms_add_members(brel->direct_lateral_relids,
1291
0
                lateral_refs);
1292
0
      brel->lateral_relids =
1293
0
        bms_add_members(brel->lateral_relids,
1294
0
                lateral_refs);
1295
0
    }
1296
0
    else
1297
0
    {
1298
      /* Evaluation site is a join */
1299
0
      varno = -1;
1300
0
      while ((varno = bms_next_member(eval_at, varno)) >= 0)
1301
0
      {
1302
0
        RelOptInfo *brel = find_base_rel_ignore_join(root, varno);
1303
1304
0
        if (brel == NULL)
1305
0
          continue; /* ignore outer joins in eval_at */
1306
0
        brel->lateral_relids = bms_add_members(brel->lateral_relids,
1307
0
                             lateral_refs);
1308
0
      }
1309
0
    }
1310
0
  }
1311
1312
  /*
1313
   * If we found no actual lateral references, we're done; but reset the
1314
   * hasLateralRTEs flag to avoid useless work later.
1315
   */
1316
0
  if (!found_laterals)
1317
0
  {
1318
0
    root->hasLateralRTEs = false;
1319
0
    return;
1320
0
  }
1321
1322
  /*
1323
   * Calculate the transitive closure of the lateral_relids sets, so that
1324
   * they describe both direct and indirect lateral references.  If relation
1325
   * X references Y laterally, and Y references Z laterally, then we will
1326
   * have to scan X on the inside of a nestloop with Z, so for all intents
1327
   * and purposes X is laterally dependent on Z too.
1328
   *
1329
   * This code is essentially Warshall's algorithm for transitive closure.
1330
   * The outer loop considers each baserel, and propagates its lateral
1331
   * dependencies to those baserels that have a lateral dependency on it.
1332
   */
1333
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1334
0
  {
1335
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1336
0
    Relids    outer_lateral_relids;
1337
0
    Index   rti2;
1338
1339
0
    if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
1340
0
      continue;
1341
1342
    /* need not consider baserel further if it has no lateral refs */
1343
0
    outer_lateral_relids = brel->lateral_relids;
1344
0
    if (outer_lateral_relids == NULL)
1345
0
      continue;
1346
1347
    /* else scan all baserels */
1348
0
    for (rti2 = 1; rti2 < root->simple_rel_array_size; rti2++)
1349
0
    {
1350
0
      RelOptInfo *brel2 = root->simple_rel_array[rti2];
1351
1352
0
      if (brel2 == NULL || brel2->reloptkind != RELOPT_BASEREL)
1353
0
        continue;
1354
1355
      /* if brel2 has lateral ref to brel, propagate brel's refs */
1356
0
      if (bms_is_member(rti, brel2->lateral_relids))
1357
0
        brel2->lateral_relids = bms_add_members(brel2->lateral_relids,
1358
0
                            outer_lateral_relids);
1359
0
    }
1360
0
  }
1361
1362
  /*
1363
   * Now that we've identified all lateral references, mark each baserel
1364
   * with the set of relids of rels that reference it laterally (possibly
1365
   * indirectly) --- that is, the inverse mapping of lateral_relids.
1366
   */
1367
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1368
0
  {
1369
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1370
0
    Relids    lateral_relids;
1371
0
    int     rti2;
1372
1373
0
    if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
1374
0
      continue;
1375
1376
    /* Nothing to do at rels with no lateral refs */
1377
0
    lateral_relids = brel->lateral_relids;
1378
0
    if (bms_is_empty(lateral_relids))
1379
0
      continue;
1380
1381
    /* No rel should have a lateral dependency on itself */
1382
0
    Assert(!bms_is_member(rti, lateral_relids));
1383
1384
    /* Mark this rel's referencees */
1385
0
    rti2 = -1;
1386
0
    while ((rti2 = bms_next_member(lateral_relids, rti2)) >= 0)
1387
0
    {
1388
0
      RelOptInfo *brel2 = root->simple_rel_array[rti2];
1389
1390
0
      if (brel2 == NULL)
1391
0
        continue;   /* must be an OJ */
1392
1393
0
      Assert(brel2->reloptkind == RELOPT_BASEREL);
1394
0
      brel2->lateral_referencers =
1395
0
        bms_add_member(brel2->lateral_referencers, rti);
1396
0
    }
1397
0
  }
1398
0
}
1399
1400
1401
/*****************************************************************************
1402
 *
1403
 *    JOIN TREE PROCESSING
1404
 *
1405
 *****************************************************************************/
1406
1407
/*
1408
 * deconstruct_jointree
1409
 *    Recursively scan the query's join tree for WHERE and JOIN/ON qual
1410
 *    clauses, and add these to the appropriate restrictinfo and joininfo
1411
 *    lists belonging to base RelOptInfos.  Also, add SpecialJoinInfo nodes
1412
 *    to root->join_info_list for any outer joins appearing in the query tree.
1413
 *    Return a "joinlist" data structure showing the join order decisions
1414
 *    that need to be made by make_one_rel().
1415
 *
1416
 * The "joinlist" result is a list of items that are either RangeTblRef
1417
 * jointree nodes or sub-joinlists.  All the items at the same level of
1418
 * joinlist must be joined in an order to be determined by make_one_rel()
1419
 * (note that legal orders may be constrained by SpecialJoinInfo nodes).
1420
 * A sub-joinlist represents a subproblem to be planned separately. Currently
1421
 * sub-joinlists arise only from FULL OUTER JOIN or when collapsing of
1422
 * subproblems is stopped by join_collapse_limit or from_collapse_limit.
1423
 */
1424
List *
1425
deconstruct_jointree(PlannerInfo *root)
1426
0
{
1427
0
  List     *result;
1428
0
  JoinDomain *top_jdomain;
1429
0
  List     *item_list = NIL;
1430
0
  ListCell   *lc;
1431
1432
  /*
1433
   * After this point, no more PlaceHolderInfos may be made, because
1434
   * make_outerjoininfo requires all active placeholders to be present in
1435
   * root->placeholder_list while we crawl up the join tree.
1436
   */
1437
0
  root->placeholdersFrozen = true;
1438
1439
  /* Fetch the already-created top-level join domain for the query */
1440
0
  top_jdomain = linitial_node(JoinDomain, root->join_domains);
1441
0
  top_jdomain->jd_relids = NULL; /* filled during deconstruct_recurse */
1442
1443
  /* Start recursion at top of jointree */
1444
0
  Assert(root->parse->jointree != NULL &&
1445
0
       IsA(root->parse->jointree, FromExpr));
1446
1447
  /* These are filled as we scan the jointree */
1448
0
  root->all_baserels = NULL;
1449
0
  root->outer_join_rels = NULL;
1450
1451
  /* Perform the initial scan of the jointree */
1452
0
  result = deconstruct_recurse(root, (Node *) root->parse->jointree,
1453
0
                 top_jdomain, NULL,
1454
0
                 &item_list);
1455
1456
  /* Now we can form the value of all_query_rels, too */
1457
0
  root->all_query_rels = bms_union(root->all_baserels, root->outer_join_rels);
1458
1459
  /* ... which should match what we computed for the top join domain */
1460
0
  Assert(bms_equal(root->all_query_rels, top_jdomain->jd_relids));
1461
1462
  /* Now scan all the jointree nodes again, and distribute quals */
1463
0
  foreach(lc, item_list)
1464
0
  {
1465
0
    JoinTreeItem *jtitem = (JoinTreeItem *) lfirst(lc);
1466
1467
0
    deconstruct_distribute(root, jtitem);
1468
0
  }
1469
1470
  /*
1471
   * If there were any special joins then we may have some postponed LEFT
1472
   * JOIN clauses to deal with.
1473
   */
1474
0
  if (root->join_info_list)
1475
0
  {
1476
0
    foreach(lc, item_list)
1477
0
    {
1478
0
      JoinTreeItem *jtitem = (JoinTreeItem *) lfirst(lc);
1479
1480
0
      if (jtitem->oj_joinclauses != NIL)
1481
0
        deconstruct_distribute_oj_quals(root, item_list, jtitem);
1482
0
    }
1483
0
  }
1484
1485
  /* Don't need the JoinTreeItems any more */
1486
0
  list_free_deep(item_list);
1487
1488
0
  return result;
1489
0
}
1490
1491
/*
1492
 * deconstruct_recurse
1493
 *    One recursion level of deconstruct_jointree's initial jointree scan.
1494
 *
1495
 * jtnode is the jointree node to examine, and parent_domain is the
1496
 * enclosing join domain.  (We must add all base+OJ relids appearing
1497
 * here or below to parent_domain.)  parent_jtitem is the JoinTreeItem
1498
 * for the parent jointree node, or NULL at the top of the recursion.
1499
 *
1500
 * item_list is an in/out parameter: we add a JoinTreeItem struct to
1501
 * that list for each jointree node, in depth-first traversal order.
1502
 * (Hence, after each call, the last list item corresponds to its jtnode.)
1503
 *
1504
 * Return value is the appropriate joinlist for this jointree node.
1505
 */
1506
static List *
1507
deconstruct_recurse(PlannerInfo *root, Node *jtnode,
1508
          JoinDomain *parent_domain,
1509
          JoinTreeItem *parent_jtitem,
1510
          List **item_list)
1511
0
{
1512
0
  List     *joinlist;
1513
0
  JoinTreeItem *jtitem;
1514
1515
0
  Assert(jtnode != NULL);
1516
1517
  /* Make the new JoinTreeItem, but don't add it to item_list yet */
1518
0
  jtitem = palloc0_object(JoinTreeItem);
1519
0
  jtitem->jtnode = jtnode;
1520
0
  jtitem->jti_parent = parent_jtitem;
1521
1522
0
  if (IsA(jtnode, RangeTblRef))
1523
0
  {
1524
0
    int     varno = ((RangeTblRef *) jtnode)->rtindex;
1525
1526
    /* Fill all_baserels as we encounter baserel jointree nodes */
1527
0
    root->all_baserels = bms_add_member(root->all_baserels, varno);
1528
    /* This node belongs to parent_domain */
1529
0
    jtitem->jdomain = parent_domain;
1530
0
    parent_domain->jd_relids = bms_add_member(parent_domain->jd_relids,
1531
0
                          varno);
1532
    /* qualscope is just the one RTE */
1533
0
    jtitem->qualscope = bms_make_singleton(varno);
1534
    /* A single baserel does not create an inner join */
1535
0
    jtitem->inner_join_rels = NULL;
1536
0
    joinlist = list_make1(jtnode);
1537
0
  }
1538
0
  else if (IsA(jtnode, FromExpr))
1539
0
  {
1540
0
    FromExpr   *f = (FromExpr *) jtnode;
1541
0
    int     remaining;
1542
0
    ListCell   *l;
1543
1544
    /* This node belongs to parent_domain, as do its children */
1545
0
    jtitem->jdomain = parent_domain;
1546
1547
    /*
1548
     * Recurse to handle child nodes, and compute output joinlist.  We
1549
     * collapse subproblems into a single joinlist whenever the resulting
1550
     * joinlist wouldn't exceed from_collapse_limit members.  Also, always
1551
     * collapse one-element subproblems, since that won't lengthen the
1552
     * joinlist anyway.
1553
     */
1554
0
    jtitem->qualscope = NULL;
1555
0
    jtitem->inner_join_rels = NULL;
1556
0
    joinlist = NIL;
1557
0
    remaining = list_length(f->fromlist);
1558
0
    foreach(l, f->fromlist)
1559
0
    {
1560
0
      JoinTreeItem *sub_item;
1561
0
      List     *sub_joinlist;
1562
0
      int     sub_members;
1563
1564
0
      sub_joinlist = deconstruct_recurse(root, lfirst(l),
1565
0
                         parent_domain,
1566
0
                         jtitem,
1567
0
                         item_list);
1568
0
      sub_item = (JoinTreeItem *) llast(*item_list);
1569
0
      jtitem->qualscope = bms_add_members(jtitem->qualscope,
1570
0
                        sub_item->qualscope);
1571
0
      jtitem->inner_join_rels = sub_item->inner_join_rels;
1572
0
      sub_members = list_length(sub_joinlist);
1573
0
      remaining--;
1574
0
      if (sub_members <= 1 ||
1575
0
        list_length(joinlist) + sub_members + remaining <= from_collapse_limit)
1576
0
        joinlist = list_concat(joinlist, sub_joinlist);
1577
0
      else
1578
0
        joinlist = lappend(joinlist, sub_joinlist);
1579
0
    }
1580
1581
    /*
1582
     * A FROM with more than one list element is an inner join subsuming
1583
     * all below it, so we should report inner_join_rels = qualscope. If
1584
     * there was exactly one element, we should (and already did) report
1585
     * whatever its inner_join_rels were.  If there were no elements (is
1586
     * that still possible?) the initialization before the loop fixed it.
1587
     */
1588
0
    if (list_length(f->fromlist) > 1)
1589
0
      jtitem->inner_join_rels = jtitem->qualscope;
1590
0
  }
1591
0
  else if (IsA(jtnode, JoinExpr))
1592
0
  {
1593
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1594
0
    JoinDomain *child_domain,
1595
0
           *fj_domain;
1596
0
    JoinTreeItem *left_item,
1597
0
           *right_item;
1598
0
    List     *leftjoinlist,
1599
0
           *rightjoinlist;
1600
1601
0
    switch (j->jointype)
1602
0
    {
1603
0
      case JOIN_INNER:
1604
        /* This node belongs to parent_domain, as do its children */
1605
0
        jtitem->jdomain = parent_domain;
1606
        /* Recurse */
1607
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1608
0
                           parent_domain,
1609
0
                           jtitem,
1610
0
                           item_list);
1611
0
        left_item = (JoinTreeItem *) llast(*item_list);
1612
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1613
0
                          parent_domain,
1614
0
                          jtitem,
1615
0
                          item_list);
1616
0
        right_item = (JoinTreeItem *) llast(*item_list);
1617
        /* Compute qualscope etc */
1618
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1619
0
                        right_item->qualscope);
1620
0
        jtitem->inner_join_rels = jtitem->qualscope;
1621
0
        jtitem->left_rels = left_item->qualscope;
1622
0
        jtitem->right_rels = right_item->qualscope;
1623
        /* Inner join adds no restrictions for quals */
1624
0
        jtitem->nonnullable_rels = NULL;
1625
0
        break;
1626
0
      case JOIN_LEFT:
1627
0
      case JOIN_ANTI:
1628
        /* Make new join domain for my quals and the RHS */
1629
0
        child_domain = makeNode(JoinDomain);
1630
0
        child_domain->jd_relids = NULL; /* filled by recursion */
1631
0
        root->join_domains = lappend(root->join_domains, child_domain);
1632
0
        jtitem->jdomain = child_domain;
1633
        /* Recurse */
1634
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1635
0
                           parent_domain,
1636
0
                           jtitem,
1637
0
                           item_list);
1638
0
        left_item = (JoinTreeItem *) llast(*item_list);
1639
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1640
0
                          child_domain,
1641
0
                          jtitem,
1642
0
                          item_list);
1643
0
        right_item = (JoinTreeItem *) llast(*item_list);
1644
        /* Compute join domain contents, qualscope etc */
1645
0
        parent_domain->jd_relids =
1646
0
          bms_add_members(parent_domain->jd_relids,
1647
0
                  child_domain->jd_relids);
1648
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1649
0
                        right_item->qualscope);
1650
0
        Assert(j->rtindex != 0);
1651
0
        parent_domain->jd_relids =
1652
0
          bms_add_member(parent_domain->jd_relids,
1653
0
                   j->rtindex);
1654
0
        jtitem->qualscope = bms_add_member(jtitem->qualscope,
1655
0
                           j->rtindex);
1656
0
        root->outer_join_rels = bms_add_member(root->outer_join_rels,
1657
0
                             j->rtindex);
1658
0
        mark_rels_nulled_by_join(root, j->rtindex,
1659
0
                     right_item->qualscope);
1660
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1661
0
                          right_item->inner_join_rels);
1662
0
        jtitem->left_rels = left_item->qualscope;
1663
0
        jtitem->right_rels = right_item->qualscope;
1664
0
        jtitem->nonnullable_rels = left_item->qualscope;
1665
0
        break;
1666
0
      case JOIN_SEMI:
1667
        /* This node belongs to parent_domain, as do its children */
1668
0
        jtitem->jdomain = parent_domain;
1669
        /* Recurse */
1670
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1671
0
                           parent_domain,
1672
0
                           jtitem,
1673
0
                           item_list);
1674
0
        left_item = (JoinTreeItem *) llast(*item_list);
1675
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1676
0
                          parent_domain,
1677
0
                          jtitem,
1678
0
                          item_list);
1679
0
        right_item = (JoinTreeItem *) llast(*item_list);
1680
        /* Compute qualscope etc */
1681
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1682
0
                        right_item->qualscope);
1683
        /* SEMI join never has rtindex, so don't add to anything */
1684
0
        Assert(j->rtindex == 0);
1685
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1686
0
                          right_item->inner_join_rels);
1687
0
        jtitem->left_rels = left_item->qualscope;
1688
0
        jtitem->right_rels = right_item->qualscope;
1689
        /* Semi join adds no restrictions for quals */
1690
0
        jtitem->nonnullable_rels = NULL;
1691
0
        break;
1692
0
      case JOIN_FULL:
1693
        /* The FULL JOIN's quals need their very own domain */
1694
0
        fj_domain = makeNode(JoinDomain);
1695
0
        root->join_domains = lappend(root->join_domains, fj_domain);
1696
0
        jtitem->jdomain = fj_domain;
1697
        /* Recurse, giving each side its own join domain */
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
        leftjoinlist = deconstruct_recurse(root, j->larg,
1702
0
                           child_domain,
1703
0
                           jtitem,
1704
0
                           item_list);
1705
0
        left_item = (JoinTreeItem *) llast(*item_list);
1706
0
        fj_domain->jd_relids = bms_copy(child_domain->jd_relids);
1707
0
        child_domain = makeNode(JoinDomain);
1708
0
        child_domain->jd_relids = NULL; /* filled by recursion */
1709
0
        root->join_domains = lappend(root->join_domains, child_domain);
1710
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1711
0
                          child_domain,
1712
0
                          jtitem,
1713
0
                          item_list);
1714
0
        right_item = (JoinTreeItem *) llast(*item_list);
1715
        /* Compute qualscope etc */
1716
0
        fj_domain->jd_relids = bms_add_members(fj_domain->jd_relids,
1717
0
                             child_domain->jd_relids);
1718
0
        parent_domain->jd_relids = bms_add_members(parent_domain->jd_relids,
1719
0
                               fj_domain->jd_relids);
1720
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1721
0
                        right_item->qualscope);
1722
0
        Assert(j->rtindex != 0);
1723
0
        parent_domain->jd_relids = bms_add_member(parent_domain->jd_relids,
1724
0
                              j->rtindex);
1725
0
        jtitem->qualscope = bms_add_member(jtitem->qualscope,
1726
0
                           j->rtindex);
1727
0
        root->outer_join_rels = bms_add_member(root->outer_join_rels,
1728
0
                             j->rtindex);
1729
0
        mark_rels_nulled_by_join(root, j->rtindex,
1730
0
                     left_item->qualscope);
1731
0
        mark_rels_nulled_by_join(root, j->rtindex,
1732
0
                     right_item->qualscope);
1733
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1734
0
                          right_item->inner_join_rels);
1735
0
        jtitem->left_rels = left_item->qualscope;
1736
0
        jtitem->right_rels = right_item->qualscope;
1737
        /* each side is both outer and inner */
1738
0
        jtitem->nonnullable_rels = jtitem->qualscope;
1739
0
        break;
1740
0
      default:
1741
        /* JOIN_RIGHT was eliminated during reduce_outer_joins() */
1742
0
        elog(ERROR, "unrecognized join type: %d",
1743
0
           (int) j->jointype);
1744
0
        leftjoinlist = rightjoinlist = NIL; /* keep compiler quiet */
1745
0
        break;
1746
0
    }
1747
1748
    /*
1749
     * Compute the output joinlist.  We fold subproblems together except
1750
     * at a FULL JOIN or where join_collapse_limit would be exceeded.
1751
     */
1752
0
    if (j->jointype == JOIN_FULL)
1753
0
    {
1754
      /* force the join order exactly at this node */
1755
0
      joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
1756
0
    }
1757
0
    else if (list_length(leftjoinlist) + list_length(rightjoinlist) <=
1758
0
         join_collapse_limit)
1759
0
    {
1760
      /* OK to combine subproblems */
1761
0
      joinlist = list_concat(leftjoinlist, rightjoinlist);
1762
0
    }
1763
0
    else
1764
0
    {
1765
      /* can't combine, but needn't force join order above here */
1766
0
      Node     *leftpart,
1767
0
             *rightpart;
1768
1769
      /* avoid creating useless 1-element sublists */
1770
0
      if (list_length(leftjoinlist) == 1)
1771
0
        leftpart = (Node *) linitial(leftjoinlist);
1772
0
      else
1773
0
        leftpart = (Node *) leftjoinlist;
1774
0
      if (list_length(rightjoinlist) == 1)
1775
0
        rightpart = (Node *) linitial(rightjoinlist);
1776
0
      else
1777
0
        rightpart = (Node *) rightjoinlist;
1778
0
      joinlist = list_make2(leftpart, rightpart);
1779
0
    }
1780
0
  }
1781
0
  else
1782
0
  {
1783
0
    elog(ERROR, "unrecognized node type: %d",
1784
0
       (int) nodeTag(jtnode));
1785
0
    joinlist = NIL;     /* keep compiler quiet */
1786
0
  }
1787
1788
  /* Finally, we can add the new JoinTreeItem to item_list */
1789
0
  *item_list = lappend(*item_list, jtitem);
1790
1791
0
  return joinlist;
1792
0
}
1793
1794
/*
1795
 * deconstruct_distribute
1796
 *    Process one jointree node in phase 2 of deconstruct_jointree processing.
1797
 *
1798
 * Distribute quals of the node to appropriate restriction and join lists.
1799
 * In addition, entries will be added to root->join_info_list for outer joins.
1800
 */
1801
static void
1802
deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
1803
0
{
1804
0
  Node     *jtnode = jtitem->jtnode;
1805
1806
0
  if (IsA(jtnode, RangeTblRef))
1807
0
  {
1808
0
    int     varno = ((RangeTblRef *) jtnode)->rtindex;
1809
1810
    /* Deal with any securityQuals attached to the RTE */
1811
0
    if (root->qual_security_level > 0)
1812
0
      process_security_barrier_quals(root,
1813
0
                       varno,
1814
0
                       jtitem);
1815
0
  }
1816
0
  else if (IsA(jtnode, FromExpr))
1817
0
  {
1818
0
    FromExpr   *f = (FromExpr *) jtnode;
1819
1820
    /*
1821
     * Process any lateral-referencing quals that were postponed to this
1822
     * level by children.
1823
     */
1824
0
    distribute_quals_to_rels(root, jtitem->lateral_clauses,
1825
0
                 jtitem,
1826
0
                 NULL,
1827
0
                 root->qual_security_level,
1828
0
                 jtitem->qualscope,
1829
0
                 NULL, NULL, NULL,
1830
0
                 true, false, false,
1831
0
                 NULL);
1832
1833
    /*
1834
     * Now process the top-level quals.
1835
     */
1836
0
    distribute_quals_to_rels(root, (List *) f->quals,
1837
0
                 jtitem,
1838
0
                 NULL,
1839
0
                 root->qual_security_level,
1840
0
                 jtitem->qualscope,
1841
0
                 NULL, NULL, NULL,
1842
0
                 true, false, false,
1843
0
                 NULL);
1844
0
  }
1845
0
  else if (IsA(jtnode, JoinExpr))
1846
0
  {
1847
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1848
0
    Relids    ojscope;
1849
0
    List     *my_quals;
1850
0
    SpecialJoinInfo *sjinfo;
1851
0
    List    **postponed_oj_qual_list;
1852
1853
    /*
1854
     * Include lateral-referencing quals postponed from children in
1855
     * my_quals, so that they'll be handled properly in
1856
     * make_outerjoininfo.  (This is destructive to
1857
     * jtitem->lateral_clauses, but we won't use that again.)
1858
     */
1859
0
    my_quals = list_concat(jtitem->lateral_clauses,
1860
0
                 (List *) j->quals);
1861
1862
    /*
1863
     * For an OJ, form the SpecialJoinInfo now, so that we can pass it to
1864
     * distribute_qual_to_rels.  We must compute its ojscope too.
1865
     *
1866
     * Semijoins are a bit of a hybrid: we build a SpecialJoinInfo, but we
1867
     * want ojscope = NULL for distribute_qual_to_rels.
1868
     */
1869
0
    if (j->jointype != JOIN_INNER)
1870
0
    {
1871
0
      sjinfo = make_outerjoininfo(root,
1872
0
                    jtitem->left_rels,
1873
0
                    jtitem->right_rels,
1874
0
                    jtitem->inner_join_rels,
1875
0
                    j->jointype,
1876
0
                    j->rtindex,
1877
0
                    my_quals);
1878
0
      jtitem->sjinfo = sjinfo;
1879
0
      if (j->jointype == JOIN_SEMI)
1880
0
        ojscope = NULL;
1881
0
      else
1882
0
        ojscope = bms_union(sjinfo->min_lefthand,
1883
0
                  sjinfo->min_righthand);
1884
0
    }
1885
0
    else
1886
0
    {
1887
0
      sjinfo = NULL;
1888
0
      ojscope = NULL;
1889
0
    }
1890
1891
    /*
1892
     * If it's a left join with a join clause that is strict for the LHS,
1893
     * then we need to postpone handling of any non-degenerate join
1894
     * clauses, in case the join is able to commute with another left join
1895
     * per identity 3.  (Degenerate clauses need not be postponed, since
1896
     * they will drop down below this join anyway.)
1897
     */
1898
0
    if (j->jointype == JOIN_LEFT && sjinfo->lhs_strict)
1899
0
    {
1900
0
      postponed_oj_qual_list = &jtitem->oj_joinclauses;
1901
1902
      /*
1903
       * Add back any commutable lower OJ relids that were removed from
1904
       * min_lefthand or min_righthand, else the ojscope cross-check in
1905
       * distribute_qual_to_rels will complain.  Since we are postponing
1906
       * processing of non-degenerate clauses, this addition doesn't
1907
       * affect anything except that cross-check.  Real clause
1908
       * positioning decisions will be made later, when we revisit the
1909
       * postponed clauses.
1910
       */
1911
0
      ojscope = bms_add_members(ojscope, sjinfo->commute_below_l);
1912
0
      ojscope = bms_add_members(ojscope, sjinfo->commute_below_r);
1913
0
    }
1914
0
    else
1915
0
      postponed_oj_qual_list = NULL;
1916
1917
    /* Process the JOIN's qual clauses */
1918
0
    distribute_quals_to_rels(root, my_quals,
1919
0
                 jtitem,
1920
0
                 sjinfo,
1921
0
                 root->qual_security_level,
1922
0
                 jtitem->qualscope,
1923
0
                 ojscope, jtitem->nonnullable_rels,
1924
0
                 NULL, /* incompatible_relids */
1925
0
                 true, /* allow_equivalence */
1926
0
                 false, false,  /* not clones */
1927
0
                 postponed_oj_qual_list);
1928
1929
    /* And add the SpecialJoinInfo to join_info_list */
1930
0
    if (sjinfo)
1931
0
      root->join_info_list = lappend(root->join_info_list, sjinfo);
1932
0
  }
1933
0
  else
1934
0
  {
1935
0
    elog(ERROR, "unrecognized node type: %d",
1936
0
       (int) nodeTag(jtnode));
1937
0
  }
1938
0
}
1939
1940
/*
1941
 * process_security_barrier_quals
1942
 *    Transfer security-barrier quals into relation's baserestrictinfo list.
1943
 *
1944
 * The rewriter put any relevant security-barrier conditions into the RTE's
1945
 * securityQuals field, but it's now time to copy them into the rel's
1946
 * baserestrictinfo.
1947
 *
1948
 * In inheritance cases, we only consider quals attached to the parent rel
1949
 * here; they will be valid for all children too, so it's okay to consider
1950
 * them for purposes like equivalence class creation.  Quals attached to
1951
 * individual child rels will be dealt with during path creation.
1952
 */
1953
static void
1954
process_security_barrier_quals(PlannerInfo *root,
1955
                 int rti, JoinTreeItem *jtitem)
1956
0
{
1957
0
  RangeTblEntry *rte = root->simple_rte_array[rti];
1958
0
  Index   security_level = 0;
1959
0
  ListCell   *lc;
1960
1961
  /*
1962
   * Each element of the securityQuals list has been preprocessed into an
1963
   * implicitly-ANDed list of clauses.  All the clauses in a given sublist
1964
   * should get the same security level, but successive sublists get higher
1965
   * levels.
1966
   */
1967
0
  foreach(lc, rte->securityQuals)
1968
0
  {
1969
0
    List     *qualset = (List *) lfirst(lc);
1970
1971
    /*
1972
     * We cheat to the extent of passing ojscope = qualscope rather than
1973
     * its more logical value of NULL.  The only effect this has is to
1974
     * force a Var-free qual to be evaluated at the rel rather than being
1975
     * pushed up to top of tree, which we don't want.
1976
     */
1977
0
    distribute_quals_to_rels(root, qualset,
1978
0
                 jtitem,
1979
0
                 NULL,
1980
0
                 security_level,
1981
0
                 jtitem->qualscope,
1982
0
                 jtitem->qualscope,
1983
0
                 NULL,
1984
0
                 NULL,
1985
0
                 true,
1986
0
                 false, false,  /* not clones */
1987
0
                 NULL);
1988
0
    security_level++;
1989
0
  }
1990
1991
  /* Assert that qual_security_level is higher than anything we just used */
1992
0
  Assert(security_level <= root->qual_security_level);
1993
0
}
1994
1995
/*
1996
 * mark_rels_nulled_by_join
1997
 *    Fill RelOptInfo.nulling_relids of baserels nulled by this outer join
1998
 *
1999
 * Inputs:
2000
 *  ojrelid: RT index of the join RTE (must not be 0)
2001
 *  lower_rels: the base+OJ Relids syntactically below nullable side of join
2002
 */
2003
static void
2004
mark_rels_nulled_by_join(PlannerInfo *root, Index ojrelid,
2005
             Relids lower_rels)
2006
0
{
2007
0
  int     relid = -1;
2008
2009
0
  while ((relid = bms_next_member(lower_rels, relid)) > 0)
2010
0
  {
2011
0
    RelOptInfo *rel = root->simple_rel_array[relid];
2012
2013
    /* ignore the RTE_GROUP RTE */
2014
0
    if (relid == root->group_rtindex)
2015
0
      continue;
2016
2017
0
    if (rel == NULL)   /* must be an outer join */
2018
0
    {
2019
0
      Assert(bms_is_member(relid, root->outer_join_rels));
2020
0
      continue;
2021
0
    }
2022
0
    rel->nulling_relids = bms_add_member(rel->nulling_relids, ojrelid);
2023
0
  }
2024
0
}
2025
2026
/*
2027
 * make_outerjoininfo
2028
 *    Build a SpecialJoinInfo for the current outer join
2029
 *
2030
 * Inputs:
2031
 *  left_rels: the base+OJ Relids syntactically on outer side of join
2032
 *  right_rels: the base+OJ Relids syntactically on inner side of join
2033
 *  inner_join_rels: base+OJ Relids participating in inner joins below this one
2034
 *  jointype: what it says (must always be LEFT, FULL, SEMI, or ANTI)
2035
 *  ojrelid: RT index of the join RTE (0 for SEMI, which isn't in the RT list)
2036
 *  clause: the outer join's join condition (in implicit-AND format)
2037
 *
2038
 * The node should eventually be appended to root->join_info_list, but we
2039
 * do not do that here.
2040
 *
2041
 * Note: we assume that this function is invoked bottom-up, so that
2042
 * root->join_info_list already contains entries for all outer joins that are
2043
 * syntactically below this one.
2044
 */
2045
static SpecialJoinInfo *
2046
make_outerjoininfo(PlannerInfo *root,
2047
           Relids left_rels, Relids right_rels,
2048
           Relids inner_join_rels,
2049
           JoinType jointype, Index ojrelid,
2050
           List *clause)
2051
0
{
2052
0
  SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo);
2053
0
  Relids    clause_relids;
2054
0
  Relids    strict_relids;
2055
0
  Relids    min_lefthand;
2056
0
  Relids    min_righthand;
2057
0
  Relids    commute_below_l;
2058
0
  Relids    commute_below_r;
2059
0
  ListCell   *l;
2060
2061
  /*
2062
   * We should not see RIGHT JOIN here because left/right were switched
2063
   * earlier
2064
   */
2065
0
  Assert(jointype != JOIN_INNER);
2066
0
  Assert(jointype != JOIN_RIGHT);
2067
2068
  /*
2069
   * Presently the executor cannot support FOR [KEY] UPDATE/SHARE marking of
2070
   * rels appearing on the nullable side of an outer join. (It's somewhat
2071
   * unclear what that would mean, anyway: what should we mark when a result
2072
   * row is generated from no element of the nullable relation?)  So,
2073
   * complain if any nullable rel is FOR [KEY] UPDATE/SHARE.
2074
   *
2075
   * You might be wondering why this test isn't made far upstream in the
2076
   * parser.  It's because the parser hasn't got enough info --- consider
2077
   * FOR UPDATE applied to a view.  Only after rewriting and flattening do
2078
   * we know whether the view contains an outer join.
2079
   *
2080
   * We use the original RowMarkClause list here; the PlanRowMark list would
2081
   * list everything.
2082
   */
2083
0
  foreach(l, root->parse->rowMarks)
2084
0
  {
2085
0
    RowMarkClause *rc = (RowMarkClause *) lfirst(l);
2086
2087
0
    if (bms_is_member(rc->rti, right_rels) ||
2088
0
      (jointype == JOIN_FULL && bms_is_member(rc->rti, left_rels)))
2089
0
      ereport(ERROR,
2090
0
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2091
      /*------
2092
       translator: %s is a SQL row locking clause such as FOR UPDATE */
2093
0
           errmsg("%s cannot be applied to the nullable side of an outer join",
2094
0
              LCS_asString(rc->strength))));
2095
0
  }
2096
2097
0
  sjinfo->syn_lefthand = left_rels;
2098
0
  sjinfo->syn_righthand = right_rels;
2099
0
  sjinfo->jointype = jointype;
2100
0
  sjinfo->ojrelid = ojrelid;
2101
  /* these fields may get added to later: */
2102
0
  sjinfo->commute_above_l = NULL;
2103
0
  sjinfo->commute_above_r = NULL;
2104
0
  sjinfo->commute_below_l = NULL;
2105
0
  sjinfo->commute_below_r = NULL;
2106
2107
0
  compute_semijoin_info(root, sjinfo, clause);
2108
2109
  /* If it's a full join, no need to be very smart */
2110
0
  if (jointype == JOIN_FULL)
2111
0
  {
2112
0
    sjinfo->min_lefthand = bms_copy(left_rels);
2113
0
    sjinfo->min_righthand = bms_copy(right_rels);
2114
0
    sjinfo->lhs_strict = false; /* don't care about this */
2115
0
    return sjinfo;
2116
0
  }
2117
2118
  /*
2119
   * Retrieve all relids mentioned within the join clause.
2120
   */
2121
0
  clause_relids = pull_varnos(root, (Node *) clause);
2122
2123
  /*
2124
   * For which relids is the clause strict, ie, it cannot succeed if the
2125
   * rel's columns are all NULL?
2126
   */
2127
0
  strict_relids = find_nonnullable_rels((Node *) clause);
2128
2129
  /*
2130
   * find_nonnullable_rels looks inside PlaceHolderVars, so it can report
2131
   * rels that the clause references only laterally.  Ignore those, since
2132
   * like clause_relids we treat a PHV as computed at its ph_eval_at.
2133
   */
2134
0
  strict_relids = bms_int_members(strict_relids, clause_relids);
2135
2136
  /* Remember whether the clause is strict for any LHS relations */
2137
0
  sjinfo->lhs_strict = bms_overlap(strict_relids, left_rels);
2138
2139
  /*
2140
   * Required LHS always includes the LHS rels mentioned in the clause. We
2141
   * may have to add more rels based on lower outer joins; see below.
2142
   */
2143
0
  min_lefthand = bms_intersect(clause_relids, left_rels);
2144
2145
  /*
2146
   * Similarly for required RHS.  But here, we must also include any lower
2147
   * inner joins, to ensure we don't try to commute with any of them.
2148
   */
2149
0
  min_righthand = bms_int_members(bms_union(clause_relids, inner_join_rels),
2150
0
                  right_rels);
2151
2152
  /*
2153
   * Now check previous outer joins for ordering restrictions.
2154
   *
2155
   * commute_below_l and commute_below_r accumulate the relids of lower
2156
   * outer joins that we think this one can commute with.  These decisions
2157
   * are just tentative within this loop, since we might find an
2158
   * intermediate outer join that prevents commutation.  Surviving relids
2159
   * will get merged into the SpecialJoinInfo structs afterwards.
2160
   */
2161
0
  commute_below_l = commute_below_r = NULL;
2162
0
  foreach(l, root->join_info_list)
2163
0
  {
2164
0
    SpecialJoinInfo *otherinfo = (SpecialJoinInfo *) lfirst(l);
2165
0
    bool    have_unsafe_phvs;
2166
2167
    /*
2168
     * A full join is an optimization barrier: we can't associate into or
2169
     * out of it.  Hence, if it overlaps either LHS or RHS of the current
2170
     * rel, expand that side's min relset to cover the whole full join.
2171
     */
2172
0
    if (otherinfo->jointype == JOIN_FULL)
2173
0
    {
2174
0
      Assert(otherinfo->ojrelid != 0);
2175
0
      if (bms_overlap(left_rels, otherinfo->syn_lefthand) ||
2176
0
        bms_overlap(left_rels, otherinfo->syn_righthand))
2177
0
      {
2178
0
        min_lefthand = bms_add_members(min_lefthand,
2179
0
                         otherinfo->syn_lefthand);
2180
0
        min_lefthand = bms_add_members(min_lefthand,
2181
0
                         otherinfo->syn_righthand);
2182
0
        min_lefthand = bms_add_member(min_lefthand,
2183
0
                        otherinfo->ojrelid);
2184
0
      }
2185
0
      if (bms_overlap(right_rels, otherinfo->syn_lefthand) ||
2186
0
        bms_overlap(right_rels, otherinfo->syn_righthand))
2187
0
      {
2188
0
        min_righthand = bms_add_members(min_righthand,
2189
0
                        otherinfo->syn_lefthand);
2190
0
        min_righthand = bms_add_members(min_righthand,
2191
0
                        otherinfo->syn_righthand);
2192
0
        min_righthand = bms_add_member(min_righthand,
2193
0
                         otherinfo->ojrelid);
2194
0
      }
2195
      /* Needn't do anything else with the full join */
2196
0
      continue;
2197
0
    }
2198
2199
    /*
2200
     * If our join condition contains any PlaceHolderVars that need to be
2201
     * evaluated above the lower OJ, then we can't commute with it.
2202
     */
2203
0
    if (otherinfo->ojrelid != 0)
2204
0
      have_unsafe_phvs =
2205
0
        contain_placeholder_references_to(root,
2206
0
                          (Node *) clause,
2207
0
                          otherinfo->ojrelid);
2208
0
    else
2209
0
      have_unsafe_phvs = false;
2210
2211
    /*
2212
     * For a lower OJ in our LHS, if our join condition uses the lower
2213
     * join's RHS and is not strict for that rel, we must preserve the
2214
     * ordering of the two OJs, so add lower OJ's full syntactic relset to
2215
     * min_lefthand.  (We must use its full syntactic relset, not just its
2216
     * min_lefthand + min_righthand.  This is because there might be other
2217
     * OJs below this one that this one can commute with, but we cannot
2218
     * commute with them if we don't with this one.)  Also, if we have
2219
     * unsafe PHVs or the current join is a semijoin or antijoin, we must
2220
     * preserve ordering regardless of strictness.
2221
     *
2222
     * Note: I believe we have to insist on being strict for at least one
2223
     * rel in the lower OJ's min_righthand, not its whole syn_righthand.
2224
     *
2225
     * When we don't need to preserve ordering, check to see if outer join
2226
     * identity 3 applies, and if so, remove the lower OJ's ojrelid from
2227
     * our min_lefthand so that commutation is allowed.
2228
     */
2229
0
    if (bms_overlap(left_rels, otherinfo->syn_righthand))
2230
0
    {
2231
0
      if (bms_overlap(clause_relids, otherinfo->syn_righthand) &&
2232
0
        (have_unsafe_phvs ||
2233
0
         jointype == JOIN_SEMI || jointype == JOIN_ANTI ||
2234
0
         !bms_overlap(strict_relids, otherinfo->min_righthand)))
2235
0
      {
2236
        /* Preserve ordering */
2237
0
        min_lefthand = bms_add_members(min_lefthand,
2238
0
                         otherinfo->syn_lefthand);
2239
0
        min_lefthand = bms_add_members(min_lefthand,
2240
0
                         otherinfo->syn_righthand);
2241
0
        if (otherinfo->ojrelid != 0)
2242
0
          min_lefthand = bms_add_member(min_lefthand,
2243
0
                          otherinfo->ojrelid);
2244
0
      }
2245
0
      else if (jointype == JOIN_LEFT &&
2246
0
           otherinfo->jointype == JOIN_LEFT &&
2247
0
           bms_overlap(strict_relids, otherinfo->min_righthand) &&
2248
0
           !bms_overlap(clause_relids, otherinfo->syn_lefthand))
2249
0
      {
2250
        /* Identity 3 applies, so remove the ordering restriction */
2251
0
        min_lefthand = bms_del_member(min_lefthand, otherinfo->ojrelid);
2252
        /* Record the (still tentative) commutability relationship */
2253
0
        commute_below_l =
2254
0
          bms_add_member(commute_below_l, otherinfo->ojrelid);
2255
0
      }
2256
0
    }
2257
2258
    /*
2259
     * For a lower OJ in our RHS, if our join condition does not use the
2260
     * lower join's RHS and the lower OJ's join condition is strict, we
2261
     * can interchange the ordering of the two OJs; otherwise we must add
2262
     * the lower OJ's full syntactic relset to min_righthand.
2263
     *
2264
     * Also, if our join condition does not use the lower join's LHS
2265
     * either, force the ordering to be preserved.  Otherwise we can end
2266
     * up with SpecialJoinInfos with identical min_righthands, which can
2267
     * confuse join_is_legal (see discussion in backend/optimizer/README).
2268
     *
2269
     * Also, we must preserve ordering anyway if we have unsafe PHVs, or
2270
     * if either this join or the lower OJ is a semijoin or antijoin.
2271
     *
2272
     * When we don't need to preserve ordering, check to see if outer join
2273
     * identity 3 applies, and if so, remove the lower OJ's ojrelid from
2274
     * our min_righthand so that commutation is allowed.
2275
     */
2276
0
    if (bms_overlap(right_rels, otherinfo->syn_righthand))
2277
0
    {
2278
0
      if (bms_overlap(clause_relids, otherinfo->syn_righthand) ||
2279
0
        !bms_overlap(clause_relids, otherinfo->min_lefthand) ||
2280
0
        have_unsafe_phvs ||
2281
0
        jointype == JOIN_SEMI ||
2282
0
        jointype == JOIN_ANTI ||
2283
0
        otherinfo->jointype == JOIN_SEMI ||
2284
0
        otherinfo->jointype == JOIN_ANTI ||
2285
0
        !otherinfo->lhs_strict)
2286
0
      {
2287
        /* Preserve ordering */
2288
0
        min_righthand = bms_add_members(min_righthand,
2289
0
                        otherinfo->syn_lefthand);
2290
0
        min_righthand = bms_add_members(min_righthand,
2291
0
                        otherinfo->syn_righthand);
2292
0
        if (otherinfo->ojrelid != 0)
2293
0
          min_righthand = bms_add_member(min_righthand,
2294
0
                           otherinfo->ojrelid);
2295
0
      }
2296
0
      else if (jointype == JOIN_LEFT &&
2297
0
           otherinfo->jointype == JOIN_LEFT &&
2298
0
           otherinfo->lhs_strict)
2299
0
      {
2300
        /* Identity 3 applies, so remove the ordering restriction */
2301
0
        min_righthand = bms_del_member(min_righthand,
2302
0
                         otherinfo->ojrelid);
2303
        /* Record the (still tentative) commutability relationship */
2304
0
        commute_below_r =
2305
0
          bms_add_member(commute_below_r, otherinfo->ojrelid);
2306
0
      }
2307
0
    }
2308
0
  }
2309
2310
  /*
2311
   * Examine PlaceHolderVars.  If a PHV is supposed to be evaluated within
2312
   * this join's nullable side, then ensure that min_righthand contains the
2313
   * full eval_at set of the PHV.  This ensures that the PHV actually can be
2314
   * evaluated within the RHS.  Note that this works only because we should
2315
   * already have determined the final eval_at level for any PHV
2316
   * syntactically within this join.
2317
   */
2318
0
  foreach(l, root->placeholder_list)
2319
0
  {
2320
0
    PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
2321
0
    Relids    ph_syn_level = phinfo->ph_var->phrels;
2322
2323
    /* Ignore placeholder if it didn't syntactically come from RHS */
2324
0
    if (!bms_is_subset(ph_syn_level, right_rels))
2325
0
      continue;
2326
2327
    /* Else, prevent join from being formed before we eval the PHV */
2328
0
    min_righthand = bms_add_members(min_righthand, phinfo->ph_eval_at);
2329
0
  }
2330
2331
  /*
2332
   * If we found nothing to put in min_lefthand, punt and make it the full
2333
   * LHS, to avoid having an empty min_lefthand which will confuse later
2334
   * processing. (We don't try to be smart about such cases, just correct.)
2335
   * Likewise for min_righthand.
2336
   */
2337
0
  if (bms_is_empty(min_lefthand))
2338
0
    min_lefthand = bms_copy(left_rels);
2339
0
  if (bms_is_empty(min_righthand))
2340
0
    min_righthand = bms_copy(right_rels);
2341
2342
  /* Now they'd better be nonempty */
2343
0
  Assert(!bms_is_empty(min_lefthand));
2344
0
  Assert(!bms_is_empty(min_righthand));
2345
  /* Shouldn't overlap either */
2346
0
  Assert(!bms_overlap(min_lefthand, min_righthand));
2347
2348
0
  sjinfo->min_lefthand = min_lefthand;
2349
0
  sjinfo->min_righthand = min_righthand;
2350
2351
  /*
2352
   * Now that we've identified the correct min_lefthand and min_righthand,
2353
   * any commute_below_l or commute_below_r relids that have not gotten
2354
   * added back into those sets (due to intervening outer joins) are indeed
2355
   * commutable with this one.
2356
   *
2357
   * First, delete any subsequently-added-back relids (this is easier than
2358
   * maintaining commute_below_l/r precisely through all the above).
2359
   */
2360
0
  commute_below_l = bms_del_members(commute_below_l, min_lefthand);
2361
0
  commute_below_r = bms_del_members(commute_below_r, min_righthand);
2362
2363
  /* Anything left? */
2364
0
  if (commute_below_l || commute_below_r)
2365
0
  {
2366
    /* Yup, so we must update the derived data in the SpecialJoinInfos */
2367
0
    sjinfo->commute_below_l = commute_below_l;
2368
0
    sjinfo->commute_below_r = commute_below_r;
2369
0
    foreach(l, root->join_info_list)
2370
0
    {
2371
0
      SpecialJoinInfo *otherinfo = (SpecialJoinInfo *) lfirst(l);
2372
2373
0
      if (bms_is_member(otherinfo->ojrelid, commute_below_l))
2374
0
        otherinfo->commute_above_l =
2375
0
          bms_add_member(otherinfo->commute_above_l, ojrelid);
2376
0
      else if (bms_is_member(otherinfo->ojrelid, commute_below_r))
2377
0
        otherinfo->commute_above_r =
2378
0
          bms_add_member(otherinfo->commute_above_r, ojrelid);
2379
0
    }
2380
0
  }
2381
2382
0
  return sjinfo;
2383
0
}
2384
2385
/*
2386
 * compute_semijoin_info
2387
 *    Fill semijoin-related fields of a new SpecialJoinInfo
2388
 *
2389
 * Note: this relies on only the jointype and syn_righthand fields of the
2390
 * SpecialJoinInfo; the rest may not be set yet.
2391
 */
2392
static void
2393
compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo, List *clause)
2394
0
{
2395
0
  List     *semi_operators;
2396
0
  List     *semi_rhs_exprs;
2397
0
  bool    all_btree;
2398
0
  bool    all_hash;
2399
0
  ListCell   *lc;
2400
2401
  /* Initialize semijoin-related fields in case we can't unique-ify */
2402
0
  sjinfo->semi_can_btree = false;
2403
0
  sjinfo->semi_can_hash = false;
2404
0
  sjinfo->semi_operators = NIL;
2405
0
  sjinfo->semi_rhs_exprs = NIL;
2406
2407
  /* Nothing more to do if it's not a semijoin */
2408
0
  if (sjinfo->jointype != JOIN_SEMI)
2409
0
    return;
2410
2411
  /*
2412
   * Look to see whether the semijoin's join quals consist of AND'ed
2413
   * equality operators, with (only) RHS variables on only one side of each
2414
   * one.  If so, we can figure out how to enforce uniqueness for the RHS.
2415
   *
2416
   * Note that the input clause list is the list of quals that are
2417
   * *syntactically* associated with the semijoin, which in practice means
2418
   * the synthesized comparison list for an IN or the WHERE of an EXISTS.
2419
   * Particularly in the latter case, it might contain clauses that aren't
2420
   * *semantically* associated with the join, but refer to just one side or
2421
   * the other.  We can ignore such clauses here, as they will just drop
2422
   * down to be processed within one side or the other.  (It is okay to
2423
   * consider only the syntactically-associated clauses here because for a
2424
   * semijoin, no higher-level quals could refer to the RHS, and so there
2425
   * can be no other quals that are semantically associated with this join.
2426
   * We do things this way because it is useful to have the set of potential
2427
   * unique-ification expressions before we can extract the list of quals
2428
   * that are actually semantically associated with the particular join.)
2429
   *
2430
   * Note that the semi_operators list consists of the joinqual operators
2431
   * themselves (but commuted if needed to put the RHS value on the right).
2432
   * These could be cross-type operators, in which case the operator
2433
   * actually needed for uniqueness is a related single-type operator. We
2434
   * assume here that that operator will be available from the btree or hash
2435
   * opclass when the time comes ... if not, create_unique_plan() will fail.
2436
   */
2437
0
  semi_operators = NIL;
2438
0
  semi_rhs_exprs = NIL;
2439
0
  all_btree = true;
2440
0
  all_hash = enable_hashagg;  /* don't consider hash if not enabled */
2441
0
  foreach(lc, clause)
2442
0
  {
2443
0
    OpExpr     *op = (OpExpr *) lfirst(lc);
2444
0
    Oid     opno;
2445
0
    Node     *left_expr;
2446
0
    Node     *right_expr;
2447
0
    Relids    left_varnos;
2448
0
    Relids    right_varnos;
2449
0
    Relids    all_varnos;
2450
0
    Oid     opinputtype;
2451
2452
    /* Is it a binary opclause? */
2453
0
    if (!IsA(op, OpExpr) ||
2454
0
      list_length(op->args) != 2)
2455
0
    {
2456
      /* No, but does it reference both sides? */
2457
0
      all_varnos = pull_varnos(root, (Node *) op);
2458
0
      if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
2459
0
        bms_is_subset(all_varnos, sjinfo->syn_righthand))
2460
0
      {
2461
        /*
2462
         * Clause refers to only one rel, so ignore it --- unless it
2463
         * contains volatile functions, in which case we'd better
2464
         * punt.
2465
         */
2466
0
        if (contain_volatile_functions((Node *) op))
2467
0
          return;
2468
0
        continue;
2469
0
      }
2470
      /* Non-operator clause referencing both sides, must punt */
2471
0
      return;
2472
0
    }
2473
2474
    /* Extract data from binary opclause */
2475
0
    opno = op->opno;
2476
0
    left_expr = linitial(op->args);
2477
0
    right_expr = lsecond(op->args);
2478
0
    left_varnos = pull_varnos(root, left_expr);
2479
0
    right_varnos = pull_varnos(root, right_expr);
2480
0
    all_varnos = bms_union(left_varnos, right_varnos);
2481
0
    opinputtype = exprType(left_expr);
2482
2483
    /* Does it reference both sides? */
2484
0
    if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
2485
0
      bms_is_subset(all_varnos, sjinfo->syn_righthand))
2486
0
    {
2487
      /*
2488
       * Clause refers to only one rel, so ignore it --- unless it
2489
       * contains volatile functions, in which case we'd better punt.
2490
       */
2491
0
      if (contain_volatile_functions((Node *) op))
2492
0
        return;
2493
0
      continue;
2494
0
    }
2495
2496
    /* check rel membership of arguments */
2497
0
    if (!bms_is_empty(right_varnos) &&
2498
0
      bms_is_subset(right_varnos, sjinfo->syn_righthand) &&
2499
0
      !bms_overlap(left_varnos, sjinfo->syn_righthand))
2500
0
    {
2501
      /* typical case, right_expr is RHS variable */
2502
0
    }
2503
0
    else if (!bms_is_empty(left_varnos) &&
2504
0
         bms_is_subset(left_varnos, sjinfo->syn_righthand) &&
2505
0
         !bms_overlap(right_varnos, sjinfo->syn_righthand))
2506
0
    {
2507
      /* flipped case, left_expr is RHS variable */
2508
0
      opno = get_commutator(opno);
2509
0
      if (!OidIsValid(opno))
2510
0
        return;
2511
0
      right_expr = left_expr;
2512
0
    }
2513
0
    else
2514
0
    {
2515
      /* mixed membership of args, punt */
2516
0
      return;
2517
0
    }
2518
2519
    /* all operators must be btree equality or hash equality */
2520
0
    if (all_btree)
2521
0
    {
2522
      /* oprcanmerge is considered a hint... */
2523
0
      if (!op_mergejoinable(opno, opinputtype) ||
2524
0
        get_mergejoin_opfamilies(opno) == NIL)
2525
0
        all_btree = false;
2526
0
    }
2527
0
    if (all_hash)
2528
0
    {
2529
      /* ... but oprcanhash had better be correct */
2530
0
      if (!op_hashjoinable(opno, opinputtype))
2531
0
        all_hash = false;
2532
0
    }
2533
0
    if (!(all_btree || all_hash))
2534
0
      return;
2535
2536
    /*
2537
     * Ensure the RHS expression exposes the join's input collation (its
2538
     * type should be OK already); see comments for
2539
     * canonicalize_ec_expression.
2540
     */
2541
0
    right_expr = (Node *) canonicalize_ec_expression((Expr *) copyObject(right_expr),
2542
0
                             exprType(right_expr),
2543
0
                             op->inputcollid);
2544
2545
    /* so far so good, keep building lists */
2546
0
    semi_operators = lappend_oid(semi_operators, opno);
2547
0
    semi_rhs_exprs = lappend(semi_rhs_exprs, right_expr);
2548
0
  }
2549
2550
  /* Punt if we didn't find at least one column to unique-ify */
2551
0
  if (semi_rhs_exprs == NIL)
2552
0
    return;
2553
2554
  /*
2555
   * The expressions we'd need to unique-ify mustn't be volatile.
2556
   */
2557
0
  if (contain_volatile_functions((Node *) semi_rhs_exprs))
2558
0
    return;
2559
2560
  /*
2561
   * If we get here, we can unique-ify the semijoin's RHS using at least one
2562
   * of sorting and hashing.  Save the information about how to do that.
2563
   */
2564
0
  sjinfo->semi_can_btree = all_btree;
2565
0
  sjinfo->semi_can_hash = all_hash;
2566
0
  sjinfo->semi_operators = semi_operators;
2567
0
  sjinfo->semi_rhs_exprs = semi_rhs_exprs;
2568
0
}
2569
2570
/*
2571
 * deconstruct_distribute_oj_quals
2572
 *    Adjust LEFT JOIN quals to be suitable for commuted-left-join cases,
2573
 *    then push them into the joinqual lists and EquivalenceClass structures.
2574
 *
2575
 * This runs immediately after we've completed the deconstruct_distribute scan.
2576
 * jtitems contains all the JoinTreeItems (in depth-first order), and jtitem
2577
 * is one that has postponed oj_joinclauses to deal with.
2578
 */
2579
static void
2580
deconstruct_distribute_oj_quals(PlannerInfo *root,
2581
                List *jtitems,
2582
                JoinTreeItem *jtitem)
2583
0
{
2584
0
  SpecialJoinInfo *sjinfo = jtitem->sjinfo;
2585
0
  Relids    qualscope,
2586
0
        ojscope,
2587
0
        nonnullable_rels;
2588
2589
  /* Recompute syntactic and semantic scopes of this left join */
2590
0
  qualscope = bms_union(sjinfo->syn_lefthand, sjinfo->syn_righthand);
2591
0
  qualscope = bms_add_member(qualscope, sjinfo->ojrelid);
2592
0
  ojscope = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
2593
0
  nonnullable_rels = sjinfo->syn_lefthand;
2594
2595
  /*
2596
   * If this join can commute with any other ones per outer-join identity 3,
2597
   * and it is the one providing the join clause with flexible semantics,
2598
   * then we have to generate variants of the join clause with different
2599
   * nullingrels labeling.  Otherwise, just push out the postponed clause
2600
   * as-is.
2601
   */
2602
0
  Assert(sjinfo->lhs_strict); /* else we shouldn't be here */
2603
0
  if (sjinfo->commute_above_r || sjinfo->commute_below_l)
2604
0
  {
2605
0
    Relids    joins_above;
2606
0
    Relids    joins_below;
2607
0
    Relids    incompatible_joins;
2608
0
    Relids    joins_so_far;
2609
0
    List     *quals;
2610
0
    int     save_last_rinfo_serial;
2611
0
    ListCell   *lc;
2612
2613
    /* Identify the outer joins this one commutes with */
2614
0
    joins_above = sjinfo->commute_above_r;
2615
0
    joins_below = sjinfo->commute_below_l;
2616
2617
    /*
2618
     * Generate qual variants with different sets of nullingrels bits.
2619
     *
2620
     * We only need bit-sets that correspond to the successively less
2621
     * deeply syntactically-nested subsets of this join and its
2622
     * commutators.  That's true first because obviously only those forms
2623
     * of the Vars and PHVs could appear elsewhere in the query, and
2624
     * second because the outer join identities do not provide a way to
2625
     * re-order such joins in a way that would require different marking.
2626
     * (That is, while the current join may commute with several others,
2627
     * none of those others can commute with each other.)  To visit the
2628
     * interesting joins in syntactic nesting order, we rely on the
2629
     * jtitems list to be ordered that way.
2630
     *
2631
     * We first strip out all the nullingrels bits corresponding to
2632
     * commuting joins below this one, and then successively put them back
2633
     * as we crawl up the join stack.
2634
     */
2635
0
    quals = jtitem->oj_joinclauses;
2636
0
    if (!bms_is_empty(joins_below))
2637
0
      quals = (List *) remove_nulling_relids((Node *) quals,
2638
0
                           joins_below,
2639
0
                           NULL);
2640
2641
    /*
2642
     * We'll need to mark the lower versions of the quals as not safe to
2643
     * apply above not-yet-processed joins of the stack.  This prevents
2644
     * possibly applying a cloned qual at the wrong join level.
2645
     */
2646
0
    incompatible_joins = bms_union(joins_below, joins_above);
2647
0
    incompatible_joins = bms_add_member(incompatible_joins,
2648
0
                      sjinfo->ojrelid);
2649
2650
    /*
2651
     * Each time we produce RestrictInfo(s) from these quals, reset the
2652
     * last_rinfo_serial counter, so that the RestrictInfos for the "same"
2653
     * qual condition get identical serial numbers.  (This relies on the
2654
     * fact that we're not changing the qual list in any way that'd affect
2655
     * the number of RestrictInfos built from it.) This'll allow us to
2656
     * detect duplicative qual usage later.
2657
     */
2658
0
    save_last_rinfo_serial = root->last_rinfo_serial;
2659
2660
0
    joins_so_far = NULL;
2661
0
    foreach(lc, jtitems)
2662
0
    {
2663
0
      JoinTreeItem *otherjtitem = (JoinTreeItem *) lfirst(lc);
2664
0
      SpecialJoinInfo *othersj = otherjtitem->sjinfo;
2665
0
      bool    below_sjinfo = false;
2666
0
      bool    above_sjinfo = false;
2667
0
      Relids    this_qualscope;
2668
0
      Relids    this_ojscope;
2669
0
      bool    allow_equivalence,
2670
0
            has_clone,
2671
0
            is_clone;
2672
2673
0
      if (othersj == NULL)
2674
0
        continue;   /* not an outer-join item, ignore */
2675
2676
0
      if (bms_is_member(othersj->ojrelid, joins_below))
2677
0
      {
2678
        /* othersj commutes with sjinfo from below left */
2679
0
        below_sjinfo = true;
2680
0
      }
2681
0
      else if (othersj == sjinfo)
2682
0
      {
2683
        /* found our join in syntactic order */
2684
0
        Assert(bms_equal(joins_so_far, joins_below));
2685
0
      }
2686
0
      else if (bms_is_member(othersj->ojrelid, joins_above))
2687
0
      {
2688
        /* othersj commutes with sjinfo from above */
2689
0
        above_sjinfo = true;
2690
0
      }
2691
0
      else
2692
0
      {
2693
        /* othersj is not relevant, ignore */
2694
0
        continue;
2695
0
      }
2696
2697
      /* Reset serial counter for this version of the quals */
2698
0
      root->last_rinfo_serial = save_last_rinfo_serial;
2699
2700
      /*
2701
       * When we are looking at joins above sjinfo, we are envisioning
2702
       * pushing sjinfo to above othersj, so add othersj's nulling bit
2703
       * before distributing the quals.  We should add it to Vars coming
2704
       * from the current join's LHS: we want to transform the second
2705
       * form of OJ identity 3 to the first form, in which Vars of
2706
       * relation B will appear nulled by the syntactically-upper OJ
2707
       * within the Pbc clause, but those of relation C will not.  (In
2708
       * the notation used by optimizer/README, we're converting a qual
2709
       * of the form Pbc to Pb*c.)  Of course, we must also remove that
2710
       * bit from the incompatible_joins value, else we'll make a qual
2711
       * that can't be placed anywhere.
2712
       */
2713
0
      if (above_sjinfo)
2714
0
      {
2715
0
        quals = (List *)
2716
0
          add_nulling_relids((Node *) quals,
2717
0
                     sjinfo->syn_lefthand,
2718
0
                     bms_make_singleton(othersj->ojrelid));
2719
0
        incompatible_joins = bms_del_member(incompatible_joins,
2720
0
                          othersj->ojrelid);
2721
0
      }
2722
2723
      /* Compute qualscope and ojscope for this join level */
2724
0
      this_qualscope = bms_union(qualscope, joins_so_far);
2725
0
      this_ojscope = bms_union(ojscope, joins_so_far);
2726
0
      if (above_sjinfo)
2727
0
      {
2728
        /* othersj is not yet in joins_so_far, but we need it */
2729
0
        this_qualscope = bms_add_member(this_qualscope,
2730
0
                        othersj->ojrelid);
2731
0
        this_ojscope = bms_add_member(this_ojscope,
2732
0
                        othersj->ojrelid);
2733
        /* sjinfo is in joins_so_far, and we don't want it */
2734
0
        this_ojscope = bms_del_member(this_ojscope,
2735
0
                        sjinfo->ojrelid);
2736
0
      }
2737
2738
      /*
2739
       * We generate EquivalenceClasses only from the first form of the
2740
       * quals, with the fewest nullingrels bits set.  An EC made from
2741
       * this version of the quals can be useful below the outer-join
2742
       * nest, whereas versions with some nullingrels bits set would not
2743
       * be.  We cannot generate ECs from more than one version, or
2744
       * we'll make nonsensical conclusions that Vars with nullingrels
2745
       * bits set are equal to their versions without.  Fortunately,
2746
       * such ECs wouldn't be very useful anyway, because they'd equate
2747
       * values not observable outside the join nest.  (See
2748
       * optimizer/README.)
2749
       *
2750
       * The first form of the quals is also the only one marked as
2751
       * has_clone rather than is_clone.
2752
       */
2753
0
      allow_equivalence = (joins_so_far == NULL);
2754
0
      has_clone = allow_equivalence;
2755
0
      is_clone = !has_clone;
2756
2757
0
      distribute_quals_to_rels(root, quals,
2758
0
                   otherjtitem,
2759
0
                   sjinfo,
2760
0
                   root->qual_security_level,
2761
0
                   this_qualscope,
2762
0
                   this_ojscope, nonnullable_rels,
2763
0
                   bms_copy(incompatible_joins),
2764
0
                   allow_equivalence,
2765
0
                   has_clone,
2766
0
                   is_clone,
2767
0
                   NULL); /* no more postponement */
2768
2769
      /*
2770
       * Adjust qual nulling bits for next level up, if needed.  We
2771
       * don't want to put sjinfo's own bit in at all, and if we're
2772
       * above sjinfo then we did it already.  Here, we should mark all
2773
       * Vars coming from the lower join's RHS.  (Again, we are
2774
       * converting a qual of the form Pbc to Pb*c, but now we are
2775
       * putting back bits that were there in the parser output and were
2776
       * temporarily stripped above.)  Update incompatible_joins too.
2777
       */
2778
0
      if (below_sjinfo)
2779
0
      {
2780
0
        quals = (List *)
2781
0
          add_nulling_relids((Node *) quals,
2782
0
                     othersj->syn_righthand,
2783
0
                     bms_make_singleton(othersj->ojrelid));
2784
0
        incompatible_joins = bms_del_member(incompatible_joins,
2785
0
                          othersj->ojrelid);
2786
0
      }
2787
2788
      /* ... and track joins processed so far */
2789
0
      joins_so_far = bms_add_member(joins_so_far, othersj->ojrelid);
2790
0
    }
2791
0
  }
2792
0
  else
2793
0
  {
2794
    /* No commutation possible, just process the postponed clauses */
2795
0
    distribute_quals_to_rels(root, jtitem->oj_joinclauses,
2796
0
                 jtitem,
2797
0
                 sjinfo,
2798
0
                 root->qual_security_level,
2799
0
                 qualscope,
2800
0
                 ojscope, nonnullable_rels,
2801
0
                 NULL, /* incompatible_relids */
2802
0
                 true, /* allow_equivalence */
2803
0
                 false, false,  /* not clones */
2804
0
                 NULL); /* no more postponement */
2805
0
  }
2806
0
}
2807
2808
2809
/*****************************************************************************
2810
 *
2811
 *    QUALIFICATIONS
2812
 *
2813
 *****************************************************************************/
2814
2815
/*
2816
 * distribute_quals_to_rels
2817
 *    Convenience routine to apply distribute_qual_to_rels to each element
2818
 *    of an AND'ed list of clauses.
2819
 */
2820
static void
2821
distribute_quals_to_rels(PlannerInfo *root, List *clauses,
2822
             JoinTreeItem *jtitem,
2823
             SpecialJoinInfo *sjinfo,
2824
             Index security_level,
2825
             Relids qualscope,
2826
             Relids ojscope,
2827
             Relids outerjoin_nonnullable,
2828
             Relids incompatible_relids,
2829
             bool allow_equivalence,
2830
             bool has_clone,
2831
             bool is_clone,
2832
             List **postponed_oj_qual_list)
2833
0
{
2834
0
  ListCell   *lc;
2835
2836
0
  foreach(lc, clauses)
2837
0
  {
2838
0
    Node     *clause = (Node *) lfirst(lc);
2839
2840
0
    distribute_qual_to_rels(root, clause,
2841
0
                jtitem,
2842
0
                sjinfo,
2843
0
                security_level,
2844
0
                qualscope,
2845
0
                ojscope,
2846
0
                outerjoin_nonnullable,
2847
0
                incompatible_relids,
2848
0
                allow_equivalence,
2849
0
                has_clone,
2850
0
                is_clone,
2851
0
                postponed_oj_qual_list);
2852
0
  }
2853
0
}
2854
2855
/*
2856
 * distribute_qual_to_rels
2857
 *    Add clause information to either the baserestrictinfo or joininfo list
2858
 *    (depending on whether the clause is a join) of each base relation
2859
 *    mentioned in the clause.  A RestrictInfo node is created and added to
2860
 *    the appropriate list for each rel.  Alternatively, if the clause uses a
2861
 *    mergejoinable operator, enter its left- and right-side expressions into
2862
 *    the query's EquivalenceClasses.
2863
 *
2864
 * In some cases, quals will be added to parent jtitems' lateral_clauses
2865
 * or to postponed_oj_qual_list instead of being processed right away.
2866
 * These will be dealt with in later calls of deconstruct_distribute.
2867
 *
2868
 * 'clause': the qual clause to be distributed
2869
 * 'jtitem': the JoinTreeItem for the containing jointree node
2870
 * 'sjinfo': join's SpecialJoinInfo (NULL for an inner join or WHERE clause)
2871
 * 'security_level': security_level to assign to the qual
2872
 * 'qualscope': set of base+OJ rels the qual's syntactic scope covers
2873
 * 'ojscope': NULL if not an outer-join qual, else the minimum set of base+OJ
2874
 *    rels needed to form this join
2875
 * 'outerjoin_nonnullable': NULL if not an outer-join qual, else the set of
2876
 *    base+OJ rels appearing on the outer (nonnullable) side of the join
2877
 *    (for FULL JOIN this includes both sides of the join, and must in fact
2878
 *    equal qualscope)
2879
 * 'incompatible_relids': the set of outer-join relid(s) that must not be
2880
 *    computed below this qual.  We only bother to compute this for
2881
 *    "clone" quals, otherwise it can be left NULL.
2882
 * 'allow_equivalence': true if it's okay to convert clause into an
2883
 *    EquivalenceClass
2884
 * 'has_clone': has_clone property to assign to the qual
2885
 * 'is_clone': is_clone property to assign to the qual
2886
 * 'postponed_oj_qual_list': if not NULL, non-degenerate outer join clauses
2887
 *    should be added to this list instead of being processed (list entries
2888
 *    are just the bare clauses)
2889
 *
2890
 * 'qualscope' identifies what level of JOIN the qual came from syntactically.
2891
 * 'ojscope' is needed if we decide to force the qual up to the outer-join
2892
 * level, which will be ojscope not necessarily qualscope.
2893
 */
2894
static void
2895
distribute_qual_to_rels(PlannerInfo *root, Node *clause,
2896
            JoinTreeItem *jtitem,
2897
            SpecialJoinInfo *sjinfo,
2898
            Index security_level,
2899
            Relids qualscope,
2900
            Relids ojscope,
2901
            Relids outerjoin_nonnullable,
2902
            Relids incompatible_relids,
2903
            bool allow_equivalence,
2904
            bool has_clone,
2905
            bool is_clone,
2906
            List **postponed_oj_qual_list)
2907
0
{
2908
0
  Relids    relids;
2909
0
  bool    is_pushed_down;
2910
0
  bool    pseudoconstant = false;
2911
0
  bool    maybe_equivalence;
2912
0
  bool    maybe_outer_join;
2913
0
  RestrictInfo *restrictinfo;
2914
2915
  /*
2916
   * Retrieve all relids mentioned within the clause.
2917
   */
2918
0
  relids = pull_varnos(root, clause);
2919
2920
  /*
2921
   * In ordinary SQL, a WHERE or JOIN/ON clause can't reference any rels
2922
   * that aren't within its syntactic scope; however, if we pulled up a
2923
   * LATERAL subquery then we might find such references in quals that have
2924
   * been pulled up.  We need to treat such quals as belonging to the join
2925
   * level that includes every rel they reference.  Although we could make
2926
   * pull_up_subqueries() place such quals correctly to begin with, it's
2927
   * easier to handle it here.  When we find a clause that contains Vars
2928
   * outside its syntactic scope, locate the nearest parent join level that
2929
   * includes all the required rels and add the clause to that level's
2930
   * lateral_clauses list.  We'll process it when we reach that join level.
2931
   */
2932
0
  if (!bms_is_subset(relids, qualscope))
2933
0
  {
2934
0
    JoinTreeItem *pitem;
2935
2936
0
    Assert(root->hasLateralRTEs); /* shouldn't happen otherwise */
2937
0
    Assert(sjinfo == NULL); /* mustn't postpone past outer join */
2938
0
    for (pitem = jtitem->jti_parent; pitem; pitem = pitem->jti_parent)
2939
0
    {
2940
0
      if (bms_is_subset(relids, pitem->qualscope))
2941
0
      {
2942
0
        pitem->lateral_clauses = lappend(pitem->lateral_clauses,
2943
0
                         clause);
2944
0
        return;
2945
0
      }
2946
2947
      /*
2948
       * We should not be postponing any quals past an outer join.  If
2949
       * this Assert fires, pull_up_subqueries() messed up.
2950
       */
2951
0
      Assert(pitem->sjinfo == NULL);
2952
0
    }
2953
0
    elog(ERROR, "failed to postpone qual containing lateral reference");
2954
0
  }
2955
2956
  /*
2957
   * If it's an outer-join clause, also check that relids is a subset of
2958
   * ojscope.  (This should not fail if the syntactic scope check passed.)
2959
   */
2960
0
  if (ojscope && !bms_is_subset(relids, ojscope))
2961
0
    elog(ERROR, "JOIN qualification cannot refer to other relations");
2962
2963
  /*
2964
   * If the clause is variable-free, our normal heuristic for pushing it
2965
   * down to just the mentioned rels doesn't work, because there are none.
2966
   *
2967
   * If the clause is an outer-join clause, we must force it to the OJ's
2968
   * semantic level to preserve semantics.
2969
   *
2970
   * Otherwise, when the clause contains volatile functions, we force it to
2971
   * be evaluated at its original syntactic level.  This preserves the
2972
   * expected semantics.
2973
   *
2974
   * When the clause contains no volatile functions either, it is actually a
2975
   * pseudoconstant clause that will not change value during any one
2976
   * execution of the plan, and hence can be used as a one-time qual in a
2977
   * gating Result plan node.  We put such a clause into the regular
2978
   * RestrictInfo lists for the moment, but eventually createplan.c will
2979
   * pull it out and make a gating Result node immediately above whatever
2980
   * plan node the pseudoconstant clause is assigned to.  It's usually best
2981
   * to put a gating node as high in the plan tree as possible.
2982
   */
2983
0
  if (bms_is_empty(relids))
2984
0
  {
2985
0
    if (ojscope)
2986
0
    {
2987
      /* clause is attached to outer join, eval it there */
2988
0
      relids = bms_copy(ojscope);
2989
      /* mustn't use as gating qual, so don't mark pseudoconstant */
2990
0
    }
2991
0
    else if (contain_volatile_functions(clause))
2992
0
    {
2993
      /* eval at original syntactic level */
2994
0
      relids = bms_copy(qualscope);
2995
      /* again, can't mark pseudoconstant */
2996
0
    }
2997
0
    else
2998
0
    {
2999
      /*
3000
       * If we are in the top-level join domain, we can push the qual to
3001
       * the top of the plan tree.  Otherwise, be conservative and eval
3002
       * it at original syntactic level.  (Ideally we'd push it to the
3003
       * top of the current join domain in all cases, but that causes
3004
       * problems if we later rearrange outer-join evaluation order.
3005
       * Pseudoconstant quals below the top level are a pretty odd case,
3006
       * so it's not clear that it's worth working hard on.)
3007
       */
3008
0
      if (jtitem->jdomain == (JoinDomain *) linitial(root->join_domains))
3009
0
        relids = bms_copy(jtitem->jdomain->jd_relids);
3010
0
      else
3011
0
        relids = bms_copy(qualscope);
3012
      /* mark as gating qual */
3013
0
      pseudoconstant = true;
3014
      /* tell createplan.c to check for gating quals */
3015
0
      root->hasPseudoConstantQuals = true;
3016
0
    }
3017
0
  }
3018
3019
  /*----------
3020
   * Check to see if clause application must be delayed by outer-join
3021
   * considerations.
3022
   *
3023
   * A word about is_pushed_down: we mark the qual as "pushed down" if
3024
   * it is (potentially) applicable at a level different from its original
3025
   * syntactic level.  This flag is used to distinguish OUTER JOIN ON quals
3026
   * from other quals pushed down to the same joinrel.  The rules are:
3027
   *    WHERE quals and INNER JOIN quals: is_pushed_down = true.
3028
   *    Non-degenerate OUTER JOIN quals: is_pushed_down = false.
3029
   *    Degenerate OUTER JOIN quals: is_pushed_down = true.
3030
   * A "degenerate" OUTER JOIN qual is one that doesn't mention the
3031
   * non-nullable side, and hence can be pushed down into the nullable side
3032
   * without changing the join result.  It is correct to treat it as a
3033
   * regular filter condition at the level where it is evaluated.
3034
   *
3035
   * Note: it is not immediately obvious that a simple boolean is enough
3036
   * for this: if for some reason we were to attach a degenerate qual to
3037
   * its original join level, it would need to be treated as an outer join
3038
   * qual there.  However, this cannot happen, because all the rels the
3039
   * clause mentions must be in the outer join's min_righthand, therefore
3040
   * the join it needs must be formed before the outer join; and we always
3041
   * attach quals to the lowest level where they can be evaluated.  But
3042
   * if we were ever to re-introduce a mechanism for delaying evaluation
3043
   * of "expensive" quals, this area would need work.
3044
   *
3045
   * Note: generally, use of is_pushed_down has to go through the macro
3046
   * RINFO_IS_PUSHED_DOWN, because that flag alone is not always sufficient
3047
   * to tell whether a clause must be treated as pushed-down in context.
3048
   * This seems like another reason why it should perhaps be rethought.
3049
   *----------
3050
   */
3051
0
  if (bms_overlap(relids, outerjoin_nonnullable))
3052
0
  {
3053
    /*
3054
     * The qual is attached to an outer join and mentions (some of the)
3055
     * rels on the nonnullable side, so it's not degenerate.  If the
3056
     * caller wants to postpone handling such clauses, just add it to
3057
     * postponed_oj_qual_list and return.  (The work we've done up to here
3058
     * will have to be redone later, but there's not much of it.)
3059
     */
3060
0
    if (postponed_oj_qual_list != NULL)
3061
0
    {
3062
0
      *postponed_oj_qual_list = lappend(*postponed_oj_qual_list, clause);
3063
0
      return;
3064
0
    }
3065
3066
    /*
3067
     * We can't use such a clause to deduce equivalence (the left and
3068
     * right sides might be unequal above the join because one of them has
3069
     * gone to NULL) ... but we might be able to use it for more limited
3070
     * deductions, if it is mergejoinable.  So consider adding it to the
3071
     * lists of set-aside outer-join clauses.
3072
     */
3073
0
    is_pushed_down = false;
3074
0
    maybe_equivalence = false;
3075
0
    maybe_outer_join = true;
3076
3077
    /*
3078
     * Now force the qual to be evaluated exactly at the level of joining
3079
     * corresponding to the outer join.  We cannot let it get pushed down
3080
     * into the nonnullable side, since then we'd produce no output rows,
3081
     * rather than the intended single null-extended row, for any
3082
     * nonnullable-side rows failing the qual.
3083
     */
3084
0
    Assert(ojscope);
3085
0
    relids = ojscope;
3086
0
    Assert(!pseudoconstant);
3087
0
  }
3088
0
  else
3089
0
  {
3090
    /*
3091
     * Normal qual clause or degenerate outer-join clause.  Either way, we
3092
     * can mark it as pushed-down.
3093
     */
3094
0
    is_pushed_down = true;
3095
3096
    /* Feed qual to the equivalence machinery, if allowed by caller */
3097
0
    maybe_equivalence = allow_equivalence;
3098
3099
    /*
3100
     * Since it doesn't mention the LHS, it's certainly not useful as a
3101
     * set-aside OJ clause, even if it's in an OJ.
3102
     */
3103
0
    maybe_outer_join = false;
3104
0
  }
3105
3106
  /*
3107
   * Build the RestrictInfo node itself.
3108
   */
3109
0
  restrictinfo = make_restrictinfo(root,
3110
0
                   (Expr *) clause,
3111
0
                   is_pushed_down,
3112
0
                   has_clone,
3113
0
                   is_clone,
3114
0
                   pseudoconstant,
3115
0
                   security_level,
3116
0
                   relids,
3117
0
                   incompatible_relids,
3118
0
                   outerjoin_nonnullable);
3119
3120
  /*
3121
   * If it's a join clause, add vars used in the clause to targetlists of
3122
   * their relations, so that they will be emitted by the plan nodes that
3123
   * scan those relations (else they won't be available at the join node!).
3124
   *
3125
   * Normally we mark the vars as needed at the join identified by "relids".
3126
   * However, if this is a clone clause then ignore the outer-join relids in
3127
   * that set.  Otherwise, vars appearing in a cloned clause would end up
3128
   * marked as having to propagate to the highest one of the commuting
3129
   * joins, which would often be an overestimate.  For such clauses, correct
3130
   * var propagation is ensured by making ojscope include input rels from
3131
   * both sides of the join.
3132
   *
3133
   * Note: if the clause gets absorbed into an EquivalenceClass then this
3134
   * may be unnecessary, but for now we have to do it to cover the case
3135
   * where the EC becomes ec_broken and we end up reinserting the original
3136
   * clauses into the plan.
3137
   */
3138
0
  if (bms_membership(relids) == BMS_MULTIPLE)
3139
0
  {
3140
0
    List     *vars = pull_var_clause(clause,
3141
0
                       PVC_RECURSE_AGGREGATES |
3142
0
                       PVC_RECURSE_WINDOWFUNCS |
3143
0
                       PVC_INCLUDE_PLACEHOLDERS);
3144
0
    Relids    where_needed;
3145
3146
0
    if (is_clone)
3147
0
      where_needed = bms_intersect(relids, root->all_baserels);
3148
0
    else
3149
0
      where_needed = relids;
3150
0
    add_vars_to_targetlist(root, vars, where_needed);
3151
0
    list_free(vars);
3152
0
  }
3153
3154
  /*
3155
   * We check "mergejoinability" of every clause, not only join clauses,
3156
   * because we want to know about equivalences between vars of the same
3157
   * relation, or between vars and consts.
3158
   */
3159
0
  check_mergejoinable(restrictinfo);
3160
3161
  /*
3162
   * If it is a true equivalence clause, send it to the EquivalenceClass
3163
   * machinery.  We do *not* attach it directly to any restriction or join
3164
   * lists.  The EC code will propagate it to the appropriate places later.
3165
   *
3166
   * If the clause has a mergejoinable operator, yet isn't an equivalence
3167
   * because it is an outer-join clause, the EC code may still be able to do
3168
   * something with it.  We add it to appropriate lists for further
3169
   * consideration later.  Specifically:
3170
   *
3171
   * If it is a left or right outer-join qualification that relates the two
3172
   * sides of the outer join (no funny business like leftvar1 = leftvar2 +
3173
   * rightvar), we add it to root->left_join_clauses or
3174
   * root->right_join_clauses according to which side the nonnullable
3175
   * variable appears on.
3176
   *
3177
   * If it is a full outer-join qualification, we add it to
3178
   * root->full_join_clauses.  (Ideally we'd discard cases that aren't
3179
   * leftvar = rightvar, as we do for left/right joins, but this routine
3180
   * doesn't have the info needed to do that; and the current usage of the
3181
   * full_join_clauses list doesn't require that, so it's not currently
3182
   * worth complicating this routine's API to make it possible.)
3183
   *
3184
   * If none of the above hold, pass it off to
3185
   * distribute_restrictinfo_to_rels().
3186
   *
3187
   * In all cases, it's important to initialize the left_ec and right_ec
3188
   * fields of a mergejoinable clause, so that all possibly mergejoinable
3189
   * expressions have representations in EquivalenceClasses.  If
3190
   * process_equivalence is successful, it will take care of that;
3191
   * otherwise, we have to call initialize_mergeclause_eclasses to do it.
3192
   */
3193
0
  if (restrictinfo->mergeopfamilies)
3194
0
  {
3195
0
    if (maybe_equivalence)
3196
0
    {
3197
0
      if (process_equivalence(root, &restrictinfo, jtitem->jdomain))
3198
0
        return;
3199
      /* EC rejected it, so set left_ec/right_ec the hard way ... */
3200
0
      if (restrictinfo->mergeopfamilies) /* EC might have changed this */
3201
0
        initialize_mergeclause_eclasses(root, restrictinfo);
3202
      /* ... and fall through to distribute_restrictinfo_to_rels */
3203
0
    }
3204
0
    else if (maybe_outer_join && restrictinfo->can_join)
3205
0
    {
3206
      /* we need to set up left_ec/right_ec the hard way */
3207
0
      initialize_mergeclause_eclasses(root, restrictinfo);
3208
      /* now see if it should go to any outer-join lists */
3209
0
      Assert(sjinfo != NULL);
3210
0
      if (bms_is_subset(restrictinfo->left_relids,
3211
0
                outerjoin_nonnullable) &&
3212
0
        !bms_overlap(restrictinfo->right_relids,
3213
0
               outerjoin_nonnullable))
3214
0
      {
3215
        /* we have outervar = innervar */
3216
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3217
3218
0
        ojcinfo->rinfo = restrictinfo;
3219
0
        ojcinfo->sjinfo = sjinfo;
3220
0
        root->left_join_clauses = lappend(root->left_join_clauses,
3221
0
                          ojcinfo);
3222
0
        return;
3223
0
      }
3224
0
      if (bms_is_subset(restrictinfo->right_relids,
3225
0
                outerjoin_nonnullable) &&
3226
0
        !bms_overlap(restrictinfo->left_relids,
3227
0
               outerjoin_nonnullable))
3228
0
      {
3229
        /* we have innervar = outervar */
3230
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3231
3232
0
        ojcinfo->rinfo = restrictinfo;
3233
0
        ojcinfo->sjinfo = sjinfo;
3234
0
        root->right_join_clauses = lappend(root->right_join_clauses,
3235
0
                           ojcinfo);
3236
0
        return;
3237
0
      }
3238
0
      if (sjinfo->jointype == JOIN_FULL)
3239
0
      {
3240
        /* FULL JOIN (above tests cannot match in this case) */
3241
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3242
3243
0
        ojcinfo->rinfo = restrictinfo;
3244
0
        ojcinfo->sjinfo = sjinfo;
3245
0
        root->full_join_clauses = lappend(root->full_join_clauses,
3246
0
                          ojcinfo);
3247
0
        return;
3248
0
      }
3249
      /* nope, so fall through to distribute_restrictinfo_to_rels */
3250
0
    }
3251
0
    else
3252
0
    {
3253
      /* we still need to set up left_ec/right_ec */
3254
0
      initialize_mergeclause_eclasses(root, restrictinfo);
3255
0
    }
3256
0
  }
3257
3258
  /* No EC special case applies, so push it into the clause lists */
3259
0
  distribute_restrictinfo_to_rels(root, restrictinfo);
3260
0
}
3261
3262
/*
3263
 * add_base_clause_to_rel
3264
 *    Add 'restrictinfo' as a baserestrictinfo to the base relation denoted
3265
 *    by 'relid'.  We offer some simple prechecks to try to determine if the
3266
 *    qual is always true, in which case we ignore it rather than add it.
3267
 *    If we detect the qual is always false, we replace it with
3268
 *    constant-FALSE.
3269
 */
3270
static void
3271
add_base_clause_to_rel(PlannerInfo *root, Index relid,
3272
             RestrictInfo *restrictinfo)
3273
0
{
3274
0
  RelOptInfo *rel = find_base_rel(root, relid);
3275
0
  RangeTblEntry *rte = root->simple_rte_array[relid];
3276
3277
0
  Assert(bms_membership(restrictinfo->required_relids) == BMS_SINGLETON);
3278
3279
  /*
3280
   * For inheritance parent tables, we must always record the RestrictInfo
3281
   * in baserestrictinfo as is.  If we were to transform or skip adding it,
3282
   * then the original wouldn't be available in apply_child_basequals. Since
3283
   * there are two RangeTblEntries for inheritance parents, one with
3284
   * inh==true and the other with inh==false, we're still able to apply this
3285
   * optimization to the inh==false one.  The inh==true one is what
3286
   * apply_child_basequals() sees, whereas the inh==false one is what's used
3287
   * for the scan node in the final plan.
3288
   *
3289
   * We make an exception to this for partitioned tables.  For these, we
3290
   * always apply the constant-TRUE and constant-FALSE transformations.  A
3291
   * qual which is either of these for a partitioned table must also be that
3292
   * for all of its child partitions.
3293
   */
3294
0
  if (!rte->inh || rte->relkind == RELKIND_PARTITIONED_TABLE)
3295
0
  {
3296
    /* Don't add the clause if it is always true */
3297
0
    if (restriction_is_always_true(root, restrictinfo))
3298
0
      return;
3299
3300
    /*
3301
     * Substitute the origin qual with constant-FALSE if it is provably
3302
     * always false.
3303
     *
3304
     * Note that we need to keep the same rinfo_serial, since it is in
3305
     * practice the same condition.  We also need to reset the
3306
     * last_rinfo_serial counter, which is essential to ensure that the
3307
     * RestrictInfos for the "same" qual condition get identical serial
3308
     * numbers (see deconstruct_distribute_oj_quals).
3309
     */
3310
0
    if (restriction_is_always_false(root, restrictinfo))
3311
0
    {
3312
0
      int     save_rinfo_serial = restrictinfo->rinfo_serial;
3313
0
      int     save_last_rinfo_serial = root->last_rinfo_serial;
3314
3315
0
      restrictinfo = make_restrictinfo(root,
3316
0
                       (Expr *) makeBoolConst(false, false),
3317
0
                       restrictinfo->is_pushed_down,
3318
0
                       restrictinfo->has_clone,
3319
0
                       restrictinfo->is_clone,
3320
0
                       restrictinfo->pseudoconstant,
3321
0
                       0, /* security_level */
3322
0
                       restrictinfo->required_relids,
3323
0
                       restrictinfo->incompatible_relids,
3324
0
                       restrictinfo->outer_relids);
3325
0
      restrictinfo->rinfo_serial = save_rinfo_serial;
3326
0
      root->last_rinfo_serial = save_last_rinfo_serial;
3327
0
    }
3328
0
  }
3329
3330
  /* Add clause to rel's restriction list */
3331
0
  rel->baserestrictinfo = lappend(rel->baserestrictinfo, restrictinfo);
3332
3333
  /* Update security level info */
3334
0
  rel->baserestrict_min_security = Min(rel->baserestrict_min_security,
3335
0
                     restrictinfo->security_level);
3336
0
}
3337
3338
/*
3339
 * restriction_is_always_true
3340
 *    Check to see if the RestrictInfo is always true.
3341
 *
3342
 * Currently we only check for NullTest quals and OR clauses that include
3343
 * NullTest quals.  We may extend it in the future.
3344
 */
3345
bool
3346
restriction_is_always_true(PlannerInfo *root,
3347
               RestrictInfo *restrictinfo)
3348
0
{
3349
  /*
3350
   * For a clone clause, we don't have a reliable way to determine if the
3351
   * input expression of a NullTest is non-nullable: nullingrel bits in
3352
   * clone clauses may not reflect reality, so we dare not draw conclusions
3353
   * from clones about whether Vars are guaranteed not-null.
3354
   */
3355
0
  if (restrictinfo->has_clone || restrictinfo->is_clone)
3356
0
    return false;
3357
3358
  /* Check for NullTest qual */
3359
0
  if (IsA(restrictinfo->clause, NullTest))
3360
0
  {
3361
0
    NullTest   *nulltest = (NullTest *) restrictinfo->clause;
3362
3363
    /* is this NullTest an IS_NOT_NULL qual? */
3364
0
    if (nulltest->nulltesttype != IS_NOT_NULL)
3365
0
      return false;
3366
3367
    /*
3368
     * Empty rows can appear NULL in some contexts and NOT NULL in others,
3369
     * so avoid this optimization for row expressions.
3370
     */
3371
0
    if (nulltest->argisrow)
3372
0
      return false;
3373
3374
0
    return expr_is_nonnullable(root, nulltest->arg, NOTNULL_SOURCE_RELOPT);
3375
0
  }
3376
3377
  /* If it's an OR, check its sub-clauses */
3378
0
  if (restriction_is_or_clause(restrictinfo))
3379
0
  {
3380
0
    ListCell   *lc;
3381
3382
0
    Assert(is_orclause(restrictinfo->orclause));
3383
3384
    /*
3385
     * if any of the given OR branches is provably always true then the
3386
     * entire condition is true.
3387
     */
3388
0
    foreach(lc, ((BoolExpr *) restrictinfo->orclause)->args)
3389
0
    {
3390
0
      Node     *orarg = (Node *) lfirst(lc);
3391
3392
0
      if (!IsA(orarg, RestrictInfo))
3393
0
        continue;
3394
3395
0
      if (restriction_is_always_true(root, (RestrictInfo *) orarg))
3396
0
        return true;
3397
0
    }
3398
0
  }
3399
3400
0
  return false;
3401
0
}
3402
3403
/*
3404
 * restriction_is_always_false
3405
 *    Check to see if the RestrictInfo is always false.
3406
 *
3407
 * Currently we only check for NullTest quals and OR clauses that include
3408
 * NullTest quals.  We may extend it in the future.
3409
 */
3410
bool
3411
restriction_is_always_false(PlannerInfo *root,
3412
              RestrictInfo *restrictinfo)
3413
0
{
3414
  /*
3415
   * For a clone clause, we don't have a reliable way to determine if the
3416
   * input expression of a NullTest is non-nullable: nullingrel bits in
3417
   * clone clauses may not reflect reality, so we dare not draw conclusions
3418
   * from clones about whether Vars are guaranteed not-null.
3419
   */
3420
0
  if (restrictinfo->has_clone || restrictinfo->is_clone)
3421
0
    return false;
3422
3423
  /* Check for NullTest qual */
3424
0
  if (IsA(restrictinfo->clause, NullTest))
3425
0
  {
3426
0
    NullTest   *nulltest = (NullTest *) restrictinfo->clause;
3427
3428
    /* is this NullTest an IS_NULL qual? */
3429
0
    if (nulltest->nulltesttype != IS_NULL)
3430
0
      return false;
3431
3432
    /*
3433
     * Empty rows can appear NULL in some contexts and NOT NULL in others,
3434
     * so avoid this optimization for row expressions.
3435
     */
3436
0
    if (nulltest->argisrow)
3437
0
      return false;
3438
3439
0
    return expr_is_nonnullable(root, nulltest->arg, NOTNULL_SOURCE_RELOPT);
3440
0
  }
3441
3442
  /* If it's an OR, check its sub-clauses */
3443
0
  if (restriction_is_or_clause(restrictinfo))
3444
0
  {
3445
0
    ListCell   *lc;
3446
3447
0
    Assert(is_orclause(restrictinfo->orclause));
3448
3449
    /*
3450
     * Currently, when processing OR expressions, we only return true when
3451
     * all of the OR branches are always false.  This could perhaps be
3452
     * expanded to remove OR branches that are provably false.  This may
3453
     * be a useful thing to do as it could result in the OR being left
3454
     * with a single arg.  That's useful as it would allow the OR
3455
     * condition to be replaced with its single argument which may allow
3456
     * use of an index for faster filtering on the remaining condition.
3457
     */
3458
0
    foreach(lc, ((BoolExpr *) restrictinfo->orclause)->args)
3459
0
    {
3460
0
      Node     *orarg = (Node *) lfirst(lc);
3461
3462
0
      if (!IsA(orarg, RestrictInfo) ||
3463
0
        !restriction_is_always_false(root, (RestrictInfo *) orarg))
3464
0
        return false;
3465
0
    }
3466
0
    return true;
3467
0
  }
3468
3469
0
  return false;
3470
0
}
3471
3472
/*
3473
 * distribute_restrictinfo_to_rels
3474
 *    Push a completed RestrictInfo into the proper restriction or join
3475
 *    clause list(s).
3476
 *
3477
 * This is the last step of distribute_qual_to_rels() for ordinary qual
3478
 * clauses.  Clauses that are interesting for equivalence-class processing
3479
 * are diverted to the EC machinery, but may ultimately get fed back here.
3480
 */
3481
void
3482
distribute_restrictinfo_to_rels(PlannerInfo *root,
3483
                RestrictInfo *restrictinfo)
3484
0
{
3485
0
  Relids    relids = restrictinfo->required_relids;
3486
3487
0
  if (!bms_is_empty(relids))
3488
0
  {
3489
0
    int     relid;
3490
3491
0
    if (bms_get_singleton_member(relids, &relid))
3492
0
    {
3493
      /*
3494
       * There is only one relation participating in the clause, so it
3495
       * is a restriction clause for that relation.
3496
       */
3497
0
      add_base_clause_to_rel(root, relid, restrictinfo);
3498
0
    }
3499
0
    else
3500
0
    {
3501
      /*
3502
       * The clause is a join clause, since there is more than one rel
3503
       * in its relid set.
3504
       */
3505
3506
      /*
3507
       * Check for hashjoinable operators.  (We don't bother setting the
3508
       * hashjoin info except in true join clauses.)
3509
       */
3510
0
      check_hashjoinable(restrictinfo);
3511
3512
      /*
3513
       * Likewise, check if the clause is suitable to be used with a
3514
       * Memoize node to cache inner tuples during a parameterized
3515
       * nested loop.
3516
       */
3517
0
      check_memoizable(restrictinfo);
3518
3519
      /*
3520
       * Add clause to the join lists of all the relevant relations.
3521
       */
3522
0
      add_join_clause_to_rels(root, restrictinfo, relids);
3523
0
    }
3524
0
  }
3525
0
  else
3526
0
  {
3527
    /*
3528
     * clause references no rels, and therefore we have no place to attach
3529
     * it.  Shouldn't get here if callers are working properly.
3530
     */
3531
0
    elog(ERROR, "cannot cope with variable-free clause");
3532
0
  }
3533
0
}
3534
3535
/*
3536
 * process_implied_equality
3537
 *    Create a restrictinfo item that says "item1 op item2", and push it
3538
 *    into the appropriate lists.  (In practice opno is always a btree
3539
 *    equality operator.)
3540
 *
3541
 * "qualscope" is the nominal syntactic level to impute to the restrictinfo.
3542
 * This must contain at least all the rels used in the expressions, but it
3543
 * is used only to set the qual application level when both exprs are
3544
 * variable-free.  (Hence, it should usually match the join domain in which
3545
 * the clause applies.)  Otherwise the qual is applied at the lowest join
3546
 * level that provides all its variables.
3547
 *
3548
 * "security_level" is the security level to assign to the new restrictinfo.
3549
 *
3550
 * "both_const" indicates whether both items are known pseudo-constant;
3551
 * in this case it is worth applying eval_const_expressions() in case we
3552
 * can produce constant TRUE or constant FALSE.  (Otherwise it's not,
3553
 * because the expressions went through eval_const_expressions already.)
3554
 *
3555
 * Returns the generated RestrictInfo, if any.  The result will be NULL
3556
 * if both_const is true and we successfully reduced the clause to
3557
 * constant TRUE.
3558
 *
3559
 * Note: this function will copy item1 and item2, but it is caller's
3560
 * responsibility to make sure that the Relids parameters are fresh copies
3561
 * not shared with other uses.
3562
 *
3563
 * Note: we do not do initialize_mergeclause_eclasses() here.  It is
3564
 * caller's responsibility that left_ec/right_ec be set as necessary.
3565
 */
3566
RestrictInfo *
3567
process_implied_equality(PlannerInfo *root,
3568
             Oid opno,
3569
             Oid collation,
3570
             Expr *item1,
3571
             Expr *item2,
3572
             Relids qualscope,
3573
             Index security_level,
3574
             bool both_const)
3575
0
{
3576
0
  RestrictInfo *restrictinfo;
3577
0
  Node     *clause;
3578
0
  Relids    relids;
3579
0
  bool    pseudoconstant = false;
3580
3581
  /*
3582
   * Build the new clause.  Copy to ensure it shares no substructure with
3583
   * original (this is necessary in case there are subselects in there...)
3584
   */
3585
0
  clause = (Node *) make_opclause(opno,
3586
0
                  BOOLOID, /* opresulttype */
3587
0
                  false,  /* opretset */
3588
0
                  copyObject(item1),
3589
0
                  copyObject(item2),
3590
0
                  InvalidOid,
3591
0
                  collation);
3592
3593
  /* If both constant, try to reduce to a boolean constant. */
3594
0
  if (both_const)
3595
0
  {
3596
0
    clause = eval_const_expressions(root, clause);
3597
3598
    /* If we produced const TRUE, just drop the clause */
3599
0
    if (clause && IsA(clause, Const))
3600
0
    {
3601
0
      Const    *cclause = (Const *) clause;
3602
3603
0
      Assert(cclause->consttype == BOOLOID);
3604
0
      if (!cclause->constisnull && DatumGetBool(cclause->constvalue))
3605
0
        return NULL;
3606
0
    }
3607
0
  }
3608
3609
  /*
3610
   * The rest of this is a very cut-down version of distribute_qual_to_rels.
3611
   * We can skip most of the work therein, but there are a couple of special
3612
   * cases we still have to handle.
3613
   *
3614
   * Retrieve all relids mentioned within the possibly-simplified clause.
3615
   */
3616
0
  relids = pull_varnos(root, clause);
3617
0
  Assert(bms_is_subset(relids, qualscope));
3618
3619
  /*
3620
   * If the clause is variable-free, our normal heuristic for pushing it
3621
   * down to just the mentioned rels doesn't work, because there are none.
3622
   * Apply it as a gating qual at the appropriate level (see comments for
3623
   * get_join_domain_min_rels).
3624
   */
3625
0
  if (bms_is_empty(relids))
3626
0
  {
3627
    /* eval at join domain's safe level */
3628
0
    relids = get_join_domain_min_rels(root, qualscope);
3629
    /* mark as gating qual */
3630
0
    pseudoconstant = true;
3631
    /* tell createplan.c to check for gating quals */
3632
0
    root->hasPseudoConstantQuals = true;
3633
0
  }
3634
3635
  /*
3636
   * Build the RestrictInfo node itself.
3637
   */
3638
0
  restrictinfo = make_restrictinfo(root,
3639
0
                   (Expr *) clause,
3640
0
                   true, /* is_pushed_down */
3641
0
                   false, /* !has_clone */
3642
0
                   false, /* !is_clone */
3643
0
                   pseudoconstant,
3644
0
                   security_level,
3645
0
                   relids,
3646
0
                   NULL, /* incompatible_relids */
3647
0
                   NULL); /* outer_relids */
3648
3649
  /*
3650
   * If it's a join clause, add vars used in the clause to targetlists of
3651
   * their relations, so that they will be emitted by the plan nodes that
3652
   * scan those relations (else they won't be available at the join node!).
3653
   *
3654
   * Typically, we'd have already done this when the component expressions
3655
   * were first seen by distribute_qual_to_rels; but it is possible that
3656
   * some of the Vars could have missed having that done because they only
3657
   * appeared in single-relation clauses originally.  So do it here for
3658
   * safety.
3659
   */
3660
0
  if (bms_membership(relids) == BMS_MULTIPLE)
3661
0
  {
3662
0
    List     *vars = pull_var_clause(clause,
3663
0
                       PVC_RECURSE_AGGREGATES |
3664
0
                       PVC_RECURSE_WINDOWFUNCS |
3665
0
                       PVC_INCLUDE_PLACEHOLDERS);
3666
3667
0
    add_vars_to_targetlist(root, vars, relids);
3668
0
    list_free(vars);
3669
0
  }
3670
3671
  /*
3672
   * Check mergejoinability.  This will usually succeed, since the op came
3673
   * from an EquivalenceClass; but we could have reduced the original clause
3674
   * to a constant.
3675
   */
3676
0
  check_mergejoinable(restrictinfo);
3677
3678
  /*
3679
   * Note we don't do initialize_mergeclause_eclasses(); the caller can
3680
   * handle that much more cheaply than we can.  It's okay to call
3681
   * distribute_restrictinfo_to_rels() before that happens.
3682
   */
3683
3684
  /*
3685
   * Push the new clause into all the appropriate restrictinfo lists.
3686
   */
3687
0
  distribute_restrictinfo_to_rels(root, restrictinfo);
3688
3689
0
  return restrictinfo;
3690
0
}
3691
3692
/*
3693
 * build_implied_join_equality --- build a RestrictInfo for a derived equality
3694
 *
3695
 * This overlaps the functionality of process_implied_equality(), but we
3696
 * must not push the RestrictInfo into the joininfo tree.
3697
 *
3698
 * Note: this function will copy item1 and item2, but it is caller's
3699
 * responsibility to make sure that the Relids parameters are fresh copies
3700
 * not shared with other uses.
3701
 *
3702
 * Note: we do not do initialize_mergeclause_eclasses() here.  It is
3703
 * caller's responsibility that left_ec/right_ec be set as necessary.
3704
 */
3705
RestrictInfo *
3706
build_implied_join_equality(PlannerInfo *root,
3707
              Oid opno,
3708
              Oid collation,
3709
              Expr *item1,
3710
              Expr *item2,
3711
              Relids qualscope,
3712
              Index security_level)
3713
0
{
3714
0
  RestrictInfo *restrictinfo;
3715
0
  Expr     *clause;
3716
3717
  /*
3718
   * Build the new clause.  Copy to ensure it shares no substructure with
3719
   * original (this is necessary in case there are subselects in there...)
3720
   */
3721
0
  clause = make_opclause(opno,
3722
0
               BOOLOID, /* opresulttype */
3723
0
               false,  /* opretset */
3724
0
               copyObject(item1),
3725
0
               copyObject(item2),
3726
0
               InvalidOid,
3727
0
               collation);
3728
3729
  /*
3730
   * Build the RestrictInfo node itself.
3731
   */
3732
0
  restrictinfo = make_restrictinfo(root,
3733
0
                   clause,
3734
0
                   true, /* is_pushed_down */
3735
0
                   false, /* !has_clone */
3736
0
                   false, /* !is_clone */
3737
0
                   false, /* pseudoconstant */
3738
0
                   security_level,  /* security_level */
3739
0
                   qualscope, /* required_relids */
3740
0
                   NULL, /* incompatible_relids */
3741
0
                   NULL); /* outer_relids */
3742
3743
  /* Set mergejoinability/hashjoinability flags */
3744
0
  check_mergejoinable(restrictinfo);
3745
0
  check_hashjoinable(restrictinfo);
3746
0
  check_memoizable(restrictinfo);
3747
3748
0
  return restrictinfo;
3749
0
}
3750
3751
/*
3752
 * get_join_domain_min_rels
3753
 *    Identify the appropriate join level for derived quals belonging
3754
 *    to the join domain with the given relids.
3755
 *
3756
 * When we derive a pseudoconstant (Var-free) clause from an EquivalenceClass,
3757
 * we'd ideally apply the clause at the top level of the EC's join domain.
3758
 * However, if there are any outer joins inside that domain that get commuted
3759
 * with joins outside it, that leads to not finding a correct place to apply
3760
 * the clause.  Instead, remove any lower outer joins from the relid set,
3761
 * and apply the clause to just the remaining rels.  This still results in a
3762
 * correct answer, since if the clause produces FALSE then the LHS of these
3763
 * joins will be empty leading to an empty join result.
3764
 *
3765
 * However, there's no need to remove outer joins if this is the top-level
3766
 * join domain of the query, since then there's nothing else to commute with.
3767
 *
3768
 * Note: it's tempting to use this in distribute_qual_to_rels where it's
3769
 * dealing with pseudoconstant quals; but we can't because the necessary
3770
 * SpecialJoinInfos aren't all formed at that point.
3771
 *
3772
 * The result is always freshly palloc'd; we do not modify domain_relids.
3773
 */
3774
static Relids
3775
get_join_domain_min_rels(PlannerInfo *root, Relids domain_relids)
3776
0
{
3777
0
  Relids    result = bms_copy(domain_relids);
3778
0
  ListCell   *lc;
3779
3780
  /* Top-level join domain? */
3781
0
  if (bms_equal(result, root->all_query_rels))
3782
0
    return result;
3783
3784
  /* Nope, look for lower outer joins that could potentially commute out */
3785
0
  foreach(lc, root->join_info_list)
3786
0
  {
3787
0
    SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
3788
3789
0
    if (sjinfo->jointype == JOIN_LEFT &&
3790
0
      bms_is_member(sjinfo->ojrelid, result))
3791
0
    {
3792
0
      result = bms_del_member(result, sjinfo->ojrelid);
3793
0
      result = bms_del_members(result, sjinfo->syn_righthand);
3794
0
    }
3795
0
  }
3796
0
  return result;
3797
0
}
3798
3799
3800
/*
3801
 * match_foreign_keys_to_quals
3802
 *    Match foreign-key constraints to equivalence classes and join quals
3803
 *
3804
 * The idea here is to see which query join conditions match equality
3805
 * constraints of a foreign-key relationship.  For such join conditions,
3806
 * we can use the FK semantics to make selectivity estimates that are more
3807
 * reliable than estimating from statistics, especially for multiple-column
3808
 * FKs, where the normal assumption of independent conditions tends to fail.
3809
 *
3810
 * In this function we annotate the ForeignKeyOptInfos in root->fkey_list
3811
 * with info about which eclasses and join qual clauses they match, and
3812
 * discard any ForeignKeyOptInfos that are irrelevant for the query.
3813
 */
3814
void
3815
match_foreign_keys_to_quals(PlannerInfo *root)
3816
0
{
3817
0
  List     *newlist = NIL;
3818
0
  ListCell   *lc;
3819
3820
0
  foreach(lc, root->fkey_list)
3821
0
  {
3822
0
    ForeignKeyOptInfo *fkinfo = (ForeignKeyOptInfo *) lfirst(lc);
3823
0
    RelOptInfo *con_rel;
3824
0
    RelOptInfo *ref_rel;
3825
0
    int     colno;
3826
3827
    /*
3828
     * Either relid might identify a rel that is in the query's rtable but
3829
     * isn't referenced by the jointree (typically because it's been
3830
     * removed by join removal), so that it won't have a RelOptInfo. Hence
3831
     * don't use find_base_rel() here.  We can ignore such FKs.
3832
     */
3833
0
    if (fkinfo->con_relid >= root->simple_rel_array_size ||
3834
0
      fkinfo->ref_relid >= root->simple_rel_array_size)
3835
0
      continue;     /* just paranoia */
3836
0
    con_rel = root->simple_rel_array[fkinfo->con_relid];
3837
0
    if (con_rel == NULL)
3838
0
      continue;
3839
0
    ref_rel = root->simple_rel_array[fkinfo->ref_relid];
3840
0
    if (ref_rel == NULL)
3841
0
      continue;
3842
3843
    /*
3844
     * Ignore FK unless both rels are baserels.  This gets rid of FKs that
3845
     * link to inheritance child rels (otherrels).
3846
     */
3847
0
    if (con_rel->reloptkind != RELOPT_BASEREL ||
3848
0
      ref_rel->reloptkind != RELOPT_BASEREL)
3849
0
      continue;
3850
3851
    /*
3852
     * Scan the columns and try to match them to eclasses and quals.
3853
     *
3854
     * Note: for simple inner joins, any match should be in an eclass.
3855
     * "Loose" quals that syntactically match an FK equality must have
3856
     * been rejected for EC status because they are outer-join quals or
3857
     * similar.  We can still consider them to match the FK.
3858
     */
3859
0
    for (colno = 0; colno < fkinfo->nkeys; colno++)
3860
0
    {
3861
0
      EquivalenceClass *ec;
3862
0
      AttrNumber  con_attno,
3863
0
            ref_attno;
3864
0
      Oid     fpeqop;
3865
0
      ListCell   *lc2;
3866
3867
0
      ec = match_eclasses_to_foreign_key_col(root, fkinfo, colno);
3868
      /* Don't bother looking for loose quals if we got an EC match */
3869
0
      if (ec != NULL)
3870
0
      {
3871
0
        fkinfo->nmatched_ec++;
3872
0
        if (ec->ec_has_const)
3873
0
          fkinfo->nconst_ec++;
3874
0
        continue;
3875
0
      }
3876
3877
      /*
3878
       * Scan joininfo list for relevant clauses.  Either rel's joininfo
3879
       * list would do equally well; we use con_rel's.
3880
       */
3881
0
      con_attno = fkinfo->conkey[colno];
3882
0
      ref_attno = fkinfo->confkey[colno];
3883
0
      fpeqop = InvalidOid; /* we'll look this up only if needed */
3884
3885
0
      foreach(lc2, con_rel->joininfo)
3886
0
      {
3887
0
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc2);
3888
0
        OpExpr     *clause = (OpExpr *) rinfo->clause;
3889
0
        Var      *leftvar;
3890
0
        Var      *rightvar;
3891
3892
        /* Only binary OpExprs are useful for consideration */
3893
0
        if (!IsA(clause, OpExpr) ||
3894
0
          list_length(clause->args) != 2)
3895
0
          continue;
3896
0
        leftvar = (Var *) get_leftop((Expr *) clause);
3897
0
        rightvar = (Var *) get_rightop((Expr *) clause);
3898
3899
        /* Operands must be Vars, possibly with RelabelType */
3900
0
        while (leftvar && IsA(leftvar, RelabelType))
3901
0
          leftvar = (Var *) ((RelabelType *) leftvar)->arg;
3902
0
        if (!(leftvar && IsA(leftvar, Var)))
3903
0
          continue;
3904
0
        while (rightvar && IsA(rightvar, RelabelType))
3905
0
          rightvar = (Var *) ((RelabelType *) rightvar)->arg;
3906
0
        if (!(rightvar && IsA(rightvar, Var)))
3907
0
          continue;
3908
3909
        /* Now try to match the vars to the current foreign key cols */
3910
0
        if (fkinfo->ref_relid == leftvar->varno &&
3911
0
          ref_attno == leftvar->varattno &&
3912
0
          fkinfo->con_relid == rightvar->varno &&
3913
0
          con_attno == rightvar->varattno)
3914
0
        {
3915
          /* Vars match, but is it the right operator? */
3916
0
          if (clause->opno == fkinfo->conpfeqop[colno])
3917
0
          {
3918
0
            fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
3919
0
                            rinfo);
3920
0
            fkinfo->nmatched_ri++;
3921
0
          }
3922
0
        }
3923
0
        else if (fkinfo->ref_relid == rightvar->varno &&
3924
0
             ref_attno == rightvar->varattno &&
3925
0
             fkinfo->con_relid == leftvar->varno &&
3926
0
             con_attno == leftvar->varattno)
3927
0
        {
3928
          /*
3929
           * Reverse match, must check commutator operator.  Look it
3930
           * up if we didn't already.  (In the worst case we might
3931
           * do multiple lookups here, but that would require an FK
3932
           * equality operator without commutator, which is
3933
           * unlikely.)
3934
           */
3935
0
          if (!OidIsValid(fpeqop))
3936
0
            fpeqop = get_commutator(fkinfo->conpfeqop[colno]);
3937
0
          if (clause->opno == fpeqop)
3938
0
          {
3939
0
            fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
3940
0
                            rinfo);
3941
0
            fkinfo->nmatched_ri++;
3942
0
          }
3943
0
        }
3944
0
      }
3945
      /* If we found any matching loose quals, count col as matched */
3946
0
      if (fkinfo->rinfos[colno])
3947
0
        fkinfo->nmatched_rcols++;
3948
0
    }
3949
3950
    /*
3951
     * Currently, we drop multicolumn FKs that aren't fully matched to the
3952
     * query.  Later we might figure out how to derive some sort of
3953
     * estimate from them, in which case this test should be weakened to
3954
     * "if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) > 0)".
3955
     */
3956
0
    if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) == fkinfo->nkeys)
3957
0
      newlist = lappend(newlist, fkinfo);
3958
0
  }
3959
  /* Replace fkey_list, thereby discarding any useless entries */
3960
0
  root->fkey_list = newlist;
3961
0
}
3962
3963
3964
/*****************************************************************************
3965
 *
3966
 *   CHECKS FOR MERGEJOINABLE AND HASHJOINABLE CLAUSES
3967
 *
3968
 *****************************************************************************/
3969
3970
/*
3971
 * check_mergejoinable
3972
 *    If the restrictinfo's clause is mergejoinable, set the mergejoin
3973
 *    info fields in the restrictinfo.
3974
 *
3975
 *    Currently, we support mergejoin for binary opclauses where
3976
 *    the operator is a mergejoinable operator.  The arguments can be
3977
 *    anything --- as long as there are no volatile functions in them.
3978
 */
3979
static void
3980
check_mergejoinable(RestrictInfo *restrictinfo)
3981
0
{
3982
0
  Expr     *clause = restrictinfo->clause;
3983
0
  Oid     opno;
3984
0
  Node     *leftarg;
3985
3986
0
  if (restrictinfo->pseudoconstant)
3987
0
    return;
3988
0
  if (!is_opclause(clause))
3989
0
    return;
3990
0
  if (list_length(((OpExpr *) clause)->args) != 2)
3991
0
    return;
3992
3993
0
  opno = ((OpExpr *) clause)->opno;
3994
0
  leftarg = linitial(((OpExpr *) clause)->args);
3995
3996
0
  if (op_mergejoinable(opno, exprType(leftarg)) &&
3997
0
    !contain_volatile_functions((Node *) restrictinfo))
3998
0
    restrictinfo->mergeopfamilies = get_mergejoin_opfamilies(opno);
3999
4000
  /*
4001
   * Note: op_mergejoinable is just a hint; if we fail to find the operator
4002
   * in any btree opfamilies, mergeopfamilies remains NIL and so the clause
4003
   * is not treated as mergejoinable.
4004
   */
4005
0
}
4006
4007
/*
4008
 * check_hashjoinable
4009
 *    If the restrictinfo's clause is hashjoinable, set the hashjoin
4010
 *    info fields in the restrictinfo.
4011
 *
4012
 *    Currently, we support hashjoin for binary opclauses where
4013
 *    the operator is a hashjoinable operator.  The arguments can be
4014
 *    anything --- as long as there are no volatile functions in them.
4015
 */
4016
static void
4017
check_hashjoinable(RestrictInfo *restrictinfo)
4018
0
{
4019
0
  Expr     *clause = restrictinfo->clause;
4020
0
  Oid     opno;
4021
0
  Node     *leftarg;
4022
4023
0
  if (restrictinfo->pseudoconstant)
4024
0
    return;
4025
0
  if (!is_opclause(clause))
4026
0
    return;
4027
0
  if (list_length(((OpExpr *) clause)->args) != 2)
4028
0
    return;
4029
4030
0
  opno = ((OpExpr *) clause)->opno;
4031
0
  leftarg = linitial(((OpExpr *) clause)->args);
4032
4033
0
  if (op_hashjoinable(opno, exprType(leftarg)) &&
4034
0
    !contain_volatile_functions((Node *) restrictinfo))
4035
0
    restrictinfo->hashjoinoperator = opno;
4036
0
}
4037
4038
/*
4039
 * check_memoizable
4040
 *    If the restrictinfo's clause is suitable to be used for a Memoize node,
4041
 *    set the left_hasheqoperator and right_hasheqoperator to the hash equality
4042
 *    operator that will be needed during caching.
4043
 */
4044
static void
4045
check_memoizable(RestrictInfo *restrictinfo)
4046
0
{
4047
0
  TypeCacheEntry *typentry;
4048
0
  Expr     *clause = restrictinfo->clause;
4049
0
  Oid     lefttype;
4050
0
  Oid     righttype;
4051
4052
0
  if (restrictinfo->pseudoconstant)
4053
0
    return;
4054
0
  if (!is_opclause(clause))
4055
0
    return;
4056
0
  if (list_length(((OpExpr *) clause)->args) != 2)
4057
0
    return;
4058
4059
0
  lefttype = exprType(linitial(((OpExpr *) clause)->args));
4060
4061
0
  typentry = lookup_type_cache(lefttype, TYPECACHE_HASH_PROC |
4062
0
                 TYPECACHE_EQ_OPR);
4063
4064
0
  if (OidIsValid(typentry->hash_proc) && OidIsValid(typentry->eq_opr))
4065
0
    restrictinfo->left_hasheqoperator = typentry->eq_opr;
4066
4067
0
  righttype = exprType(lsecond(((OpExpr *) clause)->args));
4068
4069
  /*
4070
   * Lookup the right type, unless it's the same as the left type, in which
4071
   * case typentry is already pointing to the required TypeCacheEntry.
4072
   */
4073
0
  if (lefttype != righttype)
4074
0
    typentry = lookup_type_cache(righttype, TYPECACHE_HASH_PROC |
4075
0
                   TYPECACHE_EQ_OPR);
4076
4077
0
  if (OidIsValid(typentry->hash_proc) && OidIsValid(typentry->eq_opr))
4078
0
    restrictinfo->right_hasheqoperator = typentry->eq_opr;
4079
0
}