LCOV - code coverage report
Current view: top level - src/backend/optimizer/plan - initsplan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 683 715 95.5 %
Date: 2021-05-13 09:07:15 Functions: 23 23 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-2021, 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_class.h"
      18             : #include "catalog/pg_type.h"
      19             : #include "nodes/makefuncs.h"
      20             : #include "nodes/nodeFuncs.h"
      21             : #include "optimizer/clauses.h"
      22             : #include "optimizer/cost.h"
      23             : #include "optimizer/inherit.h"
      24             : #include "optimizer/joininfo.h"
      25             : #include "optimizer/optimizer.h"
      26             : #include "optimizer/pathnode.h"
      27             : #include "optimizer/paths.h"
      28             : #include "optimizer/placeholder.h"
      29             : #include "optimizer/planmain.h"
      30             : #include "optimizer/planner.h"
      31             : #include "optimizer/prep.h"
      32             : #include "optimizer/restrictinfo.h"
      33             : #include "parser/analyze.h"
      34             : #include "rewrite/rewriteManip.h"
      35             : #include "utils/lsyscache.h"
      36             : #include "utils/typcache.h"
      37             : 
      38             : /* These parameters are set by GUC */
      39             : int         from_collapse_limit;
      40             : int         join_collapse_limit;
      41             : 
      42             : 
      43             : /* Elements of the postponed_qual_list used during deconstruct_recurse */
      44             : typedef struct PostponedQual
      45             : {
      46             :     Node       *qual;           /* a qual clause waiting to be processed */
      47             :     Relids      relids;         /* the set of baserels it references */
      48             : } PostponedQual;
      49             : 
      50             : 
      51             : static void extract_lateral_references(PlannerInfo *root, RelOptInfo *brel,
      52             :                                        Index rtindex);
      53             : static List *deconstruct_recurse(PlannerInfo *root, Node *jtnode,
      54             :                                  bool below_outer_join,
      55             :                                  Relids *qualscope, Relids *inner_join_rels,
      56             :                                  List **postponed_qual_list);
      57             : static void process_security_barrier_quals(PlannerInfo *root,
      58             :                                            int rti, Relids qualscope,
      59             :                                            bool below_outer_join);
      60             : static SpecialJoinInfo *make_outerjoininfo(PlannerInfo *root,
      61             :                                            Relids left_rels, Relids right_rels,
      62             :                                            Relids inner_join_rels,
      63             :                                            JoinType jointype, List *clause);
      64             : static void compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo,
      65             :                                   List *clause);
      66             : static void distribute_qual_to_rels(PlannerInfo *root, Node *clause,
      67             :                                     bool below_outer_join,
      68             :                                     JoinType jointype,
      69             :                                     Index security_level,
      70             :                                     Relids qualscope,
      71             :                                     Relids ojscope,
      72             :                                     Relids outerjoin_nonnullable,
      73             :                                     List **postponed_qual_list);
      74             : static bool check_outerjoin_delay(PlannerInfo *root, Relids *relids_p,
      75             :                                   Relids *nullable_relids_p, bool is_pushed_down);
      76             : static bool check_equivalence_delay(PlannerInfo *root,
      77             :                                     RestrictInfo *restrictinfo);
      78             : static bool check_redundant_nullability_qual(PlannerInfo *root, Node *clause);
      79             : static void check_mergejoinable(RestrictInfo *restrictinfo);
      80             : static void check_hashjoinable(RestrictInfo *restrictinfo);
      81             : static void check_resultcacheable(RestrictInfo *restrictinfo);
      82             : 
      83             : 
      84             : /*****************************************************************************
      85             :  *
      86             :  *   JOIN TREES
      87             :  *
      88             :  *****************************************************************************/
      89             : 
      90             : /*
      91             :  * add_base_rels_to_query
      92             :  *
      93             :  *    Scan the query's jointree and create baserel RelOptInfos for all
      94             :  *    the base relations (e.g., table, subquery, and function RTEs)
      95             :  *    appearing in the jointree.
      96             :  *
      97             :  * The initial invocation must pass root->parse->jointree as the value of
      98             :  * jtnode.  Internally, the function recurses through the jointree.
      99             :  *
     100             :  * At the end of this process, there should be one baserel RelOptInfo for
     101             :  * every non-join RTE that is used in the query.  Some of the baserels
     102             :  * may be appendrel parents, which will require additional "otherrel"
     103             :  * RelOptInfos for their member rels, but those are added later.
     104             :  */
     105             : void
     106      610422 : add_base_rels_to_query(PlannerInfo *root, Node *jtnode)
     107             : {
     108      610422 :     if (jtnode == NULL)
     109           0 :         return;
     110      610422 :     if (IsA(jtnode, RangeTblRef))
     111             :     {
     112      304744 :         int         varno = ((RangeTblRef *) jtnode)->rtindex;
     113             : 
     114      304744 :         (void) build_simple_rel(root, varno, NULL);
     115             :     }
     116      305678 :     else if (IsA(jtnode, FromExpr))
     117             :     {
     118      242426 :         FromExpr   *f = (FromExpr *) jtnode;
     119             :         ListCell   *l;
     120             : 
     121      499966 :         foreach(l, f->fromlist)
     122      257550 :             add_base_rels_to_query(root, lfirst(l));
     123             :     }
     124       63252 :     else if (IsA(jtnode, JoinExpr))
     125             :     {
     126       63252 :         JoinExpr   *j = (JoinExpr *) jtnode;
     127             : 
     128       63252 :         add_base_rels_to_query(root, j->larg);
     129       63252 :         add_base_rels_to_query(root, j->rarg);
     130             :     }
     131             :     else
     132           0 :         elog(ERROR, "unrecognized node type: %d",
     133             :              (int) nodeTag(jtnode));
     134             : }
     135             : 
     136             : /*
     137             :  * add_other_rels_to_query
     138             :  *    create "otherrel" RelOptInfos for the children of appendrel baserels
     139             :  *
     140             :  * At the end of this process, there should be RelOptInfos for all relations
     141             :  * that will be scanned by the query.
     142             :  */
     143             : void
     144      226358 : add_other_rels_to_query(PlannerInfo *root)
     145             : {
     146             :     int         rti;
     147             : 
     148      714346 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     149             :     {
     150      487990 :         RelOptInfo *rel = root->simple_rel_array[rti];
     151      487990 :         RangeTblEntry *rte = root->simple_rte_array[rti];
     152             : 
     153             :         /* there may be empty slots corresponding to non-baserel RTEs */
     154      487990 :         if (rel == NULL)
     155      154784 :             continue;
     156             : 
     157             :         /* Ignore any "otherrels" that were already added. */
     158      333206 :         if (rel->reloptkind != RELOPT_BASEREL)
     159       42658 :             continue;
     160             : 
     161             :         /* If it's marked as inheritable, look for children. */
     162      290548 :         if (rte->inh)
     163       12014 :             expand_inherited_rtentry(root, rel, rte, rti);
     164             :     }
     165      226356 : }
     166             : 
     167             : 
     168             : /*****************************************************************************
     169             :  *
     170             :  *   TARGET LISTS
     171             :  *
     172             :  *****************************************************************************/
     173             : 
     174             : /*
     175             :  * build_base_rel_tlists
     176             :  *    Add targetlist entries for each var needed in the query's final tlist
     177             :  *    (and HAVING clause, if any) to the appropriate base relations.
     178             :  *
     179             :  * We mark such vars as needed by "relation 0" to ensure that they will
     180             :  * propagate up through all join plan steps.
     181             :  */
     182             : void
     183      226358 : build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
     184             : {
     185      226358 :     List       *tlist_vars = pull_var_clause((Node *) final_tlist,
     186             :                                              PVC_RECURSE_AGGREGATES |
     187             :                                              PVC_RECURSE_WINDOWFUNCS |
     188             :                                              PVC_INCLUDE_PLACEHOLDERS);
     189             : 
     190      226358 :     if (tlist_vars != NIL)
     191             :     {
     192      216752 :         add_vars_to_targetlist(root, tlist_vars, bms_make_singleton(0), true);
     193      216752 :         list_free(tlist_vars);
     194             :     }
     195             : 
     196             :     /*
     197             :      * If there's a HAVING clause, we'll need the Vars it uses, too.  Note
     198             :      * that HAVING can contain Aggrefs but not WindowFuncs.
     199             :      */
     200      226358 :     if (root->parse->havingQual)
     201             :     {
     202         364 :         List       *having_vars = pull_var_clause(root->parse->havingQual,
     203             :                                                   PVC_RECURSE_AGGREGATES |
     204             :                                                   PVC_INCLUDE_PLACEHOLDERS);
     205             : 
     206         364 :         if (having_vars != NIL)
     207             :         {
     208         304 :             add_vars_to_targetlist(root, having_vars,
     209             :                                    bms_make_singleton(0), true);
     210         304 :             list_free(having_vars);
     211             :         }
     212             :     }
     213      226358 : }
     214             : 
     215             : /*
     216             :  * add_vars_to_targetlist
     217             :  *    For each variable appearing in the list, add it to the owning
     218             :  *    relation's targetlist if not already present, and mark the variable
     219             :  *    as being needed for the indicated join (or for final output if
     220             :  *    where_needed includes "relation 0").
     221             :  *
     222             :  *    The list may also contain PlaceHolderVars.  These don't necessarily
     223             :  *    have a single owning relation; we keep their attr_needed info in
     224             :  *    root->placeholder_list instead.  If create_new_ph is true, it's OK
     225             :  *    to create new PlaceHolderInfos; otherwise, the PlaceHolderInfos must
     226             :  *    already exist, and we should only update their ph_needed.  (This should
     227             :  *    be true before deconstruct_jointree begins, and false after that.)
     228             :  */
     229             : void
     230      351958 : add_vars_to_targetlist(PlannerInfo *root, List *vars,
     231             :                        Relids where_needed, bool create_new_ph)
     232             : {
     233             :     ListCell   *temp;
     234             : 
     235             :     Assert(!bms_is_empty(where_needed));
     236             : 
     237     1424490 :     foreach(temp, vars)
     238             :     {
     239     1072532 :         Node       *node = (Node *) lfirst(temp);
     240             : 
     241     1072532 :         if (IsA(node, Var))
     242             :         {
     243     1071768 :             Var        *var = (Var *) node;
     244     1071768 :             RelOptInfo *rel = find_base_rel(root, var->varno);
     245     1071768 :             int         attno = var->varattno;
     246             : 
     247     1071768 :             if (bms_is_subset(where_needed, rel->relids))
     248         458 :                 continue;
     249             :             Assert(attno >= rel->min_attr && attno <= rel->max_attr);
     250     1071310 :             attno -= rel->min_attr;
     251     1071310 :             if (rel->attr_needed[attno] == NULL)
     252             :             {
     253             :                 /* Variable not yet requested, so add to rel's targetlist */
     254             :                 /* XXX is copyObject necessary here? */
     255      861054 :                 rel->reltarget->exprs = lappend(rel->reltarget->exprs,
     256             :                                                 copyObject(var));
     257             :                 /* reltarget cost and width will be computed later */
     258             :             }
     259     1071310 :             rel->attr_needed[attno] = bms_add_members(rel->attr_needed[attno],
     260             :                                                       where_needed);
     261             :         }
     262         764 :         else if (IsA(node, PlaceHolderVar))
     263             :         {
     264         764 :             PlaceHolderVar *phv = (PlaceHolderVar *) node;
     265         764 :             PlaceHolderInfo *phinfo = find_placeholder_info(root, phv,
     266             :                                                             create_new_ph);
     267             : 
     268         764 :             phinfo->ph_needed = bms_add_members(phinfo->ph_needed,
     269             :                                                 where_needed);
     270             :         }
     271             :         else
     272           0 :             elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
     273             :     }
     274      351958 : }
     275             : 
     276             : 
     277             : /*****************************************************************************
     278             :  *
     279             :  *    LATERAL REFERENCES
     280             :  *
     281             :  *****************************************************************************/
     282             : 
     283             : /*
     284             :  * find_lateral_references
     285             :  *    For each LATERAL subquery, extract all its references to Vars and
     286             :  *    PlaceHolderVars of the current query level, and make sure those values
     287             :  *    will be available for evaluation of the subquery.
     288             :  *
     289             :  * While later planning steps ensure that the Var/PHV source rels are on the
     290             :  * outside of nestloops relative to the LATERAL subquery, we also need to
     291             :  * ensure that the Vars/PHVs propagate up to the nestloop join level; this
     292             :  * means setting suitable where_needed values for them.
     293             :  *
     294             :  * Note that this only deals with lateral references in unflattened LATERAL
     295             :  * subqueries.  When we flatten a LATERAL subquery, its lateral references
     296             :  * become plain Vars in the parent query, but they may have to be wrapped in
     297             :  * PlaceHolderVars if they need to be forced NULL by outer joins that don't
     298             :  * also null the LATERAL subquery.  That's all handled elsewhere.
     299             :  *
     300             :  * This has to run before deconstruct_jointree, since it might result in
     301             :  * creation of PlaceHolderInfos.
     302             :  */
     303             : void
     304      226358 : find_lateral_references(PlannerInfo *root)
     305             : {
     306             :     Index       rti;
     307             : 
     308             :     /* We need do nothing if the query contains no LATERAL RTEs */
     309      226358 :     if (!root->hasLateralRTEs)
     310      225292 :         return;
     311             : 
     312             :     /*
     313             :      * Examine all baserels (the rel array has been set up by now).
     314             :      */
     315        6152 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     316             :     {
     317        5086 :         RelOptInfo *brel = root->simple_rel_array[rti];
     318             : 
     319             :         /* there may be empty slots corresponding to non-baserel RTEs */
     320        5086 :         if (brel == NULL)
     321        2346 :             continue;
     322             : 
     323             :         Assert(brel->relid == rti); /* sanity check on array */
     324             : 
     325             :         /*
     326             :          * This bit is less obvious than it might look.  We ignore appendrel
     327             :          * otherrels and consider only their parent baserels.  In a case where
     328             :          * a LATERAL-containing UNION ALL subquery was pulled up, it is the
     329             :          * otherrel that is actually going to be in the plan.  However, we
     330             :          * want to mark all its lateral references as needed by the parent,
     331             :          * because it is the parent's relid that will be used for join
     332             :          * planning purposes.  And the parent's RTE will contain all the
     333             :          * lateral references we need to know, since the pulled-up member is
     334             :          * nothing but a copy of parts of the original RTE's subquery.  We
     335             :          * could visit the parent's children instead and transform their
     336             :          * references back to the parent's relid, but it would be much more
     337             :          * complicated for no real gain.  (Important here is that the child
     338             :          * members have not yet received any processing beyond being pulled
     339             :          * up.)  Similarly, in appendrels created by inheritance expansion,
     340             :          * it's sufficient to look at the parent relation.
     341             :          */
     342             : 
     343             :         /* ignore RTEs that are "other rels" */
     344        2740 :         if (brel->reloptkind != RELOPT_BASEREL)
     345           0 :             continue;
     346             : 
     347        2740 :         extract_lateral_references(root, brel, rti);
     348             :     }
     349             : }
     350             : 
     351             : static void
     352        2740 : extract_lateral_references(PlannerInfo *root, RelOptInfo *brel, Index rtindex)
     353             : {
     354        2740 :     RangeTblEntry *rte = root->simple_rte_array[rtindex];
     355             :     List       *vars;
     356             :     List       *newvars;
     357             :     Relids      where_needed;
     358             :     ListCell   *lc;
     359             : 
     360             :     /* No cross-references are possible if it's not LATERAL */
     361        2740 :     if (!rte->lateral)
     362        1838 :         return;
     363             : 
     364             :     /* Fetch the appropriate variables */
     365         902 :     if (rte->rtekind == RTE_RELATION)
     366          12 :         vars = pull_vars_of_level((Node *) rte->tablesample, 0);
     367         890 :     else if (rte->rtekind == RTE_SUBQUERY)
     368         280 :         vars = pull_vars_of_level((Node *) rte->subquery, 1);
     369         610 :     else if (rte->rtekind == RTE_FUNCTION)
     370         486 :         vars = pull_vars_of_level((Node *) rte->functions, 0);
     371         124 :     else if (rte->rtekind == RTE_TABLEFUNC)
     372          96 :         vars = pull_vars_of_level((Node *) rte->tablefunc, 0);
     373          28 :     else if (rte->rtekind == RTE_VALUES)
     374          28 :         vars = pull_vars_of_level((Node *) rte->values_lists, 0);
     375             :     else
     376             :     {
     377             :         Assert(false);
     378           0 :         return;                 /* keep compiler quiet */
     379             :     }
     380             : 
     381         902 :     if (vars == NIL)
     382          40 :         return;                 /* nothing to do */
     383             : 
     384             :     /* Copy each Var (or PlaceHolderVar) and adjust it to match our level */
     385         862 :     newvars = NIL;
     386        2086 :     foreach(lc, vars)
     387             :     {
     388        1224 :         Node       *node = (Node *) lfirst(lc);
     389             : 
     390        1224 :         node = copyObject(node);
     391        1224 :         if (IsA(node, Var))
     392             :         {
     393        1184 :             Var        *var = (Var *) node;
     394             : 
     395             :             /* Adjustment is easy since it's just one node */
     396        1184 :             var->varlevelsup = 0;
     397             :         }
     398          40 :         else if (IsA(node, PlaceHolderVar))
     399             :         {
     400          40 :             PlaceHolderVar *phv = (PlaceHolderVar *) node;
     401          40 :             int         levelsup = phv->phlevelsup;
     402             : 
     403             :             /* Have to work harder to adjust the contained expression too */
     404          40 :             if (levelsup != 0)
     405          40 :                 IncrementVarSublevelsUp(node, -levelsup, 0);
     406             : 
     407             :             /*
     408             :              * If we pulled the PHV out of a subquery RTE, its expression
     409             :              * needs to be preprocessed.  subquery_planner() already did this
     410             :              * for level-zero PHVs in function and values RTEs, though.
     411             :              */
     412          40 :             if (levelsup > 0)
     413          40 :                 phv->phexpr = preprocess_phv_expression(root, phv->phexpr);
     414             :         }
     415             :         else
     416             :             Assert(false);
     417        1224 :         newvars = lappend(newvars, node);
     418             :     }
     419             : 
     420         862 :     list_free(vars);
     421             : 
     422             :     /*
     423             :      * We mark the Vars as being "needed" at the LATERAL RTE.  This is a bit
     424             :      * of a cheat: a more formal approach would be to mark each one as needed
     425             :      * at the join of the LATERAL RTE with its source RTE.  But it will work,
     426             :      * and it's much less tedious than computing a separate where_needed for
     427             :      * each Var.
     428             :      */
     429         862 :     where_needed = bms_make_singleton(rtindex);
     430             : 
     431             :     /*
     432             :      * Push Vars into their source relations' targetlists, and PHVs into
     433             :      * root->placeholder_list.
     434             :      */
     435         862 :     add_vars_to_targetlist(root, newvars, where_needed, true);
     436             : 
     437             :     /* Remember the lateral references for create_lateral_join_info */
     438         862 :     brel->lateral_vars = newvars;
     439             : }
     440             : 
     441             : /*
     442             :  * create_lateral_join_info
     443             :  *    Fill in the per-base-relation direct_lateral_relids, lateral_relids
     444             :  *    and lateral_referencers sets.
     445             :  *
     446             :  * This has to run after deconstruct_jointree, because we need to know the
     447             :  * final ph_eval_at values for PlaceHolderVars.
     448             :  */
     449             : void
     450      226358 : create_lateral_join_info(PlannerInfo *root)
     451             : {
     452      226358 :     bool        found_laterals = false;
     453             :     Index       rti;
     454             :     ListCell   *lc;
     455             : 
     456             :     /* We need do nothing if the query contains no LATERAL RTEs */
     457      226358 :     if (!root->hasLateralRTEs)
     458      225292 :         return;
     459             : 
     460             :     /*
     461             :      * Examine all baserels (the rel array has been set up by now).
     462             :      */
     463        6152 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     464             :     {
     465        5086 :         RelOptInfo *brel = root->simple_rel_array[rti];
     466             :         Relids      lateral_relids;
     467             : 
     468             :         /* there may be empty slots corresponding to non-baserel RTEs */
     469        5086 :         if (brel == NULL)
     470        2346 :             continue;
     471             : 
     472             :         Assert(brel->relid == rti); /* sanity check on array */
     473             : 
     474             :         /* ignore RTEs that are "other rels" */
     475        2740 :         if (brel->reloptkind != RELOPT_BASEREL)
     476          66 :             continue;
     477             : 
     478        2674 :         lateral_relids = NULL;
     479             : 
     480             :         /* consider each laterally-referenced Var or PHV */
     481        3890 :         foreach(lc, brel->lateral_vars)
     482             :         {
     483        1216 :             Node       *node = (Node *) lfirst(lc);
     484             : 
     485        1216 :             if (IsA(node, Var))
     486             :             {
     487        1176 :                 Var        *var = (Var *) node;
     488             : 
     489        1176 :                 found_laterals = true;
     490        1176 :                 lateral_relids = bms_add_member(lateral_relids,
     491        1176 :                                                 var->varno);
     492             :             }
     493          40 :             else if (IsA(node, PlaceHolderVar))
     494             :             {
     495          40 :                 PlaceHolderVar *phv = (PlaceHolderVar *) node;
     496          40 :                 PlaceHolderInfo *phinfo = find_placeholder_info(root, phv,
     497             :                                                                 false);
     498             : 
     499          40 :                 found_laterals = true;
     500          40 :                 lateral_relids = bms_add_members(lateral_relids,
     501          40 :                                                  phinfo->ph_eval_at);
     502             :             }
     503             :             else
     504             :                 Assert(false);
     505             :         }
     506             : 
     507             :         /* We now have all the simple lateral refs from this rel */
     508        2674 :         brel->direct_lateral_relids = lateral_relids;
     509        2674 :         brel->lateral_relids = bms_copy(lateral_relids);
     510             :     }
     511             : 
     512             :     /*
     513             :      * Now check for lateral references within PlaceHolderVars, and mark their
     514             :      * eval_at rels as having lateral references to the source rels.
     515             :      *
     516             :      * For a PHV that is due to be evaluated at a baserel, mark its source(s)
     517             :      * as direct lateral dependencies of the baserel (adding onto the ones
     518             :      * recorded above).  If it's due to be evaluated at a join, mark its
     519             :      * source(s) as indirect lateral dependencies of each baserel in the join,
     520             :      * ie put them into lateral_relids but not direct_lateral_relids.  This is
     521             :      * appropriate because we can't put any such baserel on the outside of a
     522             :      * join to one of the PHV's lateral dependencies, but on the other hand we
     523             :      * also can't yet join it directly to the dependency.
     524             :      */
     525        1214 :     foreach(lc, root->placeholder_list)
     526             :     {
     527         148 :         PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
     528         148 :         Relids      eval_at = phinfo->ph_eval_at;
     529             :         int         varno;
     530             : 
     531         148 :         if (phinfo->ph_lateral == NULL)
     532          64 :             continue;           /* PHV is uninteresting if no lateral refs */
     533             : 
     534          84 :         found_laterals = true;
     535             : 
     536          84 :         if (bms_get_singleton_member(eval_at, &varno))
     537             :         {
     538             :             /* Evaluation site is a baserel */
     539          40 :             RelOptInfo *brel = find_base_rel(root, varno);
     540             : 
     541          40 :             brel->direct_lateral_relids =
     542          40 :                 bms_add_members(brel->direct_lateral_relids,
     543          40 :                                 phinfo->ph_lateral);
     544          40 :             brel->lateral_relids =
     545          40 :                 bms_add_members(brel->lateral_relids,
     546          40 :                                 phinfo->ph_lateral);
     547             :         }
     548             :         else
     549             :         {
     550             :             /* Evaluation site is a join */
     551          44 :             varno = -1;
     552         132 :             while ((varno = bms_next_member(eval_at, varno)) >= 0)
     553             :             {
     554          88 :                 RelOptInfo *brel = find_base_rel(root, varno);
     555             : 
     556          88 :                 brel->lateral_relids = bms_add_members(brel->lateral_relids,
     557          88 :                                                        phinfo->ph_lateral);
     558             :             }
     559             :         }
     560             :     }
     561             : 
     562             :     /*
     563             :      * If we found no actual lateral references, we're done; but reset the
     564             :      * hasLateralRTEs flag to avoid useless work later.
     565             :      */
     566        1066 :     if (!found_laterals)
     567             :     {
     568         188 :         root->hasLateralRTEs = false;
     569         188 :         return;
     570             :     }
     571             : 
     572             :     /*
     573             :      * Calculate the transitive closure of the lateral_relids sets, so that
     574             :      * they describe both direct and indirect lateral references.  If relation
     575             :      * X references Y laterally, and Y references Z laterally, then we will
     576             :      * have to scan X on the inside of a nestloop with Z, so for all intents
     577             :      * and purposes X is laterally dependent on Z too.
     578             :      *
     579             :      * This code is essentially Warshall's algorithm for transitive closure.
     580             :      * The outer loop considers each baserel, and propagates its lateral
     581             :      * dependencies to those baserels that have a lateral dependency on it.
     582             :      */
     583        5044 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     584             :     {
     585        4166 :         RelOptInfo *brel = root->simple_rel_array[rti];
     586             :         Relids      outer_lateral_relids;
     587             :         Index       rti2;
     588             : 
     589        4166 :         if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
     590        1892 :             continue;
     591             : 
     592             :         /* need not consider baserel further if it has no lateral refs */
     593        2274 :         outer_lateral_relids = brel->lateral_relids;
     594        2274 :         if (outer_lateral_relids == NULL)
     595        1292 :             continue;
     596             : 
     597             :         /* else scan all baserels */
     598        5780 :         for (rti2 = 1; rti2 < root->simple_rel_array_size; rti2++)
     599             :         {
     600        4798 :             RelOptInfo *brel2 = root->simple_rel_array[rti2];
     601             : 
     602        4798 :             if (brel2 == NULL || brel2->reloptkind != RELOPT_BASEREL)
     603        2148 :                 continue;
     604             : 
     605             :             /* if brel2 has lateral ref to brel, propagate brel's refs */
     606        2650 :             if (bms_is_member(rti, brel2->lateral_relids))
     607          48 :                 brel2->lateral_relids = bms_add_members(brel2->lateral_relids,
     608             :                                                         outer_lateral_relids);
     609             :         }
     610             :     }
     611             : 
     612             :     /*
     613             :      * Now that we've identified all lateral references, mark each baserel
     614             :      * with the set of relids of rels that reference it laterally (possibly
     615             :      * indirectly) --- that is, the inverse mapping of lateral_relids.
     616             :      */
     617        5044 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     618             :     {
     619        4166 :         RelOptInfo *brel = root->simple_rel_array[rti];
     620             :         Relids      lateral_relids;
     621             :         int         rti2;
     622             : 
     623        4166 :         if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
     624        1892 :             continue;
     625             : 
     626             :         /* Nothing to do at rels with no lateral refs */
     627        2274 :         lateral_relids = brel->lateral_relids;
     628        2274 :         if (lateral_relids == NULL)
     629        1292 :             continue;
     630             : 
     631             :         /*
     632             :          * We should not have broken the invariant that lateral_relids is
     633             :          * exactly NULL if empty.
     634             :          */
     635             :         Assert(!bms_is_empty(lateral_relids));
     636             : 
     637             :         /* Also, no rel should have a lateral dependency on itself */
     638             :         Assert(!bms_is_member(rti, lateral_relids));
     639             : 
     640             :         /* Mark this rel's referencees */
     641         982 :         rti2 = -1;
     642        2068 :         while ((rti2 = bms_next_member(lateral_relids, rti2)) >= 0)
     643             :         {
     644        1086 :             RelOptInfo *brel2 = root->simple_rel_array[rti2];
     645             : 
     646             :             Assert(brel2 != NULL && brel2->reloptkind == RELOPT_BASEREL);
     647        1086 :             brel2->lateral_referencers =
     648        1086 :                 bms_add_member(brel2->lateral_referencers, rti);
     649             :         }
     650             :     }
     651             : }
     652             : 
     653             : 
     654             : /*****************************************************************************
     655             :  *
     656             :  *    JOIN TREE PROCESSING
     657             :  *
     658             :  *****************************************************************************/
     659             : 
     660             : /*
     661             :  * deconstruct_jointree
     662             :  *    Recursively scan the query's join tree for WHERE and JOIN/ON qual
     663             :  *    clauses, and add these to the appropriate restrictinfo and joininfo
     664             :  *    lists belonging to base RelOptInfos.  Also, add SpecialJoinInfo nodes
     665             :  *    to root->join_info_list for any outer joins appearing in the query tree.
     666             :  *    Return a "joinlist" data structure showing the join order decisions
     667             :  *    that need to be made by make_one_rel().
     668             :  *
     669             :  * The "joinlist" result is a list of items that are either RangeTblRef
     670             :  * jointree nodes or sub-joinlists.  All the items at the same level of
     671             :  * joinlist must be joined in an order to be determined by make_one_rel()
     672             :  * (note that legal orders may be constrained by SpecialJoinInfo nodes).
     673             :  * A sub-joinlist represents a subproblem to be planned separately. Currently
     674             :  * sub-joinlists arise only from FULL OUTER JOIN or when collapsing of
     675             :  * subproblems is stopped by join_collapse_limit or from_collapse_limit.
     676             :  *
     677             :  * NOTE: when dealing with inner joins, it is appropriate to let a qual clause
     678             :  * be evaluated at the lowest level where all the variables it mentions are
     679             :  * available.  However, we cannot push a qual down into the nullable side(s)
     680             :  * of an outer join since the qual might eliminate matching rows and cause a
     681             :  * NULL row to be incorrectly emitted by the join.  Therefore, we artificially
     682             :  * OR the minimum-relids of such an outer join into the required_relids of
     683             :  * clauses appearing above it.  This forces those clauses to be delayed until
     684             :  * application of the outer join (or maybe even higher in the join tree).
     685             :  */
     686             : List *
     687      226358 : deconstruct_jointree(PlannerInfo *root)
     688             : {
     689             :     List       *result;
     690             :     Relids      qualscope;
     691             :     Relids      inner_join_rels;
     692      226358 :     List       *postponed_qual_list = NIL;
     693             : 
     694             :     /* Start recursion at top of jointree */
     695             :     Assert(root->parse->jointree != NULL &&
     696             :            IsA(root->parse->jointree, FromExpr));
     697             : 
     698             :     /* this is filled as we scan the jointree */
     699      226358 :     root->nullable_baserels = NULL;
     700             : 
     701      226358 :     result = deconstruct_recurse(root, (Node *) root->parse->jointree, false,
     702             :                                  &qualscope, &inner_join_rels,
     703             :                                  &postponed_qual_list);
     704             : 
     705             :     /* Shouldn't be any leftover quals */
     706             :     Assert(postponed_qual_list == NIL);
     707             : 
     708      226358 :     return result;
     709             : }
     710             : 
     711             : /*
     712             :  * deconstruct_recurse
     713             :  *    One recursion level of deconstruct_jointree processing.
     714             :  *
     715             :  * Inputs:
     716             :  *  jtnode is the jointree node to examine
     717             :  *  below_outer_join is true if this node is within the nullable side of a
     718             :  *      higher-level outer join
     719             :  * Outputs:
     720             :  *  *qualscope gets the set of base Relids syntactically included in this
     721             :  *      jointree node (do not modify or free this, as it may also be pointed
     722             :  *      to by RestrictInfo and SpecialJoinInfo nodes)
     723             :  *  *inner_join_rels gets the set of base Relids syntactically included in
     724             :  *      inner joins appearing at or below this jointree node (do not modify
     725             :  *      or free this, either)
     726             :  *  *postponed_qual_list is a list of PostponedQual structs, which we can
     727             :  *      add quals to if they turn out to belong to a higher join level
     728             :  *  Return value is the appropriate joinlist for this jointree node
     729             :  *
     730             :  * In addition, entries will be added to root->join_info_list for outer joins.
     731             :  */
     732             : static List *
     733      610402 : deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join,
     734             :                     Relids *qualscope, Relids *inner_join_rels,
     735             :                     List **postponed_qual_list)
     736             : {
     737             :     List       *joinlist;
     738             : 
     739      610402 :     if (jtnode == NULL)
     740             :     {
     741           0 :         *qualscope = NULL;
     742           0 :         *inner_join_rels = NULL;
     743           0 :         return NIL;
     744             :     }
     745      610402 :     if (IsA(jtnode, RangeTblRef))
     746             :     {
     747      304734 :         int         varno = ((RangeTblRef *) jtnode)->rtindex;
     748             : 
     749             :         /* qualscope is just the one RTE */
     750      304734 :         *qualscope = bms_make_singleton(varno);
     751             :         /* Deal with any securityQuals attached to the RTE */
     752      304734 :         if (root->qual_security_level > 0)
     753        1244 :             process_security_barrier_quals(root,
     754             :                                            varno,
     755             :                                            *qualscope,
     756             :                                            below_outer_join);
     757             :         /* A single baserel does not create an inner join */
     758      304734 :         *inner_join_rels = NULL;
     759      304734 :         joinlist = list_make1(jtnode);
     760             :     }
     761      305668 :     else if (IsA(jtnode, FromExpr))
     762             :     {
     763      242416 :         FromExpr   *f = (FromExpr *) jtnode;
     764      242416 :         List       *child_postponed_quals = NIL;
     765             :         int         remaining;
     766             :         ListCell   *l;
     767             : 
     768             :         /*
     769             :          * First, recurse to handle child joins.  We collapse subproblems into
     770             :          * a single joinlist whenever the resulting joinlist wouldn't exceed
     771             :          * from_collapse_limit members.  Also, always collapse one-element
     772             :          * subproblems, since that won't lengthen the joinlist anyway.
     773             :          */
     774      242416 :         *qualscope = NULL;
     775      242416 :         *inner_join_rels = NULL;
     776      242416 :         joinlist = NIL;
     777      242416 :         remaining = list_length(f->fromlist);
     778      499956 :         foreach(l, f->fromlist)
     779             :         {
     780             :             Relids      sub_qualscope;
     781             :             List       *sub_joinlist;
     782             :             int         sub_members;
     783             : 
     784      257540 :             sub_joinlist = deconstruct_recurse(root, lfirst(l),
     785             :                                                below_outer_join,
     786             :                                                &sub_qualscope,
     787             :                                                inner_join_rels,
     788             :                                                &child_postponed_quals);
     789      257540 :             *qualscope = bms_add_members(*qualscope, sub_qualscope);
     790      257540 :             sub_members = list_length(sub_joinlist);
     791      257540 :             remaining--;
     792      257540 :             if (sub_members <= 1 ||
     793       49560 :                 list_length(joinlist) + sub_members + remaining <= from_collapse_limit)
     794      257540 :                 joinlist = list_concat(joinlist, sub_joinlist);
     795             :             else
     796           0 :                 joinlist = lappend(joinlist, sub_joinlist);
     797             :         }
     798             : 
     799             :         /*
     800             :          * A FROM with more than one list element is an inner join subsuming
     801             :          * all below it, so we should report inner_join_rels = qualscope. If
     802             :          * there was exactly one element, we should (and already did) report
     803             :          * whatever its inner_join_rels were.  If there were no elements (is
     804             :          * that still possible?) the initialization before the loop fixed it.
     805             :          */
     806      242416 :         if (list_length(f->fromlist) > 1)
     807       13244 :             *inner_join_rels = *qualscope;
     808             : 
     809             :         /*
     810             :          * Try to process any quals postponed by children.  If they need
     811             :          * further postponement, add them to my output postponed_qual_list.
     812             :          */
     813      242468 :         foreach(l, child_postponed_quals)
     814             :         {
     815          52 :             PostponedQual *pq = (PostponedQual *) lfirst(l);
     816             : 
     817          52 :             if (bms_is_subset(pq->relids, *qualscope))
     818          52 :                 distribute_qual_to_rels(root, pq->qual,
     819             :                                         below_outer_join, JOIN_INNER,
     820             :                                         root->qual_security_level,
     821             :                                         *qualscope, NULL, NULL,
     822             :                                         NULL);
     823             :             else
     824           0 :                 *postponed_qual_list = lappend(*postponed_qual_list, pq);
     825             :         }
     826             : 
     827             :         /*
     828             :          * Now process the top-level quals.
     829             :          */
     830      454522 :         foreach(l, (List *) f->quals)
     831             :         {
     832      212106 :             Node       *qual = (Node *) lfirst(l);
     833             : 
     834      212106 :             distribute_qual_to_rels(root, qual,
     835             :                                     below_outer_join, JOIN_INNER,
     836             :                                     root->qual_security_level,
     837             :                                     *qualscope, NULL, NULL,
     838             :                                     postponed_qual_list);
     839             :         }
     840             :     }
     841       63252 :     else if (IsA(jtnode, JoinExpr))
     842             :     {
     843       63252 :         JoinExpr   *j = (JoinExpr *) jtnode;
     844       63252 :         List       *child_postponed_quals = NIL;
     845             :         Relids      leftids,
     846             :                     rightids,
     847             :                     left_inners,
     848             :                     right_inners,
     849             :                     nonnullable_rels,
     850             :                     nullable_rels,
     851             :                     ojscope;
     852             :         List       *leftjoinlist,
     853             :                    *rightjoinlist;
     854             :         List       *my_quals;
     855             :         SpecialJoinInfo *sjinfo;
     856             :         ListCell   *l;
     857             : 
     858             :         /*
     859             :          * Order of operations here is subtle and critical.  First we recurse
     860             :          * to handle sub-JOINs.  Their join quals will be placed without
     861             :          * regard for whether this level is an outer join, which is correct.
     862             :          * Then we place our own join quals, which are restricted by lower
     863             :          * outer joins in any case, and are forced to this level if this is an
     864             :          * outer join and they mention the outer side.  Finally, if this is an
     865             :          * outer join, we create a join_info_list entry for the join.  This
     866             :          * will prevent quals above us in the join tree that use those rels
     867             :          * from being pushed down below this level.  (It's okay for upper
     868             :          * quals to be pushed down to the outer side, however.)
     869             :          */
     870       63252 :         switch (j->jointype)
     871             :         {
     872       15148 :             case JOIN_INNER:
     873       15148 :                 leftjoinlist = deconstruct_recurse(root, j->larg,
     874             :                                                    below_outer_join,
     875             :                                                    &leftids, &left_inners,
     876             :                                                    &child_postponed_quals);
     877       15148 :                 rightjoinlist = deconstruct_recurse(root, j->rarg,
     878             :                                                     below_outer_join,
     879             :                                                     &rightids, &right_inners,
     880             :                                                     &child_postponed_quals);
     881       15148 :                 *qualscope = bms_union(leftids, rightids);
     882       15148 :                 *inner_join_rels = *qualscope;
     883             :                 /* Inner join adds no restrictions for quals */
     884       15148 :                 nonnullable_rels = NULL;
     885             :                 /* and it doesn't force anything to null, either */
     886       15148 :                 nullable_rels = NULL;
     887       15148 :                 break;
     888       46728 :             case JOIN_LEFT:
     889             :             case JOIN_ANTI:
     890       46728 :                 leftjoinlist = deconstruct_recurse(root, j->larg,
     891             :                                                    below_outer_join,
     892             :                                                    &leftids, &left_inners,
     893             :                                                    &child_postponed_quals);
     894       46728 :                 rightjoinlist = deconstruct_recurse(root, j->rarg,
     895             :                                                     true,
     896             :                                                     &rightids, &right_inners,
     897             :                                                     &child_postponed_quals);
     898       46728 :                 *qualscope = bms_union(leftids, rightids);
     899       46728 :                 *inner_join_rels = bms_union(left_inners, right_inners);
     900       46728 :                 nonnullable_rels = leftids;
     901       46728 :                 nullable_rels = rightids;
     902       46728 :                 break;
     903         786 :             case JOIN_SEMI:
     904         786 :                 leftjoinlist = deconstruct_recurse(root, j->larg,
     905             :                                                    below_outer_join,
     906             :                                                    &leftids, &left_inners,
     907             :                                                    &child_postponed_quals);
     908         786 :                 rightjoinlist = deconstruct_recurse(root, j->rarg,
     909             :                                                     below_outer_join,
     910             :                                                     &rightids, &right_inners,
     911             :                                                     &child_postponed_quals);
     912         786 :                 *qualscope = bms_union(leftids, rightids);
     913         786 :                 *inner_join_rels = bms_union(left_inners, right_inners);
     914             :                 /* Semi join adds no restrictions for quals */
     915         786 :                 nonnullable_rels = NULL;
     916             : 
     917             :                 /*
     918             :                  * Theoretically, a semijoin would null the RHS; but since the
     919             :                  * RHS can't be accessed above the join, this is immaterial
     920             :                  * and we needn't account for it.
     921             :                  */
     922         786 :                 nullable_rels = NULL;
     923         786 :                 break;
     924         590 :             case JOIN_FULL:
     925         590 :                 leftjoinlist = deconstruct_recurse(root, j->larg,
     926             :                                                    true,
     927             :                                                    &leftids, &left_inners,
     928             :                                                    &child_postponed_quals);
     929         590 :                 rightjoinlist = deconstruct_recurse(root, j->rarg,
     930             :                                                     true,
     931             :                                                     &rightids, &right_inners,
     932             :                                                     &child_postponed_quals);
     933         590 :                 *qualscope = bms_union(leftids, rightids);
     934         590 :                 *inner_join_rels = bms_union(left_inners, right_inners);
     935             :                 /* each side is both outer and inner */
     936         590 :                 nonnullable_rels = *qualscope;
     937         590 :                 nullable_rels = *qualscope;
     938         590 :                 break;
     939           0 :             default:
     940             :                 /* JOIN_RIGHT was eliminated during reduce_outer_joins() */
     941           0 :                 elog(ERROR, "unrecognized join type: %d",
     942             :                      (int) j->jointype);
     943             :                 nonnullable_rels = NULL;    /* keep compiler quiet */
     944             :                 nullable_rels = NULL;
     945             :                 leftjoinlist = rightjoinlist = NIL;
     946             :                 break;
     947             :         }
     948             : 
     949             :         /* Report all rels that will be nulled anywhere in the jointree */
     950       63252 :         root->nullable_baserels = bms_add_members(root->nullable_baserels,
     951             :                                                   nullable_rels);
     952             : 
     953             :         /*
     954             :          * Try to process any quals postponed by children.  If they need
     955             :          * further postponement, add them to my output postponed_qual_list.
     956             :          * Quals that can be processed now must be included in my_quals, so
     957             :          * that they'll be handled properly in make_outerjoininfo.
     958             :          */
     959       63252 :         my_quals = NIL;
     960       63284 :         foreach(l, child_postponed_quals)
     961             :         {
     962          32 :             PostponedQual *pq = (PostponedQual *) lfirst(l);
     963             : 
     964          32 :             if (bms_is_subset(pq->relids, *qualscope))
     965          32 :                 my_quals = lappend(my_quals, pq->qual);
     966             :             else
     967             :             {
     968             :                 /*
     969             :                  * We should not be postponing any quals past an outer join.
     970             :                  * If this Assert fires, pull_up_subqueries() messed up.
     971             :                  */
     972             :                 Assert(j->jointype == JOIN_INNER);
     973           0 :                 *postponed_qual_list = lappend(*postponed_qual_list, pq);
     974             :             }
     975             :         }
     976       63252 :         my_quals = list_concat(my_quals, (List *) j->quals);
     977             : 
     978             :         /*
     979             :          * For an OJ, form the SpecialJoinInfo now, because we need the OJ's
     980             :          * semantic scope (ojscope) to pass to distribute_qual_to_rels.  But
     981             :          * we mustn't add it to join_info_list just yet, because we don't want
     982             :          * distribute_qual_to_rels to think it is an outer join below us.
     983             :          *
     984             :          * Semijoins are a bit of a hybrid: we build a SpecialJoinInfo, but we
     985             :          * want ojscope = NULL for distribute_qual_to_rels.
     986             :          */
     987       63252 :         if (j->jointype != JOIN_INNER)
     988             :         {
     989       48104 :             sjinfo = make_outerjoininfo(root,
     990             :                                         leftids, rightids,
     991             :                                         *inner_join_rels,
     992             :                                         j->jointype,
     993             :                                         my_quals);
     994       48104 :             if (j->jointype == JOIN_SEMI)
     995         786 :                 ojscope = NULL;
     996             :             else
     997       47318 :                 ojscope = bms_union(sjinfo->min_lefthand,
     998       47318 :                                     sjinfo->min_righthand);
     999             :         }
    1000             :         else
    1001             :         {
    1002       15148 :             sjinfo = NULL;
    1003       15148 :             ojscope = NULL;
    1004             :         }
    1005             : 
    1006             :         /* Process the JOIN's qual clauses */
    1007      155456 :         foreach(l, my_quals)
    1008             :         {
    1009       92204 :             Node       *qual = (Node *) lfirst(l);
    1010             : 
    1011       92204 :             distribute_qual_to_rels(root, qual,
    1012             :                                     below_outer_join, j->jointype,
    1013             :                                     root->qual_security_level,
    1014             :                                     *qualscope,
    1015             :                                     ojscope, nonnullable_rels,
    1016             :                                     postponed_qual_list);
    1017             :         }
    1018             : 
    1019             :         /* Now we can add the SpecialJoinInfo to join_info_list */
    1020       63252 :         if (sjinfo)
    1021             :         {
    1022       48104 :             root->join_info_list = lappend(root->join_info_list, sjinfo);
    1023             :             /* Each time we do that, recheck placeholder eval levels */
    1024       48104 :             update_placeholder_eval_levels(root, sjinfo);
    1025             :         }
    1026             : 
    1027             :         /*
    1028             :          * Finally, compute the output joinlist.  We fold subproblems together
    1029             :          * except at a FULL JOIN or where join_collapse_limit would be
    1030             :          * exceeded.
    1031             :          */
    1032       63252 :         if (j->jointype == JOIN_FULL)
    1033             :         {
    1034             :             /* force the join order exactly at this node */
    1035         590 :             joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
    1036             :         }
    1037       62662 :         else if (list_length(leftjoinlist) + list_length(rightjoinlist) <=
    1038             :                  join_collapse_limit)
    1039             :         {
    1040             :             /* OK to combine subproblems */
    1041       62582 :             joinlist = list_concat(leftjoinlist, rightjoinlist);
    1042             :         }
    1043             :         else
    1044             :         {
    1045             :             /* can't combine, but needn't force join order above here */
    1046             :             Node       *leftpart,
    1047             :                        *rightpart;
    1048             : 
    1049             :             /* avoid creating useless 1-element sublists */
    1050          80 :             if (list_length(leftjoinlist) == 1)
    1051           0 :                 leftpart = (Node *) linitial(leftjoinlist);
    1052             :             else
    1053          80 :                 leftpart = (Node *) leftjoinlist;
    1054          80 :             if (list_length(rightjoinlist) == 1)
    1055           0 :                 rightpart = (Node *) linitial(rightjoinlist);
    1056             :             else
    1057          80 :                 rightpart = (Node *) rightjoinlist;
    1058          80 :             joinlist = list_make2(leftpart, rightpart);
    1059             :         }
    1060             :     }
    1061             :     else
    1062             :     {
    1063           0 :         elog(ERROR, "unrecognized node type: %d",
    1064             :              (int) nodeTag(jtnode));
    1065             :         joinlist = NIL;         /* keep compiler quiet */
    1066             :     }
    1067      610402 :     return joinlist;
    1068             : }
    1069             : 
    1070             : /*
    1071             :  * process_security_barrier_quals
    1072             :  *    Transfer security-barrier quals into relation's baserestrictinfo list.
    1073             :  *
    1074             :  * The rewriter put any relevant security-barrier conditions into the RTE's
    1075             :  * securityQuals field, but it's now time to copy them into the rel's
    1076             :  * baserestrictinfo.
    1077             :  *
    1078             :  * In inheritance cases, we only consider quals attached to the parent rel
    1079             :  * here; they will be valid for all children too, so it's okay to consider
    1080             :  * them for purposes like equivalence class creation.  Quals attached to
    1081             :  * individual child rels will be dealt with during path creation.
    1082             :  */
    1083             : static void
    1084        1244 : process_security_barrier_quals(PlannerInfo *root,
    1085             :                                int rti, Relids qualscope,
    1086             :                                bool below_outer_join)
    1087             : {
    1088        1244 :     RangeTblEntry *rte = root->simple_rte_array[rti];
    1089        1244 :     Index       security_level = 0;
    1090             :     ListCell   *lc;
    1091             : 
    1092             :     /*
    1093             :      * Each element of the securityQuals list has been preprocessed into an
    1094             :      * implicitly-ANDed list of clauses.  All the clauses in a given sublist
    1095             :      * should get the same security level, but successive sublists get higher
    1096             :      * levels.
    1097             :      */
    1098        2544 :     foreach(lc, rte->securityQuals)
    1099             :     {
    1100        1300 :         List       *qualset = (List *) lfirst(lc);
    1101             :         ListCell   *lc2;
    1102             : 
    1103        2564 :         foreach(lc2, qualset)
    1104             :         {
    1105        1264 :             Node       *qual = (Node *) lfirst(lc2);
    1106             : 
    1107             :             /*
    1108             :              * We cheat to the extent of passing ojscope = qualscope rather
    1109             :              * than its more logical value of NULL.  The only effect this has
    1110             :              * is to force a Var-free qual to be evaluated at the rel rather
    1111             :              * than being pushed up to top of tree, which we don't want.
    1112             :              */
    1113        1264 :             distribute_qual_to_rels(root, qual,
    1114             :                                     below_outer_join,
    1115             :                                     JOIN_INNER,
    1116             :                                     security_level,
    1117             :                                     qualscope,
    1118             :                                     qualscope,
    1119             :                                     NULL,
    1120             :                                     NULL);
    1121             :         }
    1122        1300 :         security_level++;
    1123             :     }
    1124             : 
    1125             :     /* Assert that qual_security_level is higher than anything we just used */
    1126             :     Assert(security_level <= root->qual_security_level);
    1127        1244 : }
    1128             : 
    1129             : /*
    1130             :  * make_outerjoininfo
    1131             :  *    Build a SpecialJoinInfo for the current outer join
    1132             :  *
    1133             :  * Inputs:
    1134             :  *  left_rels: the base Relids syntactically on outer side of join
    1135             :  *  right_rels: the base Relids syntactically on inner side of join
    1136             :  *  inner_join_rels: base Relids participating in inner joins below this one
    1137             :  *  jointype: what it says (must always be LEFT, FULL, SEMI, or ANTI)
    1138             :  *  clause: the outer join's join condition (in implicit-AND format)
    1139             :  *
    1140             :  * The node should eventually be appended to root->join_info_list, but we
    1141             :  * do not do that here.
    1142             :  *
    1143             :  * Note: we assume that this function is invoked bottom-up, so that
    1144             :  * root->join_info_list already contains entries for all outer joins that are
    1145             :  * syntactically below this one.
    1146             :  */
    1147             : static SpecialJoinInfo *
    1148       48104 : make_outerjoininfo(PlannerInfo *root,
    1149             :                    Relids left_rels, Relids right_rels,
    1150             :                    Relids inner_join_rels,
    1151             :                    JoinType jointype, List *clause)
    1152             : {
    1153       48104 :     SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo);
    1154             :     Relids      clause_relids;
    1155             :     Relids      strict_relids;
    1156             :     Relids      min_lefthand;
    1157             :     Relids      min_righthand;
    1158             :     ListCell   *l;
    1159             : 
    1160             :     /*
    1161             :      * We should not see RIGHT JOIN here because left/right were switched
    1162             :      * earlier
    1163             :      */
    1164             :     Assert(jointype != JOIN_INNER);
    1165             :     Assert(jointype != JOIN_RIGHT);
    1166             : 
    1167             :     /*
    1168             :      * Presently the executor cannot support FOR [KEY] UPDATE/SHARE marking of
    1169             :      * rels appearing on the nullable side of an outer join. (It's somewhat
    1170             :      * unclear what that would mean, anyway: what should we mark when a result
    1171             :      * row is generated from no element of the nullable relation?)  So,
    1172             :      * complain if any nullable rel is FOR [KEY] UPDATE/SHARE.
    1173             :      *
    1174             :      * You might be wondering why this test isn't made far upstream in the
    1175             :      * parser.  It's because the parser hasn't got enough info --- consider
    1176             :      * FOR UPDATE applied to a view.  Only after rewriting and flattening do
    1177             :      * we know whether the view contains an outer join.
    1178             :      *
    1179             :      * We use the original RowMarkClause list here; the PlanRowMark list would
    1180             :      * list everything.
    1181             :      */
    1182       48136 :     foreach(l, root->parse->rowMarks)
    1183             :     {
    1184          32 :         RowMarkClause *rc = (RowMarkClause *) lfirst(l);
    1185             : 
    1186          32 :         if (bms_is_member(rc->rti, right_rels) ||
    1187           8 :             (jointype == JOIN_FULL && bms_is_member(rc->rti, left_rels)))
    1188           0 :             ereport(ERROR,
    1189             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    1190             :             /*------
    1191             :              translator: %s is a SQL row locking clause such as FOR UPDATE */
    1192             :                      errmsg("%s cannot be applied to the nullable side of an outer join",
    1193             :                             LCS_asString(rc->strength))));
    1194             :     }
    1195             : 
    1196       48104 :     sjinfo->syn_lefthand = left_rels;
    1197       48104 :     sjinfo->syn_righthand = right_rels;
    1198       48104 :     sjinfo->jointype = jointype;
    1199             :     /* this always starts out false */
    1200       48104 :     sjinfo->delay_upper_joins = false;
    1201             : 
    1202       48104 :     compute_semijoin_info(root, sjinfo, clause);
    1203             : 
    1204             :     /* If it's a full join, no need to be very smart */
    1205       48104 :     if (jointype == JOIN_FULL)
    1206             :     {
    1207         590 :         sjinfo->min_lefthand = bms_copy(left_rels);
    1208         590 :         sjinfo->min_righthand = bms_copy(right_rels);
    1209         590 :         sjinfo->lhs_strict = false; /* don't care about this */
    1210         590 :         return sjinfo;
    1211             :     }
    1212             : 
    1213             :     /*
    1214             :      * Retrieve all relids mentioned within the join clause.
    1215             :      */
    1216       47514 :     clause_relids = pull_varnos(root, (Node *) clause);
    1217             : 
    1218             :     /*
    1219             :      * For which relids is the clause strict, ie, it cannot succeed if the
    1220             :      * rel's columns are all NULL?
    1221             :      */
    1222       47514 :     strict_relids = find_nonnullable_rels((Node *) clause);
    1223             : 
    1224             :     /* Remember whether the clause is strict for any LHS relations */
    1225       47514 :     sjinfo->lhs_strict = bms_overlap(strict_relids, left_rels);
    1226             : 
    1227             :     /*
    1228             :      * Required LHS always includes the LHS rels mentioned in the clause. We
    1229             :      * may have to add more rels based on lower outer joins; see below.
    1230             :      */
    1231       47514 :     min_lefthand = bms_intersect(clause_relids, left_rels);
    1232             : 
    1233             :     /*
    1234             :      * Similarly for required RHS.  But here, we must also include any lower
    1235             :      * inner joins, to ensure we don't try to commute with any of them.
    1236             :      */
    1237       47514 :     min_righthand = bms_int_members(bms_union(clause_relids, inner_join_rels),
    1238             :                                     right_rels);
    1239             : 
    1240             :     /*
    1241             :      * Now check previous outer joins for ordering restrictions.
    1242             :      */
    1243       54776 :     foreach(l, root->join_info_list)
    1244             :     {
    1245        7262 :         SpecialJoinInfo *otherinfo = (SpecialJoinInfo *) lfirst(l);
    1246             : 
    1247             :         /*
    1248             :          * A full join is an optimization barrier: we can't associate into or
    1249             :          * out of it.  Hence, if it overlaps either LHS or RHS of the current
    1250             :          * rel, expand that side's min relset to cover the whole full join.
    1251             :          */
    1252        7262 :         if (otherinfo->jointype == JOIN_FULL)
    1253             :         {
    1254          34 :             if (bms_overlap(left_rels, otherinfo->syn_lefthand) ||
    1255          12 :                 bms_overlap(left_rels, otherinfo->syn_righthand))
    1256             :             {
    1257          10 :                 min_lefthand = bms_add_members(min_lefthand,
    1258          10 :                                                otherinfo->syn_lefthand);
    1259          10 :                 min_lefthand = bms_add_members(min_lefthand,
    1260          10 :                                                otherinfo->syn_righthand);
    1261             :             }
    1262          32 :             if (bms_overlap(right_rels, otherinfo->syn_lefthand) ||
    1263          10 :                 bms_overlap(right_rels, otherinfo->syn_righthand))
    1264             :             {
    1265          12 :                 min_righthand = bms_add_members(min_righthand,
    1266          12 :                                                 otherinfo->syn_lefthand);
    1267          12 :                 min_righthand = bms_add_members(min_righthand,
    1268          12 :                                                 otherinfo->syn_righthand);
    1269             :             }
    1270             :             /* Needn't do anything else with the full join */
    1271          22 :             continue;
    1272             :         }
    1273             : 
    1274             :         /*
    1275             :          * For a lower OJ in our LHS, if our join condition uses the lower
    1276             :          * join's RHS and is not strict for that rel, we must preserve the
    1277             :          * ordering of the two OJs, so add lower OJ's full syntactic relset to
    1278             :          * min_lefthand.  (We must use its full syntactic relset, not just its
    1279             :          * min_lefthand + min_righthand.  This is because there might be other
    1280             :          * OJs below this one that this one can commute with, but we cannot
    1281             :          * commute with them if we don't with this one.)  Also, if the current
    1282             :          * join is a semijoin or antijoin, we must preserve ordering
    1283             :          * regardless of strictness.
    1284             :          *
    1285             :          * Note: I believe we have to insist on being strict for at least one
    1286             :          * rel in the lower OJ's min_righthand, not its whole syn_righthand.
    1287             :          */
    1288        7240 :         if (bms_overlap(left_rels, otherinfo->syn_righthand))
    1289             :         {
    1290        6976 :             if (bms_overlap(clause_relids, otherinfo->syn_righthand) &&
    1291         668 :                 (jointype == JOIN_SEMI || jointype == JOIN_ANTI ||
    1292         668 :                  !bms_overlap(strict_relids, otherinfo->min_righthand)))
    1293             :             {
    1294          12 :                 min_lefthand = bms_add_members(min_lefthand,
    1295          12 :                                                otherinfo->syn_lefthand);
    1296          12 :                 min_lefthand = bms_add_members(min_lefthand,
    1297          12 :                                                otherinfo->syn_righthand);
    1298             :             }
    1299             :         }
    1300             : 
    1301             :         /*
    1302             :          * For a lower OJ in our RHS, if our join condition does not use the
    1303             :          * lower join's RHS and the lower OJ's join condition is strict, we
    1304             :          * can interchange the ordering of the two OJs; otherwise we must add
    1305             :          * the lower OJ's full syntactic relset to min_righthand.
    1306             :          *
    1307             :          * Also, if our join condition does not use the lower join's LHS
    1308             :          * either, force the ordering to be preserved.  Otherwise we can end
    1309             :          * up with SpecialJoinInfos with identical min_righthands, which can
    1310             :          * confuse join_is_legal (see discussion in backend/optimizer/README).
    1311             :          *
    1312             :          * Also, we must preserve ordering anyway if either the current join
    1313             :          * or the lower OJ is either a semijoin or an antijoin.
    1314             :          *
    1315             :          * Here, we have to consider that "our join condition" includes any
    1316             :          * clauses that syntactically appeared above the lower OJ and below
    1317             :          * ours; those are equivalent to degenerate clauses in our OJ and must
    1318             :          * be treated as such.  Such clauses obviously can't reference our
    1319             :          * LHS, and they must be non-strict for the lower OJ's RHS (else
    1320             :          * reduce_outer_joins would have reduced the lower OJ to a plain
    1321             :          * join).  Hence the other ways in which we handle clauses within our
    1322             :          * join condition are not affected by them.  The net effect is
    1323             :          * therefore sufficiently represented by the delay_upper_joins flag
    1324             :          * saved for us by check_outerjoin_delay.
    1325             :          */
    1326        7240 :         if (bms_overlap(right_rels, otherinfo->syn_righthand))
    1327             :         {
    1328         244 :             if (bms_overlap(clause_relids, otherinfo->syn_righthand) ||
    1329         228 :                 !bms_overlap(clause_relids, otherinfo->min_lefthand) ||
    1330         100 :                 jointype == JOIN_SEMI ||
    1331          92 :                 jointype == JOIN_ANTI ||
    1332          92 :                 otherinfo->jointype == JOIN_SEMI ||
    1333          84 :                 otherinfo->jointype == JOIN_ANTI ||
    1334          84 :                 !otherinfo->lhs_strict || otherinfo->delay_upper_joins)
    1335             :             {
    1336         160 :                 min_righthand = bms_add_members(min_righthand,
    1337         160 :                                                 otherinfo->syn_lefthand);
    1338         160 :                 min_righthand = bms_add_members(min_righthand,
    1339         160 :                                                 otherinfo->syn_righthand);
    1340             :             }
    1341             :         }
    1342             :     }
    1343             : 
    1344             :     /*
    1345             :      * Examine PlaceHolderVars.  If a PHV is supposed to be evaluated within
    1346             :      * this join's nullable side, then ensure that min_righthand contains the
    1347             :      * full eval_at set of the PHV.  This ensures that the PHV actually can be
    1348             :      * evaluated within the RHS.  Note that this works only because we should
    1349             :      * already have determined the final eval_at level for any PHV
    1350             :      * syntactically within this join.
    1351             :      */
    1352       48026 :     foreach(l, root->placeholder_list)
    1353             :     {
    1354         512 :         PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
    1355         512 :         Relids      ph_syn_level = phinfo->ph_var->phrels;
    1356             : 
    1357             :         /* Ignore placeholder if it didn't syntactically come from RHS */
    1358         512 :         if (!bms_is_subset(ph_syn_level, right_rels))
    1359         140 :             continue;
    1360             : 
    1361             :         /* Else, prevent join from being formed before we eval the PHV */
    1362         372 :         min_righthand = bms_add_members(min_righthand, phinfo->ph_eval_at);
    1363             :     }
    1364             : 
    1365             :     /*
    1366             :      * If we found nothing to put in min_lefthand, punt and make it the full
    1367             :      * LHS, to avoid having an empty min_lefthand which will confuse later
    1368             :      * processing. (We don't try to be smart about such cases, just correct.)
    1369             :      * Likewise for min_righthand.
    1370             :      */
    1371       47514 :     if (bms_is_empty(min_lefthand))
    1372         328 :         min_lefthand = bms_copy(left_rels);
    1373       47514 :     if (bms_is_empty(min_righthand))
    1374          64 :         min_righthand = bms_copy(right_rels);
    1375             : 
    1376             :     /* Now they'd better be nonempty */
    1377             :     Assert(!bms_is_empty(min_lefthand));
    1378             :     Assert(!bms_is_empty(min_righthand));
    1379             :     /* Shouldn't overlap either */
    1380             :     Assert(!bms_overlap(min_lefthand, min_righthand));
    1381             : 
    1382       47514 :     sjinfo->min_lefthand = min_lefthand;
    1383       47514 :     sjinfo->min_righthand = min_righthand;
    1384             : 
    1385       47514 :     return sjinfo;
    1386             : }
    1387             : 
    1388             : /*
    1389             :  * compute_semijoin_info
    1390             :  *    Fill semijoin-related fields of a new SpecialJoinInfo
    1391             :  *
    1392             :  * Note: this relies on only the jointype and syn_righthand fields of the
    1393             :  * SpecialJoinInfo; the rest may not be set yet.
    1394             :  */
    1395             : static void
    1396       48104 : compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo, List *clause)
    1397             : {
    1398             :     List       *semi_operators;
    1399             :     List       *semi_rhs_exprs;
    1400             :     bool        all_btree;
    1401             :     bool        all_hash;
    1402             :     ListCell   *lc;
    1403             : 
    1404             :     /* Initialize semijoin-related fields in case we can't unique-ify */
    1405       48104 :     sjinfo->semi_can_btree = false;
    1406       48104 :     sjinfo->semi_can_hash = false;
    1407       48104 :     sjinfo->semi_operators = NIL;
    1408       48104 :     sjinfo->semi_rhs_exprs = NIL;
    1409             : 
    1410             :     /* Nothing more to do if it's not a semijoin */
    1411       48104 :     if (sjinfo->jointype != JOIN_SEMI)
    1412       47318 :         return;
    1413             : 
    1414             :     /*
    1415             :      * Look to see whether the semijoin's join quals consist of AND'ed
    1416             :      * equality operators, with (only) RHS variables on only one side of each
    1417             :      * one.  If so, we can figure out how to enforce uniqueness for the RHS.
    1418             :      *
    1419             :      * Note that the input clause list is the list of quals that are
    1420             :      * *syntactically* associated with the semijoin, which in practice means
    1421             :      * the synthesized comparison list for an IN or the WHERE of an EXISTS.
    1422             :      * Particularly in the latter case, it might contain clauses that aren't
    1423             :      * *semantically* associated with the join, but refer to just one side or
    1424             :      * the other.  We can ignore such clauses here, as they will just drop
    1425             :      * down to be processed within one side or the other.  (It is okay to
    1426             :      * consider only the syntactically-associated clauses here because for a
    1427             :      * semijoin, no higher-level quals could refer to the RHS, and so there
    1428             :      * can be no other quals that are semantically associated with this join.
    1429             :      * We do things this way because it is useful to have the set of potential
    1430             :      * unique-ification expressions before we can extract the list of quals
    1431             :      * that are actually semantically associated with the particular join.)
    1432             :      *
    1433             :      * Note that the semi_operators list consists of the joinqual operators
    1434             :      * themselves (but commuted if needed to put the RHS value on the right).
    1435             :      * These could be cross-type operators, in which case the operator
    1436             :      * actually needed for uniqueness is a related single-type operator. We
    1437             :      * assume here that that operator will be available from the btree or hash
    1438             :      * opclass when the time comes ... if not, create_unique_plan() will fail.
    1439             :      */
    1440         786 :     semi_operators = NIL;
    1441         786 :     semi_rhs_exprs = NIL;
    1442         786 :     all_btree = true;
    1443         786 :     all_hash = enable_hashagg;  /* don't consider hash if not enabled */
    1444        1666 :     foreach(lc, clause)
    1445             :     {
    1446         922 :         OpExpr     *op = (OpExpr *) lfirst(lc);
    1447             :         Oid         opno;
    1448             :         Node       *left_expr;
    1449             :         Node       *right_expr;
    1450             :         Relids      left_varnos;
    1451             :         Relids      right_varnos;
    1452             :         Relids      all_varnos;
    1453             :         Oid         opinputtype;
    1454             : 
    1455             :         /* Is it a binary opclause? */
    1456        1794 :         if (!IsA(op, OpExpr) ||
    1457         872 :             list_length(op->args) != 2)
    1458             :         {
    1459             :             /* No, but does it reference both sides? */
    1460          50 :             all_varnos = pull_varnos(root, (Node *) op);
    1461          92 :             if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
    1462          42 :                 bms_is_subset(all_varnos, sjinfo->syn_righthand))
    1463             :             {
    1464             :                 /*
    1465             :                  * Clause refers to only one rel, so ignore it --- unless it
    1466             :                  * contains volatile functions, in which case we'd better
    1467             :                  * punt.
    1468             :                  */
    1469          46 :                 if (contain_volatile_functions((Node *) op))
    1470          42 :                     return;
    1471          46 :                 continue;
    1472             :             }
    1473             :             /* Non-operator clause referencing both sides, must punt */
    1474           4 :             return;
    1475             :         }
    1476             : 
    1477             :         /* Extract data from binary opclause */
    1478         872 :         opno = op->opno;
    1479         872 :         left_expr = linitial(op->args);
    1480         872 :         right_expr = lsecond(op->args);
    1481         872 :         left_varnos = pull_varnos(root, left_expr);
    1482         872 :         right_varnos = pull_varnos(root, right_expr);
    1483         872 :         all_varnos = bms_union(left_varnos, right_varnos);
    1484         872 :         opinputtype = exprType(left_expr);
    1485             : 
    1486             :         /* Does it reference both sides? */
    1487        1744 :         if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
    1488         872 :             bms_is_subset(all_varnos, sjinfo->syn_righthand))
    1489             :         {
    1490             :             /*
    1491             :              * Clause refers to only one rel, so ignore it --- unless it
    1492             :              * contains volatile functions, in which case we'd better punt.
    1493             :              */
    1494           4 :             if (contain_volatile_functions((Node *) op))
    1495           0 :                 return;
    1496           4 :             continue;
    1497             :         }
    1498             : 
    1499             :         /* check rel membership of arguments */
    1500        1736 :         if (!bms_is_empty(right_varnos) &&
    1501        1596 :             bms_is_subset(right_varnos, sjinfo->syn_righthand) &&
    1502         728 :             !bms_overlap(left_varnos, sjinfo->syn_righthand))
    1503             :         {
    1504             :             /* typical case, right_expr is RHS variable */
    1505             :         }
    1506         280 :         else if (!bms_is_empty(left_varnos) &&
    1507         140 :                  bms_is_subset(left_varnos, sjinfo->syn_righthand) &&
    1508         140 :                  !bms_overlap(right_varnos, sjinfo->syn_righthand))
    1509             :         {
    1510             :             /* flipped case, left_expr is RHS variable */
    1511         140 :             opno = get_commutator(opno);
    1512         140 :             if (!OidIsValid(opno))
    1513           0 :                 return;
    1514         140 :             right_expr = left_expr;
    1515             :         }
    1516             :         else
    1517             :         {
    1518             :             /* mixed membership of args, punt */
    1519           0 :             return;
    1520             :         }
    1521             : 
    1522             :         /* all operators must be btree equality or hash equality */
    1523         868 :         if (all_btree)
    1524             :         {
    1525             :             /* oprcanmerge is considered a hint... */
    1526        1698 :             if (!op_mergejoinable(opno, opinputtype) ||
    1527         830 :                 get_mergejoin_opfamilies(opno) == NIL)
    1528          38 :                 all_btree = false;
    1529             :         }
    1530         868 :         if (all_hash)
    1531             :         {
    1532             :             /* ... but oprcanhash had better be correct */
    1533         838 :             if (!op_hashjoinable(opno, opinputtype))
    1534          38 :                 all_hash = false;
    1535             :         }
    1536         868 :         if (!(all_btree || all_hash))
    1537          38 :             return;
    1538             : 
    1539             :         /* so far so good, keep building lists */
    1540         830 :         semi_operators = lappend_oid(semi_operators, opno);
    1541         830 :         semi_rhs_exprs = lappend(semi_rhs_exprs, copyObject(right_expr));
    1542             :     }
    1543             : 
    1544             :     /* Punt if we didn't find at least one column to unique-ify */
    1545         744 :     if (semi_rhs_exprs == NIL)
    1546           8 :         return;
    1547             : 
    1548             :     /*
    1549             :      * The expressions we'd need to unique-ify mustn't be volatile.
    1550             :      */
    1551         736 :     if (contain_volatile_functions((Node *) semi_rhs_exprs))
    1552           0 :         return;
    1553             : 
    1554             :     /*
    1555             :      * If we get here, we can unique-ify the semijoin's RHS using at least one
    1556             :      * of sorting and hashing.  Save the information about how to do that.
    1557             :      */
    1558         736 :     sjinfo->semi_can_btree = all_btree;
    1559         736 :     sjinfo->semi_can_hash = all_hash;
    1560         736 :     sjinfo->semi_operators = semi_operators;
    1561         736 :     sjinfo->semi_rhs_exprs = semi_rhs_exprs;
    1562             : }
    1563             : 
    1564             : 
    1565             : /*****************************************************************************
    1566             :  *
    1567             :  *    QUALIFICATIONS
    1568             :  *
    1569             :  *****************************************************************************/
    1570             : 
    1571             : /*
    1572             :  * distribute_qual_to_rels
    1573             :  *    Add clause information to either the baserestrictinfo or joininfo list
    1574             :  *    (depending on whether the clause is a join) of each base relation
    1575             :  *    mentioned in the clause.  A RestrictInfo node is created and added to
    1576             :  *    the appropriate list for each rel.  Alternatively, if the clause uses a
    1577             :  *    mergejoinable operator and is not delayed by outer-join rules, enter
    1578             :  *    the left- and right-side expressions into the query's list of
    1579             :  *    EquivalenceClasses.  Alternatively, if the clause needs to be treated
    1580             :  *    as belonging to a higher join level, just add it to postponed_qual_list.
    1581             :  *
    1582             :  * 'clause': the qual clause to be distributed
    1583             :  * 'below_outer_join': true if the qual is from a JOIN/ON that is below the
    1584             :  *      nullable side of a higher-level outer join
    1585             :  * 'jointype': type of join the qual is from (JOIN_INNER for a WHERE clause)
    1586             :  * 'security_level': security_level to assign to the qual
    1587             :  * 'qualscope': set of baserels the qual's syntactic scope covers
    1588             :  * 'ojscope': NULL if not an outer-join qual, else the minimum set of baserels
    1589             :  *      needed to form this join
    1590             :  * 'outerjoin_nonnullable': NULL if not an outer-join qual, else the set of
    1591             :  *      baserels appearing on the outer (nonnullable) side of the join
    1592             :  *      (for FULL JOIN this includes both sides of the join, and must in fact
    1593             :  *      equal qualscope)
    1594             :  * 'postponed_qual_list': list of PostponedQual structs, which we can add
    1595             :  *      this qual to if it turns out to belong to a higher join level.
    1596             :  *      Can be NULL if caller knows postponement is impossible.
    1597             :  *
    1598             :  * 'qualscope' identifies what level of JOIN the qual came from syntactically.
    1599             :  * 'ojscope' is needed if we decide to force the qual up to the outer-join
    1600             :  * level, which will be ojscope not necessarily qualscope.
    1601             :  *
    1602             :  * At the time this is called, root->join_info_list must contain entries for
    1603             :  * all and only those special joins that are syntactically below this qual.
    1604             :  */
    1605             : static void
    1606      305626 : distribute_qual_to_rels(PlannerInfo *root, Node *clause,
    1607             :                         bool below_outer_join,
    1608             :                         JoinType jointype,
    1609             :                         Index security_level,
    1610             :                         Relids qualscope,
    1611             :                         Relids ojscope,
    1612             :                         Relids outerjoin_nonnullable,
    1613             :                         List **postponed_qual_list)
    1614             : {
    1615             :     Relids      relids;
    1616             :     bool        is_pushed_down;
    1617             :     bool        outerjoin_delayed;
    1618      305626 :     bool        pseudoconstant = false;
    1619             :     bool        maybe_equivalence;
    1620             :     bool        maybe_outer_join;
    1621             :     Relids      nullable_relids;
    1622             :     RestrictInfo *restrictinfo;
    1623             : 
    1624             :     /*
    1625             :      * Retrieve all relids mentioned within the clause.
    1626             :      */
    1627      305626 :     relids = pull_varnos(root, clause);
    1628             : 
    1629             :     /*
    1630             :      * In ordinary SQL, a WHERE or JOIN/ON clause can't reference any rels
    1631             :      * that aren't within its syntactic scope; however, if we pulled up a
    1632             :      * LATERAL subquery then we might find such references in quals that have
    1633             :      * been pulled up.  We need to treat such quals as belonging to the join
    1634             :      * level that includes every rel they reference.  Although we could make
    1635             :      * pull_up_subqueries() place such quals correctly to begin with, it's
    1636             :      * easier to handle it here.  When we find a clause that contains Vars
    1637             :      * outside its syntactic scope, we add it to the postponed-quals list, and
    1638             :      * process it once we've recursed back up to the appropriate join level.
    1639             :      */
    1640      305626 :     if (!bms_is_subset(relids, qualscope))
    1641             :     {
    1642          84 :         PostponedQual *pq = (PostponedQual *) palloc(sizeof(PostponedQual));
    1643             : 
    1644             :         Assert(root->hasLateralRTEs);    /* shouldn't happen otherwise */
    1645             :         Assert(jointype == JOIN_INNER); /* mustn't postpone past outer join */
    1646          84 :         pq->qual = clause;
    1647          84 :         pq->relids = relids;
    1648          84 :         *postponed_qual_list = lappend(*postponed_qual_list, pq);
    1649      211088 :         return;
    1650             :     }
    1651             : 
    1652             :     /*
    1653             :      * If it's an outer-join clause, also check that relids is a subset of
    1654             :      * ojscope.  (This should not fail if the syntactic scope check passed.)
    1655             :      */
    1656      305542 :     if (ojscope && !bms_is_subset(relids, ojscope))
    1657           0 :         elog(ERROR, "JOIN qualification cannot refer to other relations");
    1658             : 
    1659             :     /*
    1660             :      * If the clause is variable-free, our normal heuristic for pushing it
    1661             :      * down to just the mentioned rels doesn't work, because there are none.
    1662             :      *
    1663             :      * If the clause is an outer-join clause, we must force it to the OJ's
    1664             :      * semantic level to preserve semantics.
    1665             :      *
    1666             :      * Otherwise, when the clause contains volatile functions, we force it to
    1667             :      * be evaluated at its original syntactic level.  This preserves the
    1668             :      * expected semantics.
    1669             :      *
    1670             :      * When the clause contains no volatile functions either, it is actually a
    1671             :      * pseudoconstant clause that will not change value during any one
    1672             :      * execution of the plan, and hence can be used as a one-time qual in a
    1673             :      * gating Result plan node.  We put such a clause into the regular
    1674             :      * RestrictInfo lists for the moment, but eventually createplan.c will
    1675             :      * pull it out and make a gating Result node immediately above whatever
    1676             :      * plan node the pseudoconstant clause is assigned to.  It's usually best
    1677             :      * to put a gating node as high in the plan tree as possible. If we are
    1678             :      * not below an outer join, we can actually push the pseudoconstant qual
    1679             :      * all the way to the top of the tree.  If we are below an outer join, we
    1680             :      * leave the qual at its original syntactic level (we could push it up to
    1681             :      * just below the outer join, but that seems more complex than it's
    1682             :      * worth).
    1683             :      */
    1684      305542 :     if (bms_is_empty(relids))
    1685             :     {
    1686        3518 :         if (ojscope)
    1687             :         {
    1688             :             /* clause is attached to outer join, eval it there */
    1689         144 :             relids = bms_copy(ojscope);
    1690             :             /* mustn't use as gating qual, so don't mark pseudoconstant */
    1691             :         }
    1692             :         else
    1693             :         {
    1694             :             /* eval at original syntactic level */
    1695        3374 :             relids = bms_copy(qualscope);
    1696        3374 :             if (!contain_volatile_functions(clause))
    1697             :             {
    1698             :                 /* mark as gating qual */
    1699        3206 :                 pseudoconstant = true;
    1700             :                 /* tell createplan.c to check for gating quals */
    1701        3206 :                 root->hasPseudoConstantQuals = true;
    1702             :                 /* if not below outer join, push it to top of tree */
    1703        3206 :                 if (!below_outer_join)
    1704             :                 {
    1705        3158 :                     relids =
    1706        3158 :                         get_relids_in_jointree((Node *) root->parse->jointree,
    1707             :                                                false);
    1708        3158 :                     qualscope = bms_copy(relids);
    1709             :                 }
    1710             :             }
    1711             :         }
    1712             :     }
    1713             : 
    1714             :     /*----------
    1715             :      * Check to see if clause application must be delayed by outer-join
    1716             :      * considerations.
    1717             :      *
    1718             :      * A word about is_pushed_down: we mark the qual as "pushed down" if
    1719             :      * it is (potentially) applicable at a level different from its original
    1720             :      * syntactic level.  This flag is used to distinguish OUTER JOIN ON quals
    1721             :      * from other quals pushed down to the same joinrel.  The rules are:
    1722             :      *      WHERE quals and INNER JOIN quals: is_pushed_down = true.
    1723             :      *      Non-degenerate OUTER JOIN quals: is_pushed_down = false.
    1724             :      *      Degenerate OUTER JOIN quals: is_pushed_down = true.
    1725             :      * A "degenerate" OUTER JOIN qual is one that doesn't mention the
    1726             :      * non-nullable side, and hence can be pushed down into the nullable side
    1727             :      * without changing the join result.  It is correct to treat it as a
    1728             :      * regular filter condition at the level where it is evaluated.
    1729             :      *
    1730             :      * Note: it is not immediately obvious that a simple boolean is enough
    1731             :      * for this: if for some reason we were to attach a degenerate qual to
    1732             :      * its original join level, it would need to be treated as an outer join
    1733             :      * qual there.  However, this cannot happen, because all the rels the
    1734             :      * clause mentions must be in the outer join's min_righthand, therefore
    1735             :      * the join it needs must be formed before the outer join; and we always
    1736             :      * attach quals to the lowest level where they can be evaluated.  But
    1737             :      * if we were ever to re-introduce a mechanism for delaying evaluation
    1738             :      * of "expensive" quals, this area would need work.
    1739             :      *
    1740             :      * Note: generally, use of is_pushed_down has to go through the macro
    1741             :      * RINFO_IS_PUSHED_DOWN, because that flag alone is not always sufficient
    1742             :      * to tell whether a clause must be treated as pushed-down in context.
    1743             :      * This seems like another reason why it should perhaps be rethought.
    1744             :      *----------
    1745             :      */
    1746      305542 :     if (bms_overlap(relids, outerjoin_nonnullable))
    1747             :     {
    1748             :         /*
    1749             :          * The qual is attached to an outer join and mentions (some of the)
    1750             :          * rels on the nonnullable side, so it's not degenerate.
    1751             :          *
    1752             :          * We can't use such a clause to deduce equivalence (the left and
    1753             :          * right sides might be unequal above the join because one of them has
    1754             :          * gone to NULL) ... but we might be able to use it for more limited
    1755             :          * deductions, if it is mergejoinable.  So consider adding it to the
    1756             :          * lists of set-aside outer-join clauses.
    1757             :          */
    1758       52072 :         is_pushed_down = false;
    1759       52072 :         maybe_equivalence = false;
    1760       52072 :         maybe_outer_join = true;
    1761             : 
    1762             :         /* Check to see if must be delayed by lower outer join */
    1763       52072 :         outerjoin_delayed = check_outerjoin_delay(root,
    1764             :                                                   &relids,
    1765             :                                                   &nullable_relids,
    1766             :                                                   false);
    1767             : 
    1768             :         /*
    1769             :          * Now force the qual to be evaluated exactly at the level of joining
    1770             :          * corresponding to the outer join.  We cannot let it get pushed down
    1771             :          * into the nonnullable side, since then we'd produce no output rows,
    1772             :          * rather than the intended single null-extended row, for any
    1773             :          * nonnullable-side rows failing the qual.
    1774             :          *
    1775             :          * (Do this step after calling check_outerjoin_delay, because that
    1776             :          * trashes relids.)
    1777             :          */
    1778             :         Assert(ojscope);
    1779       52072 :         relids = ojscope;
    1780             :         Assert(!pseudoconstant);
    1781             :     }
    1782             :     else
    1783             :     {
    1784             :         /*
    1785             :          * Normal qual clause or degenerate outer-join clause.  Either way, we
    1786             :          * can mark it as pushed-down.
    1787             :          */
    1788      253470 :         is_pushed_down = true;
    1789             : 
    1790             :         /* Check to see if must be delayed by lower outer join */
    1791      253470 :         outerjoin_delayed = check_outerjoin_delay(root,
    1792             :                                                   &relids,
    1793             :                                                   &nullable_relids,
    1794             :                                                   true);
    1795             : 
    1796      253470 :         if (outerjoin_delayed)
    1797             :         {
    1798             :             /* Should still be a subset of current scope ... */
    1799             :             Assert(root->hasLateralRTEs || bms_is_subset(relids, qualscope));
    1800             :             Assert(ojscope == NULL || bms_is_subset(relids, ojscope));
    1801             : 
    1802             :             /*
    1803             :              * Because application of the qual will be delayed by outer join,
    1804             :              * we mustn't assume its vars are equal everywhere.
    1805             :              */
    1806        1026 :             maybe_equivalence = false;
    1807             : 
    1808             :             /*
    1809             :              * It's possible that this is an IS NULL clause that's redundant
    1810             :              * with a lower antijoin; if so we can just discard it.  We need
    1811             :              * not test in any of the other cases, because this will only be
    1812             :              * possible for pushed-down, delayed clauses.
    1813             :              */
    1814        1026 :             if (check_redundant_nullability_qual(root, clause))
    1815         702 :                 return;
    1816             :         }
    1817             :         else
    1818             :         {
    1819             :             /*
    1820             :              * Qual is not delayed by any lower outer-join restriction, so we
    1821             :              * can consider feeding it to the equivalence machinery. However,
    1822             :              * if it's itself within an outer-join clause, treat it as though
    1823             :              * it appeared below that outer join (note that we can only get
    1824             :              * here when the clause references only nullable-side rels).
    1825             :              */
    1826      252444 :             maybe_equivalence = true;
    1827      252444 :             if (outerjoin_nonnullable != NULL)
    1828       21866 :                 below_outer_join = true;
    1829             :         }
    1830             : 
    1831             :         /*
    1832             :          * Since it doesn't mention the LHS, it's certainly not useful as a
    1833             :          * set-aside OJ clause, even if it's in an OJ.
    1834             :          */
    1835      252768 :         maybe_outer_join = false;
    1836             :     }
    1837             : 
    1838             :     /*
    1839             :      * Build the RestrictInfo node itself.
    1840             :      */
    1841      304840 :     restrictinfo = make_restrictinfo(root,
    1842             :                                      (Expr *) clause,
    1843             :                                      is_pushed_down,
    1844             :                                      outerjoin_delayed,
    1845             :                                      pseudoconstant,
    1846             :                                      security_level,
    1847             :                                      relids,
    1848             :                                      outerjoin_nonnullable,
    1849             :                                      nullable_relids);
    1850             : 
    1851             :     /*
    1852             :      * If it's a join clause (either naturally, or because delayed by
    1853             :      * outer-join rules), add vars used in the clause to targetlists of their
    1854             :      * relations, so that they will be emitted by the plan nodes that scan
    1855             :      * those relations (else they won't be available at the join node!).
    1856             :      *
    1857             :      * Note: if the clause gets absorbed into an EquivalenceClass then this
    1858             :      * may be unnecessary, but for now we have to do it to cover the case
    1859             :      * where the EC becomes ec_broken and we end up reinserting the original
    1860             :      * clauses into the plan.
    1861             :      */
    1862      304840 :     if (bms_membership(relids) == BMS_MULTIPLE)
    1863             :     {
    1864       85028 :         List       *vars = pull_var_clause(clause,
    1865             :                                            PVC_RECURSE_AGGREGATES |
    1866             :                                            PVC_RECURSE_WINDOWFUNCS |
    1867             :                                            PVC_INCLUDE_PLACEHOLDERS);
    1868             : 
    1869       85028 :         add_vars_to_targetlist(root, vars, relids, false);
    1870       85028 :         list_free(vars);
    1871             :     }
    1872             : 
    1873             :     /*
    1874             :      * We check "mergejoinability" of every clause, not only join clauses,
    1875             :      * because we want to know about equivalences between vars of the same
    1876             :      * relation, or between vars and consts.
    1877             :      */
    1878      304840 :     check_mergejoinable(restrictinfo);
    1879             : 
    1880             :     /*
    1881             :      * If it is a true equivalence clause, send it to the EquivalenceClass
    1882             :      * machinery.  We do *not* attach it directly to any restriction or join
    1883             :      * lists.  The EC code will propagate it to the appropriate places later.
    1884             :      *
    1885             :      * If the clause has a mergejoinable operator and is not
    1886             :      * outerjoin-delayed, yet isn't an equivalence because it is an outer-join
    1887             :      * clause, the EC code may yet be able to do something with it.  We add it
    1888             :      * to appropriate lists for further consideration later.  Specifically:
    1889             :      *
    1890             :      * If it is a left or right outer-join qualification that relates the two
    1891             :      * sides of the outer join (no funny business like leftvar1 = leftvar2 +
    1892             :      * rightvar), we add it to root->left_join_clauses or
    1893             :      * root->right_join_clauses according to which side the nonnullable
    1894             :      * variable appears on.
    1895             :      *
    1896             :      * If it is a full outer-join qualification, we add it to
    1897             :      * root->full_join_clauses.  (Ideally we'd discard cases that aren't
    1898             :      * leftvar = rightvar, as we do for left/right joins, but this routine
    1899             :      * doesn't have the info needed to do that; and the current usage of the
    1900             :      * full_join_clauses list doesn't require that, so it's not currently
    1901             :      * worth complicating this routine's API to make it possible.)
    1902             :      *
    1903             :      * If none of the above hold, pass it off to
    1904             :      * distribute_restrictinfo_to_rels().
    1905             :      *
    1906             :      * In all cases, it's important to initialize the left_ec and right_ec
    1907             :      * fields of a mergejoinable clause, so that all possibly mergejoinable
    1908             :      * expressions have representations in EquivalenceClasses.  If
    1909             :      * process_equivalence is successful, it will take care of that;
    1910             :      * otherwise, we have to call initialize_mergeclause_eclasses to do it.
    1911             :      */
    1912      304840 :     if (restrictinfo->mergeopfamilies)
    1913             :     {
    1914      210754 :         if (maybe_equivalence)
    1915             :         {
    1916      331620 :             if (check_equivalence_delay(root, restrictinfo) &&
    1917      165802 :                 process_equivalence(root, &restrictinfo, below_outer_join))
    1918      165710 :                 return;
    1919             :             /* EC rejected it, so set left_ec/right_ec the hard way ... */
    1920         108 :             if (restrictinfo->mergeopfamilies)   /* EC might have changed this */
    1921          80 :                 initialize_mergeclause_eclasses(root, restrictinfo);
    1922             :             /* ... and fall through to distribute_restrictinfo_to_rels */
    1923             :         }
    1924       44936 :         else if (maybe_outer_join && restrictinfo->can_join)
    1925             :         {
    1926             :             /* we need to set up left_ec/right_ec the hard way */
    1927       44604 :             initialize_mergeclause_eclasses(root, restrictinfo);
    1928             :             /* now see if it should go to any outer-join lists */
    1929       44604 :             if (bms_is_subset(restrictinfo->left_relids,
    1930       34064 :                               outerjoin_nonnullable) &&
    1931       34064 :                 !bms_overlap(restrictinfo->right_relids,
    1932             :                              outerjoin_nonnullable))
    1933             :             {
    1934             :                 /* we have outervar = innervar */
    1935       33326 :                 root->left_join_clauses = lappend(root->left_join_clauses,
    1936             :                                                   restrictinfo);
    1937       33326 :                 return;
    1938             :             }
    1939       11278 :             if (bms_is_subset(restrictinfo->right_relids,
    1940       11274 :                               outerjoin_nonnullable) &&
    1941       11274 :                 !bms_overlap(restrictinfo->left_relids,
    1942             :                              outerjoin_nonnullable))
    1943             :             {
    1944             :                 /* we have innervar = outervar */
    1945       10536 :                 root->right_join_clauses = lappend(root->right_join_clauses,
    1946             :                                                    restrictinfo);
    1947       10536 :                 return;
    1948             :             }
    1949         742 :             if (jointype == JOIN_FULL)
    1950             :             {
    1951             :                 /* FULL JOIN (above tests cannot match in this case) */
    1952         730 :                 root->full_join_clauses = lappend(root->full_join_clauses,
    1953             :                                                   restrictinfo);
    1954         730 :                 return;
    1955             :             }
    1956             :             /* nope, so fall through to distribute_restrictinfo_to_rels */
    1957             :         }
    1958             :         else
    1959             :         {
    1960             :             /* we still need to set up left_ec/right_ec */
    1961         332 :             initialize_mergeclause_eclasses(root, restrictinfo);
    1962             :         }
    1963             :     }
    1964             : 
    1965             :     /* No EC special case applies, so push it into the clause lists */
    1966       94538 :     distribute_restrictinfo_to_rels(root, restrictinfo);
    1967             : }
    1968             : 
    1969             : /*
    1970             :  * check_outerjoin_delay
    1971             :  *      Detect whether a qual referencing the given relids must be delayed
    1972             :  *      in application due to the presence of a lower outer join, and/or
    1973             :  *      may force extra delay of higher-level outer joins.
    1974             :  *
    1975             :  * If the qual must be delayed, add relids to *relids_p to reflect the lowest
    1976             :  * safe level for evaluating the qual, and return true.  Any extra delay for
    1977             :  * higher-level joins is reflected by setting delay_upper_joins to true in
    1978             :  * SpecialJoinInfo structs.  We also compute nullable_relids, the set of
    1979             :  * referenced relids that are nullable by lower outer joins (note that this
    1980             :  * can be nonempty even for a non-delayed qual).
    1981             :  *
    1982             :  * For an is_pushed_down qual, we can evaluate the qual as soon as (1) we have
    1983             :  * all the rels it mentions, and (2) we are at or above any outer joins that
    1984             :  * can null any of these rels and are below the syntactic location of the
    1985             :  * given qual.  We must enforce (2) because pushing down such a clause below
    1986             :  * the OJ might cause the OJ to emit null-extended rows that should not have
    1987             :  * been formed, or that should have been rejected by the clause.  (This is
    1988             :  * only an issue for non-strict quals, since if we can prove a qual mentioning
    1989             :  * only nullable rels is strict, we'd have reduced the outer join to an inner
    1990             :  * join in reduce_outer_joins().)
    1991             :  *
    1992             :  * To enforce (2), scan the join_info_list and merge the required-relid sets of
    1993             :  * any such OJs into the clause's own reference list.  At the time we are
    1994             :  * called, the join_info_list contains only outer joins below this qual.  We
    1995             :  * have to repeat the scan until no new relids get added; this ensures that
    1996             :  * the qual is suitably delayed regardless of the order in which OJs get
    1997             :  * executed.  As an example, if we have one OJ with LHS=A, RHS=B, and one with
    1998             :  * LHS=B, RHS=C, it is implied that these can be done in either order; if the
    1999             :  * B/C join is done first then the join to A can null C, so a qual actually
    2000             :  * mentioning only C cannot be applied below the join to A.
    2001             :  *
    2002             :  * For a non-pushed-down qual, this isn't going to determine where we place the
    2003             :  * qual, but we need to determine outerjoin_delayed and nullable_relids anyway
    2004             :  * for use later in the planning process.
    2005             :  *
    2006             :  * Lastly, a pushed-down qual that references the nullable side of any current
    2007             :  * join_info_list member and has to be evaluated above that OJ (because its
    2008             :  * required relids overlap the LHS too) causes that OJ's delay_upper_joins
    2009             :  * flag to be set true.  This will prevent any higher-level OJs from
    2010             :  * being interchanged with that OJ, which would result in not having any
    2011             :  * correct place to evaluate the qual.  (The case we care about here is a
    2012             :  * sub-select WHERE clause within the RHS of some outer join.  The WHERE
    2013             :  * clause must effectively be treated as a degenerate clause of that outer
    2014             :  * join's condition.  Rather than trying to match such clauses with joins
    2015             :  * directly, we set delay_upper_joins here, and when the upper outer join
    2016             :  * is processed by make_outerjoininfo, it will refrain from allowing the
    2017             :  * two OJs to commute.)
    2018             :  */
    2019             : static bool
    2020      351342 : check_outerjoin_delay(PlannerInfo *root,
    2021             :                       Relids *relids_p, /* in/out parameter */
    2022             :                       Relids *nullable_relids_p,    /* output parameter */
    2023             :                       bool is_pushed_down)
    2024             : {
    2025             :     Relids      relids;
    2026             :     Relids      nullable_relids;
    2027             :     bool        outerjoin_delayed;
    2028             :     bool        found_some;
    2029             : 
    2030             :     /* fast path if no special joins */
    2031      351342 :     if (root->join_info_list == NIL)
    2032             :     {
    2033      249048 :         *nullable_relids_p = NULL;
    2034      249048 :         return false;
    2035             :     }
    2036             : 
    2037             :     /* must copy relids because we need the original value at the end */
    2038      102294 :     relids = bms_copy(*relids_p);
    2039      102294 :     nullable_relids = NULL;
    2040      102294 :     outerjoin_delayed = false;
    2041             :     do
    2042             :     {
    2043             :         ListCell   *l;
    2044             : 
    2045      104044 :         found_some = false;
    2046      234540 :         foreach(l, root->join_info_list)
    2047             :         {
    2048      130496 :             SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l);
    2049             : 
    2050             :             /* do we reference any nullable rels of this OJ? */
    2051      130496 :             if (bms_overlap(relids, sjinfo->min_righthand) ||
    2052      125498 :                 (sjinfo->jointype == JOIN_FULL &&
    2053         120 :                  bms_overlap(relids, sjinfo->min_lefthand)))
    2054             :             {
    2055             :                 /* yes; have we included all its rels in relids? */
    2056        5202 :                 if (!bms_is_subset(sjinfo->min_lefthand, relids) ||
    2057        3504 :                     !bms_is_subset(sjinfo->min_righthand, relids))
    2058             :                 {
    2059             :                     /* no, so add them in */
    2060        1774 :                     relids = bms_add_members(relids, sjinfo->min_lefthand);
    2061        1774 :                     relids = bms_add_members(relids, sjinfo->min_righthand);
    2062        1774 :                     outerjoin_delayed = true;
    2063             :                     /* we'll need another iteration */
    2064        1774 :                     found_some = true;
    2065             :                 }
    2066             :                 /* track all the nullable rels of relevant OJs */
    2067        5202 :                 nullable_relids = bms_add_members(nullable_relids,
    2068        5202 :                                                   sjinfo->min_righthand);
    2069        5202 :                 if (sjinfo->jointype == JOIN_FULL)
    2070         650 :                     nullable_relids = bms_add_members(nullable_relids,
    2071         650 :                                                       sjinfo->min_lefthand);
    2072             :                 /* set delay_upper_joins if needed */
    2073        8310 :                 if (is_pushed_down && sjinfo->jointype != JOIN_FULL &&
    2074        3108 :                     bms_overlap(relids, sjinfo->min_lefthand))
    2075        3108 :                     sjinfo->delay_upper_joins = true;
    2076             :             }
    2077             :         }
    2078      104044 :     } while (found_some);
    2079             : 
    2080             :     /* identify just the actually-referenced nullable rels */
    2081      102294 :     nullable_relids = bms_int_members(nullable_relids, *relids_p);
    2082             : 
    2083             :     /* replace *relids_p, and return nullable_relids */
    2084      102294 :     bms_free(*relids_p);
    2085      102294 :     *relids_p = relids;
    2086      102294 :     *nullable_relids_p = nullable_relids;
    2087      102294 :     return outerjoin_delayed;
    2088             : }
    2089             : 
    2090             : /*
    2091             :  * check_equivalence_delay
    2092             :  *      Detect whether a potential equivalence clause is rendered unsafe
    2093             :  *      by outer-join-delay considerations.  Return true if it's safe.
    2094             :  *
    2095             :  * The initial tests in distribute_qual_to_rels will consider a mergejoinable
    2096             :  * clause to be a potential equivalence clause if it is not outerjoin_delayed.
    2097             :  * But since the point of equivalence processing is that we will recombine the
    2098             :  * two sides of the clause with others, we have to check that each side
    2099             :  * satisfies the not-outerjoin_delayed condition on its own; otherwise it might
    2100             :  * not be safe to evaluate everywhere we could place a derived equivalence
    2101             :  * condition.
    2102             :  */
    2103             : static bool
    2104      165818 : check_equivalence_delay(PlannerInfo *root,
    2105             :                         RestrictInfo *restrictinfo)
    2106             : {
    2107             :     Relids      relids;
    2108             :     Relids      nullable_relids;
    2109             : 
    2110             :     /* fast path if no special joins */
    2111      165818 :     if (root->join_info_list == NIL)
    2112      142914 :         return true;
    2113             : 
    2114             :     /* must copy restrictinfo's relids to avoid changing it */
    2115       22904 :     relids = bms_copy(restrictinfo->left_relids);
    2116             :     /* check left side does not need delay */
    2117       22904 :     if (check_outerjoin_delay(root, &relids, &nullable_relids, true))
    2118           8 :         return false;
    2119             : 
    2120             :     /* and similarly for the right side */
    2121       22896 :     relids = bms_copy(restrictinfo->right_relids);
    2122       22896 :     if (check_outerjoin_delay(root, &relids, &nullable_relids, true))
    2123           8 :         return false;
    2124             : 
    2125       22888 :     return true;
    2126             : }
    2127             : 
    2128             : /*
    2129             :  * check_redundant_nullability_qual
    2130             :  *    Check to see if the qual is an IS NULL qual that is redundant with
    2131             :  *    a lower JOIN_ANTI join.
    2132             :  *
    2133             :  * We want to suppress redundant IS NULL quals, not so much to save cycles
    2134             :  * as to avoid generating bogus selectivity estimates for them.  So if
    2135             :  * redundancy is detected here, distribute_qual_to_rels() just throws away
    2136             :  * the qual.
    2137             :  */
    2138             : static bool
    2139        1026 : check_redundant_nullability_qual(PlannerInfo *root, Node *clause)
    2140             : {
    2141             :     Var        *forced_null_var;
    2142             :     Index       forced_null_rel;
    2143             :     ListCell   *lc;
    2144             : 
    2145             :     /* Check for IS NULL, and identify the Var forced to NULL */
    2146        1026 :     forced_null_var = find_forced_null_var(clause);
    2147        1026 :     if (forced_null_var == NULL)
    2148         262 :         return false;
    2149         764 :     forced_null_rel = forced_null_var->varno;
    2150             : 
    2151             :     /*
    2152             :      * If the Var comes from the nullable side of a lower antijoin, the IS
    2153             :      * NULL condition is necessarily true.
    2154             :      */
    2155         846 :     foreach(lc, root->join_info_list)
    2156             :     {
    2157         784 :         SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
    2158             : 
    2159        1490 :         if (sjinfo->jointype == JOIN_ANTI &&
    2160         706 :             bms_is_member(forced_null_rel, sjinfo->syn_righthand))
    2161         702 :             return true;
    2162             :     }
    2163             : 
    2164          62 :     return false;
    2165             : }
    2166             : 
    2167             : /*
    2168             :  * distribute_restrictinfo_to_rels
    2169             :  *    Push a completed RestrictInfo into the proper restriction or join
    2170             :  *    clause list(s).
    2171             :  *
    2172             :  * This is the last step of distribute_qual_to_rels() for ordinary qual
    2173             :  * clauses.  Clauses that are interesting for equivalence-class processing
    2174             :  * are diverted to the EC machinery, but may ultimately get fed back here.
    2175             :  */
    2176             : void
    2177      287334 : distribute_restrictinfo_to_rels(PlannerInfo *root,
    2178             :                                 RestrictInfo *restrictinfo)
    2179             : {
    2180      287334 :     Relids      relids = restrictinfo->required_relids;
    2181             :     RelOptInfo *rel;
    2182             : 
    2183      287334 :     switch (bms_membership(relids))
    2184             :     {
    2185      230016 :         case BMS_SINGLETON:
    2186             : 
    2187             :             /*
    2188             :              * There is only one relation participating in the clause, so it
    2189             :              * is a restriction clause for that relation.
    2190             :              */
    2191      230016 :             rel = find_base_rel(root, bms_singleton_member(relids));
    2192             : 
    2193             :             /* Add clause to rel's restriction list */
    2194      230016 :             rel->baserestrictinfo = lappend(rel->baserestrictinfo,
    2195             :                                             restrictinfo);
    2196             :             /* Update security level info */
    2197      230016 :             rel->baserestrict_min_security = Min(rel->baserestrict_min_security,
    2198             :                                                  restrictinfo->security_level);
    2199      230016 :             break;
    2200       57318 :         case BMS_MULTIPLE:
    2201             : 
    2202             :             /*
    2203             :              * The clause is a join clause, since there is more than one rel
    2204             :              * in its relid set.
    2205             :              */
    2206             : 
    2207             :             /*
    2208             :              * Check for hashjoinable operators.  (We don't bother setting the
    2209             :              * hashjoin info except in true join clauses.)
    2210             :              */
    2211       57318 :             check_hashjoinable(restrictinfo);
    2212             : 
    2213             :             /*
    2214             :              * Likewise, check if the clause is suitable to be used with a
    2215             :              * Result Cache node to cache inner tuples during a parameterized
    2216             :              * nested loop.
    2217             :              */
    2218       57318 :             check_resultcacheable(restrictinfo);
    2219             : 
    2220             :             /*
    2221             :              * Add clause to the join lists of all the relevant relations.
    2222             :              */
    2223       57318 :             add_join_clause_to_rels(root, restrictinfo, relids);
    2224       57318 :             break;
    2225           0 :         default:
    2226             : 
    2227             :             /*
    2228             :              * clause references no rels, and therefore we have no place to
    2229             :              * attach it.  Shouldn't get here if callers are working properly.
    2230             :              */
    2231           0 :             elog(ERROR, "cannot cope with variable-free clause");
    2232             :             break;
    2233             :     }
    2234      287334 : }
    2235             : 
    2236             : /*
    2237             :  * process_implied_equality
    2238             :  *    Create a restrictinfo item that says "item1 op item2", and push it
    2239             :  *    into the appropriate lists.  (In practice opno is always a btree
    2240             :  *    equality operator.)
    2241             :  *
    2242             :  * "qualscope" is the nominal syntactic level to impute to the restrictinfo.
    2243             :  * This must contain at least all the rels used in the expressions, but it
    2244             :  * is used only to set the qual application level when both exprs are
    2245             :  * variable-free.  Otherwise the qual is applied at the lowest join level
    2246             :  * that provides all its variables.
    2247             :  *
    2248             :  * "nullable_relids" is the set of relids used in the expressions that are
    2249             :  * potentially nullable below the expressions.  (This has to be supplied by
    2250             :  * caller because this function is used after deconstruct_jointree, so we
    2251             :  * don't have knowledge of where the clause items came from.)
    2252             :  *
    2253             :  * "security_level" is the security level to assign to the new restrictinfo.
    2254             :  *
    2255             :  * "both_const" indicates whether both items are known pseudo-constant;
    2256             :  * in this case it is worth applying eval_const_expressions() in case we
    2257             :  * can produce constant TRUE or constant FALSE.  (Otherwise it's not,
    2258             :  * because the expressions went through eval_const_expressions already.)
    2259             :  *
    2260             :  * Returns the generated RestrictInfo, if any.  The result will be NULL
    2261             :  * if both_const is true and we successfully reduced the clause to
    2262             :  * constant TRUE.
    2263             :  *
    2264             :  * Note: this function will copy item1 and item2, but it is caller's
    2265             :  * responsibility to make sure that the Relids parameters are fresh copies
    2266             :  * not shared with other uses.
    2267             :  *
    2268             :  * Note: we do not do initialize_mergeclause_eclasses() here.  It is
    2269             :  * caller's responsibility that left_ec/right_ec be set as necessary.
    2270             :  */
    2271             : RestrictInfo *
    2272       10626 : process_implied_equality(PlannerInfo *root,
    2273             :                          Oid opno,
    2274             :                          Oid collation,
    2275             :                          Expr *item1,
    2276             :                          Expr *item2,
    2277             :                          Relids qualscope,
    2278             :                          Relids nullable_relids,
    2279             :                          Index security_level,
    2280             :                          bool below_outer_join,
    2281             :                          bool both_const)
    2282             : {
    2283             :     RestrictInfo *restrictinfo;
    2284             :     Node       *clause;
    2285             :     Relids      relids;
    2286       10626 :     bool        pseudoconstant = false;
    2287             : 
    2288             :     /*
    2289             :      * Build the new clause.  Copy to ensure it shares no substructure with
    2290             :      * original (this is necessary in case there are subselects in there...)
    2291             :      */
    2292       10626 :     clause = (Node *) make_opclause(opno,
    2293             :                                     BOOLOID,    /* opresulttype */
    2294             :                                     false,  /* opretset */
    2295       10626 :                                     copyObject(item1),
    2296       10626 :                                     copyObject(item2),
    2297             :                                     InvalidOid,
    2298             :                                     collation);
    2299             : 
    2300             :     /* If both constant, try to reduce to a boolean constant. */
    2301       10626 :     if (both_const)
    2302             :     {
    2303          80 :         clause = eval_const_expressions(root, clause);
    2304             : 
    2305             :         /* If we produced const TRUE, just drop the clause */
    2306          80 :         if (clause && IsA(clause, Const))
    2307             :         {
    2308          80 :             Const      *cclause = (Const *) clause;
    2309             : 
    2310             :             Assert(cclause->consttype == BOOLOID);
    2311          80 :             if (!cclause->constisnull && DatumGetBool(cclause->constvalue))
    2312           0 :                 return NULL;
    2313             :         }
    2314             :     }
    2315             : 
    2316             :     /*
    2317             :      * The rest of this is a very cut-down version of distribute_qual_to_rels.
    2318             :      * We can skip most of the work therein, but there are a couple of special
    2319             :      * cases we still have to handle.
    2320             :      *
    2321             :      * Retrieve all relids mentioned within the possibly-simplified clause.
    2322             :      */
    2323       10626 :     relids = pull_varnos(root, clause);
    2324             :     Assert(bms_is_subset(relids, qualscope));
    2325             : 
    2326             :     /*
    2327             :      * If the clause is variable-free, our normal heuristic for pushing it
    2328             :      * down to just the mentioned rels doesn't work, because there are none.
    2329             :      * Apply at the given qualscope, or at the top of tree if it's nonvolatile
    2330             :      * (which it very likely is, but we'll check, just to be sure).
    2331             :      */
    2332       10626 :     if (bms_is_empty(relids))
    2333             :     {
    2334             :         /* eval at original syntactic level */
    2335          80 :         relids = bms_copy(qualscope);
    2336          80 :         if (!contain_volatile_functions(clause))
    2337             :         {
    2338             :             /* mark as gating qual */
    2339          80 :             pseudoconstant = true;
    2340             :             /* tell createplan.c to check for gating quals */
    2341          80 :             root->hasPseudoConstantQuals = true;
    2342             :             /* if not below outer join, push it to top of tree */
    2343          80 :             if (!below_outer_join)
    2344             :             {
    2345             :                 relids =
    2346          40 :                     get_relids_in_jointree((Node *) root->parse->jointree,
    2347             :                                            false);
    2348             :             }
    2349             :         }
    2350             :     }
    2351             : 
    2352             :     /*
    2353             :      * Build the RestrictInfo node itself.
    2354             :      */
    2355       10626 :     restrictinfo = make_restrictinfo(root,
    2356             :                                      (Expr *) clause,
    2357             :                                      true,  /* is_pushed_down */
    2358             :                                      false, /* outerjoin_delayed */
    2359             :                                      pseudoconstant,
    2360             :                                      security_level,
    2361             :                                      relids,
    2362             :                                      NULL,  /* outer_relids */
    2363             :                                      nullable_relids);
    2364             : 
    2365             :     /*
    2366             :      * If it's a join clause, add vars used in the clause to targetlists of
    2367             :      * their relations, so that they will be emitted by the plan nodes that
    2368             :      * scan those relations (else they won't be available at the join node!).
    2369             :      *
    2370             :      * Typically, we'd have already done this when the component expressions
    2371             :      * were first seen by distribute_qual_to_rels; but it is possible that
    2372             :      * some of the Vars could have missed having that done because they only
    2373             :      * appeared in single-relation clauses originally.  So do it here for
    2374             :      * safety.
    2375             :      */
    2376       10626 :     if (bms_membership(relids) == BMS_MULTIPLE)
    2377             :     {
    2378          74 :         List       *vars = pull_var_clause(clause,
    2379             :                                            PVC_RECURSE_AGGREGATES |
    2380             :                                            PVC_RECURSE_WINDOWFUNCS |
    2381             :                                            PVC_INCLUDE_PLACEHOLDERS);
    2382             : 
    2383          74 :         add_vars_to_targetlist(root, vars, relids, false);
    2384          74 :         list_free(vars);
    2385             :     }
    2386             : 
    2387             :     /*
    2388             :      * Check mergejoinability.  This will usually succeed, since the op came
    2389             :      * from an EquivalenceClass; but we could have reduced the original clause
    2390             :      * to a constant.
    2391             :      */
    2392       10626 :     check_mergejoinable(restrictinfo);
    2393             : 
    2394             :     /*
    2395             :      * Note we don't do initialize_mergeclause_eclasses(); the caller can
    2396             :      * handle that much more cheaply than we can.  It's okay to call
    2397             :      * distribute_restrictinfo_to_rels() before that happens.
    2398             :      */
    2399             : 
    2400             :     /*
    2401             :      * Push the new clause into all the appropriate restrictinfo lists.
    2402             :      */
    2403       10626 :     distribute_restrictinfo_to_rels(root, restrictinfo);
    2404             : 
    2405       10626 :     return restrictinfo;
    2406             : }
    2407             : 
    2408             : /*
    2409             :  * build_implied_join_equality --- build a RestrictInfo for a derived equality
    2410             :  *
    2411             :  * This overlaps the functionality of process_implied_equality(), but we
    2412             :  * must not push the RestrictInfo into the joininfo tree.
    2413             :  *
    2414             :  * Note: this function will copy item1 and item2, but it is caller's
    2415             :  * responsibility to make sure that the Relids parameters are fresh copies
    2416             :  * not shared with other uses.
    2417             :  *
    2418             :  * Note: we do not do initialize_mergeclause_eclasses() here.  It is
    2419             :  * caller's responsibility that left_ec/right_ec be set as necessary.
    2420             :  */
    2421             : RestrictInfo *
    2422       56158 : build_implied_join_equality(PlannerInfo *root,
    2423             :                             Oid opno,
    2424             :                             Oid collation,
    2425             :                             Expr *item1,
    2426             :                             Expr *item2,
    2427             :                             Relids qualscope,
    2428             :                             Relids nullable_relids,
    2429             :                             Index security_level)
    2430             : {
    2431             :     RestrictInfo *restrictinfo;
    2432             :     Expr       *clause;
    2433             : 
    2434             :     /*
    2435             :      * Build the new clause.  Copy to ensure it shares no substructure with
    2436             :      * original (this is necessary in case there are subselects in there...)
    2437             :      */
    2438       56158 :     clause = make_opclause(opno,
    2439             :                            BOOLOID, /* opresulttype */
    2440             :                            false,   /* opretset */
    2441       56158 :                            copyObject(item1),
    2442       56158 :                            copyObject(item2),
    2443             :                            InvalidOid,
    2444             :                            collation);
    2445             : 
    2446             :     /*
    2447             :      * Build the RestrictInfo node itself.
    2448             :      */
    2449       56158 :     restrictinfo = make_restrictinfo(root,
    2450             :                                      clause,
    2451             :                                      true,  /* is_pushed_down */
    2452             :                                      false, /* outerjoin_delayed */
    2453             :                                      false, /* pseudoconstant */
    2454             :                                      security_level,    /* security_level */
    2455             :                                      qualscope, /* required_relids */
    2456             :                                      NULL,  /* outer_relids */
    2457             :                                      nullable_relids);  /* nullable_relids */
    2458             : 
    2459             :     /* Set mergejoinability/hashjoinability flags */
    2460       56158 :     check_mergejoinable(restrictinfo);
    2461       56158 :     check_hashjoinable(restrictinfo);
    2462       56158 :     check_resultcacheable(restrictinfo);
    2463             : 
    2464       56158 :     return restrictinfo;
    2465             : }
    2466             : 
    2467             : 
    2468             : /*
    2469             :  * match_foreign_keys_to_quals
    2470             :  *      Match foreign-key constraints to equivalence classes and join quals
    2471             :  *
    2472             :  * The idea here is to see which query join conditions match equality
    2473             :  * constraints of a foreign-key relationship.  For such join conditions,
    2474             :  * we can use the FK semantics to make selectivity estimates that are more
    2475             :  * reliable than estimating from statistics, especially for multiple-column
    2476             :  * FKs, where the normal assumption of independent conditions tends to fail.
    2477             :  *
    2478             :  * In this function we annotate the ForeignKeyOptInfos in root->fkey_list
    2479             :  * with info about which eclasses and join qual clauses they match, and
    2480             :  * discard any ForeignKeyOptInfos that are irrelevant for the query.
    2481             :  */
    2482             : void
    2483      226358 : match_foreign_keys_to_quals(PlannerInfo *root)
    2484             : {
    2485      226358 :     List       *newlist = NIL;
    2486             :     ListCell   *lc;
    2487             : 
    2488      227576 :     foreach(lc, root->fkey_list)
    2489             :     {
    2490        1218 :         ForeignKeyOptInfo *fkinfo = (ForeignKeyOptInfo *) lfirst(lc);
    2491             :         RelOptInfo *con_rel;
    2492             :         RelOptInfo *ref_rel;
    2493             :         int         colno;
    2494             : 
    2495             :         /*
    2496             :          * Either relid might identify a rel that is in the query's rtable but
    2497             :          * isn't referenced by the jointree so won't have a RelOptInfo.  Hence
    2498             :          * don't use find_base_rel() here.  We can ignore such FKs.
    2499             :          */
    2500        1218 :         if (fkinfo->con_relid >= root->simple_rel_array_size ||
    2501        1218 :             fkinfo->ref_relid >= root->simple_rel_array_size)
    2502           0 :             continue;           /* just paranoia */
    2503        1218 :         con_rel = root->simple_rel_array[fkinfo->con_relid];
    2504        1218 :         if (con_rel == NULL)
    2505           0 :             continue;
    2506        1218 :         ref_rel = root->simple_rel_array[fkinfo->ref_relid];
    2507        1218 :         if (ref_rel == NULL)
    2508          16 :             continue;
    2509             : 
    2510             :         /*
    2511             :          * Ignore FK unless both rels are baserels.  This gets rid of FKs that
    2512             :          * link to inheritance child rels (otherrels) and those that link to
    2513             :          * rels removed by join removal (dead rels).
    2514             :          */
    2515        1202 :         if (con_rel->reloptkind != RELOPT_BASEREL ||
    2516        1202 :             ref_rel->reloptkind != RELOPT_BASEREL)
    2517           0 :             continue;
    2518             : 
    2519             :         /*
    2520             :          * Scan the columns and try to match them to eclasses and quals.
    2521             :          *
    2522             :          * Note: for simple inner joins, any match should be in an eclass.
    2523             :          * "Loose" quals that syntactically match an FK equality must have
    2524             :          * been rejected for EC status because they are outer-join quals or
    2525             :          * similar.  We can still consider them to match the FK if they are
    2526             :          * not outerjoin_delayed.
    2527             :          */
    2528        2724 :         for (colno = 0; colno < fkinfo->nkeys; colno++)
    2529             :         {
    2530             :             EquivalenceClass *ec;
    2531             :             AttrNumber  con_attno,
    2532             :                         ref_attno;
    2533             :             Oid         fpeqop;
    2534             :             ListCell   *lc2;
    2535             : 
    2536        1522 :             ec = match_eclasses_to_foreign_key_col(root, fkinfo, colno);
    2537             :             /* Don't bother looking for loose quals if we got an EC match */
    2538        1522 :             if (ec != NULL)
    2539             :             {
    2540         252 :                 fkinfo->nmatched_ec++;
    2541         252 :                 if (ec->ec_has_const)
    2542          66 :                     fkinfo->nconst_ec++;
    2543         252 :                 continue;
    2544             :             }
    2545             : 
    2546             :             /*
    2547             :              * Scan joininfo list for relevant clauses.  Either rel's joininfo
    2548             :              * list would do equally well; we use con_rel's.
    2549             :              */
    2550        1270 :             con_attno = fkinfo->conkey[colno];
    2551        1270 :             ref_attno = fkinfo->confkey[colno];
    2552        1270 :             fpeqop = InvalidOid;    /* we'll look this up only if needed */
    2553             : 
    2554        3232 :             foreach(lc2, con_rel->joininfo)
    2555             :             {
    2556        1962 :                 RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc2);
    2557        1962 :                 OpExpr     *clause = (OpExpr *) rinfo->clause;
    2558             :                 Var        *leftvar;
    2559             :                 Var        *rightvar;
    2560             : 
    2561             :                 /* Ignore outerjoin-delayed clauses */
    2562        1962 :                 if (rinfo->outerjoin_delayed)
    2563           4 :                     continue;
    2564             : 
    2565             :                 /* Only binary OpExprs are useful for consideration */
    2566        3916 :                 if (!IsA(clause, OpExpr) ||
    2567        1958 :                     list_length(clause->args) != 2)
    2568           0 :                     continue;
    2569        1958 :                 leftvar = (Var *) get_leftop((Expr *) clause);
    2570        1958 :                 rightvar = (Var *) get_rightop((Expr *) clause);
    2571             : 
    2572             :                 /* Operands must be Vars, possibly with RelabelType */
    2573        2122 :                 while (leftvar && IsA(leftvar, RelabelType))
    2574         164 :                     leftvar = (Var *) ((RelabelType *) leftvar)->arg;
    2575        1958 :                 if (!(leftvar && IsA(leftvar, Var)))
    2576           0 :                     continue;
    2577        2110 :                 while (rightvar && IsA(rightvar, RelabelType))
    2578         152 :                     rightvar = (Var *) ((RelabelType *) rightvar)->arg;
    2579        1958 :                 if (!(rightvar && IsA(rightvar, Var)))
    2580          20 :                     continue;
    2581             : 
    2582             :                 /* Now try to match the vars to the current foreign key cols */
    2583        1938 :                 if (fkinfo->ref_relid == leftvar->varno &&
    2584        1858 :                     ref_attno == leftvar->varattno &&
    2585        1102 :                     fkinfo->con_relid == rightvar->varno &&
    2586        1102 :                     con_attno == rightvar->varattno)
    2587             :                 {
    2588             :                     /* Vars match, but is it the right operator? */
    2589        2100 :                     if (clause->opno == fkinfo->conpfeqop[colno])
    2590             :                     {
    2591        1050 :                         fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
    2592             :                                                         rinfo);
    2593        1050 :                         fkinfo->nmatched_ri++;
    2594             :                     }
    2595             :                 }
    2596         888 :                 else if (fkinfo->ref_relid == rightvar->varno &&
    2597          56 :                          ref_attno == rightvar->varattno &&
    2598          20 :                          fkinfo->con_relid == leftvar->varno &&
    2599          20 :                          con_attno == leftvar->varattno)
    2600             :                 {
    2601             :                     /*
    2602             :                      * Reverse match, must check commutator operator.  Look it
    2603             :                      * up if we didn't already.  (In the worst case we might
    2604             :                      * do multiple lookups here, but that would require an FK
    2605             :                      * equality operator without commutator, which is
    2606             :                      * unlikely.)
    2607             :                      */
    2608          20 :                     if (!OidIsValid(fpeqop))
    2609          20 :                         fpeqop = get_commutator(fkinfo->conpfeqop[colno]);
    2610          20 :                     if (clause->opno == fpeqop)
    2611             :                     {
    2612          20 :                         fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
    2613             :                                                         rinfo);
    2614          20 :                         fkinfo->nmatched_ri++;
    2615             :                     }
    2616             :                 }
    2617             :             }
    2618             :             /* If we found any matching loose quals, count col as matched */
    2619        1270 :             if (fkinfo->rinfos[colno])
    2620        1070 :                 fkinfo->nmatched_rcols++;
    2621             :         }
    2622             : 
    2623             :         /*
    2624             :          * Currently, we drop multicolumn FKs that aren't fully matched to the
    2625             :          * query.  Later we might figure out how to derive some sort of
    2626             :          * estimate from them, in which case this test should be weakened to
    2627             :          * "if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) > 0)".
    2628             :          */
    2629        1202 :         if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) == fkinfo->nkeys)
    2630        1018 :             newlist = lappend(newlist, fkinfo);
    2631             :     }
    2632             :     /* Replace fkey_list, thereby discarding any useless entries */
    2633      226358 :     root->fkey_list = newlist;
    2634      226358 : }
    2635             : 
    2636             : 
    2637             : /*****************************************************************************
    2638             :  *
    2639             :  *   CHECKS FOR MERGEJOINABLE AND HASHJOINABLE CLAUSES
    2640             :  *
    2641             :  *****************************************************************************/
    2642             : 
    2643             : /*
    2644             :  * check_mergejoinable
    2645             :  *    If the restrictinfo's clause is mergejoinable, set the mergejoin
    2646             :  *    info fields in the restrictinfo.
    2647             :  *
    2648             :  *    Currently, we support mergejoin for binary opclauses where
    2649             :  *    the operator is a mergejoinable operator.  The arguments can be
    2650             :  *    anything --- as long as there are no volatile functions in them.
    2651             :  */
    2652             : static void
    2653      371624 : check_mergejoinable(RestrictInfo *restrictinfo)
    2654             : {
    2655      371624 :     Expr       *clause = restrictinfo->clause;
    2656             :     Oid         opno;
    2657             :     Node       *leftarg;
    2658             : 
    2659      371624 :     if (restrictinfo->pseudoconstant)
    2660        3286 :         return;
    2661      368338 :     if (!is_opclause(clause))
    2662       43164 :         return;
    2663      325174 :     if (list_length(((OpExpr *) clause)->args) != 2)
    2664          16 :         return;
    2665             : 
    2666      325158 :     opno = ((OpExpr *) clause)->opno;
    2667      325158 :     leftarg = linitial(((OpExpr *) clause)->args);
    2668             : 
    2669      325158 :     if (op_mergejoinable(opno, exprType(leftarg)) &&
    2670      277464 :         !contain_volatile_functions((Node *) restrictinfo))
    2671      277458 :         restrictinfo->mergeopfamilies = get_mergejoin_opfamilies(opno);
    2672             : 
    2673             :     /*
    2674             :      * Note: op_mergejoinable is just a hint; if we fail to find the operator
    2675             :      * in any btree opfamilies, mergeopfamilies remains NIL and so the clause
    2676             :      * is not treated as mergejoinable.
    2677             :      */
    2678             : }
    2679             : 
    2680             : /*
    2681             :  * check_hashjoinable
    2682             :  *    If the restrictinfo's clause is hashjoinable, set the hashjoin
    2683             :  *    info fields in the restrictinfo.
    2684             :  *
    2685             :  *    Currently, we support hashjoin for binary opclauses where
    2686             :  *    the operator is a hashjoinable operator.  The arguments can be
    2687             :  *    anything --- as long as there are no volatile functions in them.
    2688             :  */
    2689             : static void
    2690      113476 : check_hashjoinable(RestrictInfo *restrictinfo)
    2691             : {
    2692      113476 :     Expr       *clause = restrictinfo->clause;
    2693             :     Oid         opno;
    2694             :     Node       *leftarg;
    2695             : 
    2696      113476 :     if (restrictinfo->pseudoconstant)
    2697         126 :         return;
    2698      113350 :     if (!is_opclause(clause))
    2699        4042 :         return;
    2700      109308 :     if (list_length(((OpExpr *) clause)->args) != 2)
    2701           0 :         return;
    2702             : 
    2703      109308 :     opno = ((OpExpr *) clause)->opno;
    2704      109308 :     leftarg = linitial(((OpExpr *) clause)->args);
    2705             : 
    2706      109308 :     if (op_hashjoinable(opno, exprType(leftarg)) &&
    2707      107598 :         !contain_volatile_functions((Node *) restrictinfo))
    2708      107592 :         restrictinfo->hashjoinoperator = opno;
    2709             : }
    2710             : 
    2711             : /*
    2712             :  * check_resultcacheable
    2713             :  *    If the restrictinfo's clause is suitable to be used for a Result Cache
    2714             :  *    node, set the hasheqoperator to the hash equality operator that will be
    2715             :  *    needed during caching.
    2716             :  */
    2717             : static void
    2718      113476 : check_resultcacheable(RestrictInfo *restrictinfo)
    2719             : {
    2720             :     TypeCacheEntry *typentry;
    2721      113476 :     Expr       *clause = restrictinfo->clause;
    2722             :     Node       *leftarg;
    2723             : 
    2724      113476 :     if (restrictinfo->pseudoconstant)
    2725         126 :         return;
    2726      113350 :     if (!is_opclause(clause))
    2727        4042 :         return;
    2728      109308 :     if (list_length(((OpExpr *) clause)->args) != 2)
    2729           0 :         return;
    2730             : 
    2731      109308 :     leftarg = linitial(((OpExpr *) clause)->args);
    2732             : 
    2733      109308 :     typentry = lookup_type_cache(exprType(leftarg), TYPECACHE_HASH_PROC |
    2734             :                                  TYPECACHE_EQ_OPR);
    2735             : 
    2736      109308 :     if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr))
    2737         276 :         return;
    2738             : 
    2739      109032 :     restrictinfo->hasheqoperator = typentry->eq_opr;
    2740             : }

Generated by: LCOV version 1.13