LCOV - code coverage report
Current view: top level - src/backend/optimizer/plan - initsplan.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 95.8 % 1192 1142
Test Date: 2026-07-11 18:15:35 Functions: 100.0 % 38 38
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 84.4 % 925 781

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

Generated by: LCOV version 2.0-1