LCOV - code coverage report
Current view: top level - src/backend/optimizer/plan - initsplan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 961 993 96.8 %
Date: 2024-11-21 08:14:44 Functions: 33 33 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14