LCOV - differential code coverage report
Current view: top level - src/backend/optimizer/util - restrictinfo.c (source / functions) Coverage Total Hit GIC GNC CBC ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 182 182 94 34 54 114 14
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 13 13 10 3 12
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 34 34 34 1
Legend: Lines: hit not hit (240..) days: 100.0 % 148 148 94 54 98
Function coverage date bins:
(60,120] days: 100.0 % 2 2 2
(240..) days: 50.0 % 22 11 10 1 11

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * restrictinfo.c
                                  4                 :  *    RestrictInfo node manipulation routines.
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/optimizer/util/restrictinfo.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include "nodes/makefuncs.h"
                                 18                 : #include "nodes/nodeFuncs.h"
                                 19                 : #include "optimizer/clauses.h"
                                 20                 : #include "optimizer/optimizer.h"
                                 21                 : #include "optimizer/restrictinfo.h"
                                 22                 : 
                                 23                 : 
                                 24                 : static RestrictInfo *make_restrictinfo_internal(PlannerInfo *root,
                                 25                 :                                                 Expr *clause,
                                 26                 :                                                 Expr *orclause,
                                 27                 :                                                 bool is_pushed_down,
                                 28                 :                                                 bool pseudoconstant,
                                 29                 :                                                 Index security_level,
                                 30                 :                                                 Relids required_relids,
                                 31                 :                                                 Relids outer_relids);
                                 32                 : static Expr *make_sub_restrictinfos(PlannerInfo *root,
                                 33                 :                                     Expr *clause,
                                 34                 :                                     bool is_pushed_down,
                                 35                 :                                     bool pseudoconstant,
                                 36                 :                                     Index security_level,
                                 37                 :                                     Relids required_relids,
                                 38                 :                                     Relids outer_relids);
                                 39                 : 
                                 40                 : 
                                 41                 : /*
                                 42                 :  * make_restrictinfo
                                 43                 :  *
                                 44                 :  * Build a RestrictInfo node containing the given subexpression.
                                 45                 :  *
                                 46                 :  * The is_pushed_down and pseudoconstant flags for the
                                 47                 :  * RestrictInfo must be supplied by the caller, as well as the correct values
                                 48                 :  * for security_level and outer_relids.
                                 49                 :  * required_relids can be NULL, in which case it defaults to the actual clause
                                 50                 :  * contents (i.e., clause_relids).
                                 51                 :  *
                                 52                 :  * Note that there aren't options to set the has_clone and is_clone flags:
                                 53                 :  * we always initialize those to false.  There's just one place that wants
                                 54                 :  * something different, so making all callers pass them seems inconvenient.
                                 55                 :  *
                                 56                 :  * We initialize fields that depend only on the given subexpression, leaving
                                 57                 :  * others that depend on context (or may never be needed at all) to be filled
                                 58                 :  * later.
                                 59                 :  */
                                 60                 : RestrictInfo *
  808 tgl                        61 CBC      250946 : make_restrictinfo(PlannerInfo *root,
                                 62                 :                   Expr *clause,
                                 63                 :                   bool is_pushed_down,
                                 64                 :                   bool pseudoconstant,
                                 65                 :                   Index security_level,
                                 66                 :                   Relids required_relids,
                                 67                 :                   Relids outer_relids)
                                 68                 : {
                                 69                 :     /*
                                 70                 :      * If it's an OR clause, build a modified copy with RestrictInfos inserted
 6385 bruce                      71 ECB             :      * above each subclause of the top-level AND/OR structure.
 7034 tgl                        72                 :      */
 1531 tgl                        73 GIC      250946 :     if (is_orclause(clause))
  808                            74            3475 :         return (RestrictInfo *) make_sub_restrictinfos(root,
                                 75                 :                                                        clause,
                                 76                 :                                                        is_pushed_down,
                                 77                 :                                                        pseudoconstant,
                                 78                 :                                                        security_level,
                                 79                 :                                                        required_relids,
                                 80                 :                                                        outer_relids);
 7034 tgl                        81 ECB             : 
                                 82                 :     /* Shouldn't be an AND clause, else AND/OR flattening messed up */
 1531 tgl                        83 GIC      247471 :     Assert(!is_andclause(clause));
                                 84                 : 
  808                            85          247471 :     return make_restrictinfo_internal(root,
                                 86                 :                                       clause,
                                 87                 :                                       NULL,
                                 88                 :                                       is_pushed_down,
                                 89                 :                                       pseudoconstant,
                                 90                 :                                       security_level,
                                 91                 :                                       required_relids,
                                 92                 :                                       outer_relids);
                                 93                 : }
                                 94                 : 
 7034 tgl                        95 ECB             : /*
                                 96                 :  * make_restrictinfo_internal
                                 97                 :  *
                                 98                 :  * Common code for the main entry points and the recursive cases.
                                 99                 :  */
                                100                 : static RestrictInfo *
  808 tgl                       101 GIC      260725 : make_restrictinfo_internal(PlannerInfo *root,
                                102                 :                            Expr *clause,
                                103                 :                            Expr *orclause,
 6126 tgl                       104 ECB             :                            bool is_pushed_down,
                                105                 :                            bool pseudoconstant,
 2272                           106                 :                            Index security_level,
 5106                           107                 :                            Relids required_relids,
                                108                 :                            Relids outer_relids)
 7035                           109                 : {
 7035 tgl                       110 CBC      260725 :     RestrictInfo *restrictinfo = makeNode(RestrictInfo);
                                111                 :     Relids      baserels;
 7035 tgl                       112 ECB             : 
 7035 tgl                       113 CBC      260725 :     restrictinfo->clause = clause;
 7034                           114          260725 :     restrictinfo->orclause = orclause;
 7034 tgl                       115 GIC      260725 :     restrictinfo->is_pushed_down = is_pushed_down;
 6126                           116          260725 :     restrictinfo->pseudoconstant = pseudoconstant;
   69 tgl                       117 GNC      260725 :     restrictinfo->has_clone = false; /* may get set by caller */
                                118          260725 :     restrictinfo->is_clone = false; /* may get set by caller */
 2118 tgl                       119 GIC      260725 :     restrictinfo->can_join = false; /* may get set below */
 2272                           120          260725 :     restrictinfo->security_level = security_level;
 4007                           121          260725 :     restrictinfo->outer_relids = outer_relids;
 7035 tgl                       122 ECB             : 
                                123                 :     /*
 2272                           124                 :      * If it's potentially delayable by lower-level security quals, figure out
                                125                 :      * whether it's leakproof.  We can skip testing this for level-zero quals,
                                126                 :      * since they would never get delayed on security grounds anyway.
                                127                 :      */
 2272 tgl                       128 GIC      260725 :     if (security_level > 0)
                                129            2026 :         restrictinfo->leakproof = !contain_leaked_vars((Node *) clause);
                                130                 :     else
 2118 tgl                       131 CBC      258699 :         restrictinfo->leakproof = false; /* really, "don't know" */
                                132                 : 
                                133                 :     /*
                                134                 :      * Mark volatility as unknown.  The contain_volatile_functions function
                                135                 :      * will determine if there are any volatile functions when called for the
                                136                 :      * first time with this RestrictInfo.
  741 drowley                   137 ECB             :      */
  741 drowley                   138 GIC      260725 :     restrictinfo->has_volatile = VOLATILITY_UNKNOWN;
  741 drowley                   139 ECB             : 
 7035 tgl                       140                 :     /*
                                141                 :      * If it's a binary opclause, set up left/right relids info. In any case
 6385 bruce                     142                 :      * set up the total clause relids info.
 7035 tgl                       143                 :      */
 6888 neilc                     144 GIC      260725 :     if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
                                145                 :     {
  808 tgl                       146          216494 :         restrictinfo->left_relids = pull_varnos(root, get_leftop(clause));
                                147          216494 :         restrictinfo->right_relids = pull_varnos(root, get_rightop(clause));
                                148                 : 
 7035                           149          432988 :         restrictinfo->clause_relids = bms_union(restrictinfo->left_relids,
 6385 bruce                     150          216494 :                                                 restrictinfo->right_relids);
 7035 tgl                       151 ECB             : 
                                152                 :         /*
                                153                 :          * Does it look like a normal join clause, i.e., a binary operator
 6385 bruce                     154                 :          * relating expressions that come from distinct relations? If so we
                                155                 :          * might be able to use it in a join algorithm.  Note that this is a
                                156                 :          * purely syntactic test that is made regardless of context.
                                157                 :          */
 7035 tgl                       158 CBC      216494 :         if (!bms_is_empty(restrictinfo->left_relids) &&
 7035 tgl                       159 GIC      212677 :             !bms_is_empty(restrictinfo->right_relids) &&
                                160           75853 :             !bms_overlap(restrictinfo->left_relids,
                                161           75853 :                          restrictinfo->right_relids))
                                162                 :         {
 7034                           163           75064 :             restrictinfo->can_join = true;
 6126 tgl                       164 ECB             :             /* pseudoconstant should certainly not be true */
 6126 tgl                       165 CBC       75064 :             Assert(!restrictinfo->pseudoconstant);
                                166                 :         }
 7035 tgl                       167 ECB             :     }
                                168                 :     else
                                169                 :     {
                                170                 :         /* Not a binary opclause, so mark left/right relid sets as empty */
 7035 tgl                       171 CBC       44231 :         restrictinfo->left_relids = NULL;
                                172           44231 :         restrictinfo->right_relids = NULL;
                                173                 :         /* and get the total relid set the hard way */
  808                           174           44231 :         restrictinfo->clause_relids = pull_varnos(root, (Node *) clause);
                                175                 :     }
                                176                 : 
                                177                 :     /* required_relids defaults to clause_relids */
 6513 tgl                       178 GIC      260725 :     if (required_relids != NULL)
                                179          234403 :         restrictinfo->required_relids = required_relids;
                                180                 :     else
                                181           26322 :         restrictinfo->required_relids = restrictinfo->clause_relids;
                                182                 : 
                                183                 :     /*
                                184                 :      * Count the number of base rels appearing in clause_relids.  To do this,
                                185                 :      * we just delete rels mentioned in root->outer_join_rels and count the
                                186                 :      * survivors.  Because we are called during deconstruct_jointree which is
                                187                 :      * the same tree walk that populates outer_join_rels, this is a little bit
                                188                 :      * unsafe-looking; but it should be fine because the recursion in
                                189                 :      * deconstruct_jointree should already have visited any outer join that
                                190                 :      * could be mentioned in this clause.
                                191                 :      */
   69 tgl                       192 GNC      260725 :     baserels = bms_difference(restrictinfo->clause_relids,
                                193          260725 :                               root->outer_join_rels);
                                194          260725 :     restrictinfo->num_base_rels = bms_num_members(baserels);
                                195          260725 :     bms_free(baserels);
                                196                 : 
                                197                 :     /*
                                198                 :      * Label this RestrictInfo with a fresh serial number.
                                199                 :      */
                                200          260725 :     restrictinfo->rinfo_serial = ++(root->last_rinfo_serial);
                                201                 : 
                                202                 :     /*
                                203                 :      * Fill in all the cacheable fields with "not yet set" markers. None of
 3260 bruce                     204 ECB             :      * these will be computed until/unless needed.  Note in particular that we
 6385                           205                 :      * don't mark a binary opclause as mergejoinable or hashjoinable here;
                                206                 :      * that happens only if it appears in the right context (top level of a
                                207                 :      * joinclause list).
                                208                 :      */
 5923 tgl                       209 GIC      260725 :     restrictinfo->parent_ec = NULL;
                                210                 : 
 7035                           211          260725 :     restrictinfo->eval_cost.startup = -1;
 5175 tgl                       212 CBC      260725 :     restrictinfo->norm_selec = -1;
 5175 tgl                       213 GIC      260725 :     restrictinfo->outer_selec = -1;
                                214                 : 
 5923                           215          260725 :     restrictinfo->mergeopfamilies = NIL;
                                216                 : 
                                217          260725 :     restrictinfo->left_ec = NULL;
                                218          260725 :     restrictinfo->right_ec = NULL;
 5921                           219          260725 :     restrictinfo->left_em = NULL;
                                220          260725 :     restrictinfo->right_em = NULL;
 5921 tgl                       221 CBC      260725 :     restrictinfo->scansel_cache = NIL;
                                222                 : 
 5923                           223          260725 :     restrictinfo->outer_is_left = false;
 7035 tgl                       224 ECB             : 
 7035 tgl                       225 CBC      260725 :     restrictinfo->hashjoinoperator = InvalidOid;
                                226                 : 
                                227          260725 :     restrictinfo->left_bucketsize = -1;
 7035 tgl                       228 GIC      260725 :     restrictinfo->right_bucketsize = -1;
 2063 tgl                       229 CBC      260725 :     restrictinfo->left_mcvfreq = -1;
                                230          260725 :     restrictinfo->right_mcvfreq = -1;
 7035 tgl                       231 ECB             : 
  517 drowley                   232 CBC      260725 :     restrictinfo->left_hasheqoperator = InvalidOid;
                                233          260725 :     restrictinfo->right_hasheqoperator = InvalidOid;
                                234                 : 
 7035 tgl                       235          260725 :     return restrictinfo;
                                236                 : }
 7035 tgl                       237 ECB             : 
                                238                 : /*
                                239                 :  * Recursively insert sub-RestrictInfo nodes into a boolean expression.
 6561                           240                 :  *
                                241                 :  * We put RestrictInfos above simple (non-AND/OR) clauses and above
                                242                 :  * sub-OR clauses, but not above sub-AND clauses, because there's no need.
                                243                 :  * This may seem odd but it is closely related to the fact that we use
                                244                 :  * implicit-AND lists at top level of RestrictInfo lists.  Only ORs and
                                245                 :  * simple clauses are valid RestrictInfos.
                                246                 :  *
                                247                 :  * The same is_pushed_down and pseudoconstant flag
                                248                 :  * values can be applied to all RestrictInfo nodes in the result.  Likewise
                                249                 :  * for security_level and outer_relids.
                                250                 :  *
                                251                 :  * The given required_relids are attached to our top-level output,
                                252                 :  * but any OR-clause constituents are allowed to default to just the
                                253                 :  * contained rels.
                                254                 :  */
                                255                 : static Expr *
  808 tgl                       256 GIC       14536 : make_sub_restrictinfos(PlannerInfo *root,
                                257                 :                        Expr *clause,
                                258                 :                        bool is_pushed_down,
                                259                 :                        bool pseudoconstant,
                                260                 :                        Index security_level,
                                261                 :                        Relids required_relids,
                                262                 :                        Relids outer_relids)
                                263                 : {
 1531                           264           14536 :     if (is_orclause(clause))
                                265                 :     {
 7035 tgl                       266 CBC        3514 :         List       *orlist = NIL;
                                267                 :         ListCell   *temp;
                                268                 : 
 7035 tgl                       269 GIC       11821 :         foreach(temp, ((BoolExpr *) clause)->args)
                                270            8307 :             orlist = lappend(orlist,
  808                           271            8307 :                              make_sub_restrictinfos(root,
                                272            8307 :                                                     lfirst(temp),
                                273                 :                                                     is_pushed_down,
                                274                 :                                                     pseudoconstant,
 2272 tgl                       275 ECB             :                                                     security_level,
                                276                 :                                                     NULL,
                                277                 :                                                     outer_relids));
  808 tgl                       278 CBC        3514 :         return (Expr *) make_restrictinfo_internal(root,
  808 tgl                       279 ECB             :                                                    clause,
 6561                           280                 :                                                    make_orclause(orlist),
                                281                 :                                                    is_pushed_down,
                                282                 :                                                    pseudoconstant,
                                283                 :                                                    security_level,
                                284                 :                                                    required_relids,
                                285                 :                                                    outer_relids);
                                286                 :     }
 1531 tgl                       287 GIC       11022 :     else if (is_andclause(clause))
                                288                 :     {
 7035                           289            1282 :         List       *andlist = NIL;
                                290                 :         ListCell   *temp;
                                291                 : 
                                292            4036 :         foreach(temp, ((BoolExpr *) clause)->args)
 7035 tgl                       293 CBC        2754 :             andlist = lappend(andlist,
  808 tgl                       294 GIC        2754 :                               make_sub_restrictinfos(root,
  808 tgl                       295 CBC        2754 :                                                      lfirst(temp),
                                296                 :                                                      is_pushed_down,
 6126 tgl                       297 ECB             :                                                      pseudoconstant,
 2272                           298                 :                                                      security_level,
 5106                           299                 :                                                      required_relids,
                                300                 :                                                      outer_relids));
 7035 tgl                       301 GIC        1282 :         return make_andclause(andlist);
                                302                 :     }
                                303                 :     else
  808                           304            9740 :         return (Expr *) make_restrictinfo_internal(root,
  808 tgl                       305 ECB             :                                                    clause,
                                306                 :                                                    NULL,
                                307                 :                                                    is_pushed_down,
                                308                 :                                                    pseudoconstant,
                                309                 :                                                    security_level,
                                310                 :                                                    required_relids,
                                311                 :                                                    outer_relids);
                                312                 : }
                                313                 : 
                                314                 : /*
                                315                 :  * commute_restrictinfo
                                316                 :  *
                                317                 :  * Given a RestrictInfo containing a binary opclause, produce a RestrictInfo
                                318                 :  * representing the commutation of that clause.  The caller must pass the
                                319                 :  * OID of the commutator operator (which it's presumably looked up, else
                                320                 :  * it would not know this is valid).
                                321                 :  *
                                322                 :  * Beware that the result shares sub-structure with the given RestrictInfo.
                                323                 :  * That's okay for the intended usage with derived index quals, but might
                                324                 :  * be hazardous if the source is subject to change.  Also notice that we
                                325                 :  * assume without checking that the commutator op is a member of the same
                                326                 :  * btree and hash opclasses as the original op.
                                327                 :  */
                                328                 : RestrictInfo *
 1520 tgl                       329 GIC       23039 : commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op)
                                330                 : {
 1520 tgl                       331 ECB             :     RestrictInfo *result;
                                332                 :     OpExpr     *newclause;
 1520 tgl                       333 GIC       23039 :     OpExpr     *clause = castNode(OpExpr, rinfo->clause);
                                334                 : 
 1520 tgl                       335 CBC       23039 :     Assert(list_length(clause->args) == 2);
                                336                 : 
 1520 tgl                       337 ECB             :     /* flat-copy all the fields of clause ... */
 1520 tgl                       338 GIC       23039 :     newclause = makeNode(OpExpr);
                                339           23039 :     memcpy(newclause, clause, sizeof(OpExpr));
 1520 tgl                       340 ECB             : 
                                341                 :     /* ... and adjust those we need to change to commute it */
 1520 tgl                       342 GIC       23039 :     newclause->opno = comm_op;
                                343           23039 :     newclause->opfuncid = InvalidOid;
 1520 tgl                       344 CBC       23039 :     newclause->args = list_make2(lsecond(clause->args),
 1520 tgl                       345 ECB             :                                  linitial(clause->args));
                                346                 : 
                                347                 :     /* likewise, flat-copy all the fields of rinfo ... */
 1520 tgl                       348 GIC       23039 :     result = makeNode(RestrictInfo);
                                349           23039 :     memcpy(result, rinfo, sizeof(RestrictInfo));
 1520 tgl                       350 ECB             : 
                                351                 :     /*
                                352                 :      * ... and adjust those we need to change.  Note in particular that we can
                                353                 :      * preserve any cached selectivity or cost estimates, since those ought to
                                354                 :      * be the same for the new clause.  Likewise we can keep the source's
                                355                 :      * parent_ec.  It's also important that we keep the same rinfo_serial.
                                356                 :      */
 1520 tgl                       357 GIC       23039 :     result->clause = (Expr *) newclause;
                                358           23039 :     result->left_relids = rinfo->right_relids;
 1520 tgl                       359 CBC       23039 :     result->right_relids = rinfo->left_relids;
                                360           23039 :     Assert(result->orclause == NULL);
                                361           23039 :     result->left_ec = rinfo->right_ec;
                                362           23039 :     result->right_ec = rinfo->left_ec;
                                363           23039 :     result->left_em = rinfo->right_em;
                                364           23039 :     result->right_em = rinfo->left_em;
                                365           23039 :     result->scansel_cache = NIL; /* not worth updating this */
                                366           23039 :     if (rinfo->hashjoinoperator == clause->opno)
                                367           22537 :         result->hashjoinoperator = comm_op;
 1520 tgl                       368 ECB             :     else
 1520 tgl                       369 CBC         502 :         result->hashjoinoperator = InvalidOid;
 1520 tgl                       370 GIC       23039 :     result->left_bucketsize = rinfo->right_bucketsize;
 1520 tgl                       371 CBC       23039 :     result->right_bucketsize = rinfo->left_bucketsize;
                                372           23039 :     result->left_mcvfreq = rinfo->right_mcvfreq;
                                373           23039 :     result->right_mcvfreq = rinfo->left_mcvfreq;
  517 drowley                   374           23039 :     result->left_hasheqoperator = InvalidOid;
                                375           23039 :     result->right_hasheqoperator = InvalidOid;
 1520 tgl                       376 ECB             : 
 1520 tgl                       377 CBC       23039 :     return result;
                                378                 : }
 1520 tgl                       379 ECB             : 
                                380                 : /*
                                381                 :  * restriction_is_or_clause
                                382                 :  *
                                383                 :  * Returns t iff the restrictinfo node contains an 'or' clause.
                                384                 :  */
                                385                 : bool
 8660 tgl                       386 GIC      386446 : restriction_is_or_clause(RestrictInfo *restrictinfo)
                                387                 : {
 7035 tgl                       388 CBC      386446 :     if (restrictinfo->orclause != NULL)
 8986 bruce                     389 GIC       14268 :         return true;
 9345 bruce                     390 ECB             :     else
 8986 bruce                     391 CBC      372178 :         return false;
                                392                 : }
 9770 scrappy                   393 ECB             : 
                                394                 : /*
                                395                 :  * restriction_is_securely_promotable
                                396                 :  *
                                397                 :  * Returns true if it's okay to evaluate this clause "early", that is before
                                398                 :  * other restriction clauses attached to the specified relation.
                                399                 :  */
                                400                 : bool
 2272 tgl                       401 GIC      569087 : restriction_is_securely_promotable(RestrictInfo *restrictinfo,
                                402                 :                                    RelOptInfo *rel)
 9770 scrappy                   403 ECB             : {
                                404                 :     /*
                                405                 :      * It's okay if there are no baserestrictinfo clauses for the rel that
                                406                 :      * would need to go before this one, *or* if this one is leakproof.
                                407                 :      */
 2272 tgl                       408 GIC      569087 :     if (restrictinfo->security_level <= rel->baserestrict_min_security ||
                                409            2095 :         restrictinfo->leakproof)
 2272 tgl                       410 CBC      568036 :         return true;
 2272 tgl                       411 ECB             :     else
 2272 tgl                       412 CBC        1051 :         return false;
                                413                 : }
 8244 tgl                       414 ECB             : 
                                415                 : /*
                                416                 :  * Detect whether a RestrictInfo's clause is constant TRUE (note that it's
                                417                 :  * surely of type boolean).  No such WHERE clause could survive qual
                                418                 :  * canonicalization, but equivclass.c may generate such RestrictInfos for
                                419                 :  * reasons discussed therein.  We should drop them again when creating
                                420                 :  * the finished plan, which is handled by the next few functions.
                                421                 :  */
                                422                 : static inline bool
   69 tgl                       423 GNC      157289 : rinfo_is_constant_true(RestrictInfo *rinfo)
                                424                 : {
                                425          158035 :     return IsA(rinfo->clause, Const) &&
                                426          158008 :         !((Const *) rinfo->clause)->constisnull &&
                                427             719 :         DatumGetBool(((Const *) rinfo->clause)->constvalue);
                                428                 : }
                                429                 : 
                                430                 : /*
                                431                 :  * get_actual_clauses
                                432                 :  *
                                433                 :  * Returns a list containing the bare clauses from 'restrictinfo_list'.
                                434                 :  *
                                435                 :  * This is only to be used in cases where none of the RestrictInfos can
                                436                 :  * be pseudoconstant clauses (for instance, it's OK on indexqual lists).
                                437                 :  */
                                438                 : List *
 2272 tgl                       439 GIC       27541 : get_actual_clauses(List *restrictinfo_list)
 5025 tgl                       440 ECB             : {
 5025 tgl                       441 GIC       27541 :     List       *result = NIL;
 5025 tgl                       442 ECB             :     ListCell   *l;
                                443                 : 
 5025 tgl                       444 CBC       56547 :     foreach(l, restrictinfo_list)
                                445                 :     {
 2190 tgl                       446 GIC       29006 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
                                447                 : 
 2272                           448           29006 :         Assert(!rinfo->pseudoconstant);
   69 tgl                       449 GNC       29006 :         Assert(!rinfo_is_constant_true(rinfo));
                                450                 : 
 5025 tgl                       451 GIC       29006 :         result = lappend(result, rinfo->clause);
                                452                 :     }
                                453           27541 :     return result;
                                454                 : }
                                455                 : 
                                456                 : /*
 6126 tgl                       457 ECB             :  * extract_actual_clauses
                                458                 :  *
                                459                 :  * Extract bare clauses from 'restrictinfo_list', returning either the
                                460                 :  * regular ones or the pseudoconstant ones per 'pseudoconstant'.
                                461                 :  * Constant-TRUE clauses are dropped in any case.
                                462                 :  */
                                463                 : List *
 6126 tgl                       464 GIC      252629 : extract_actual_clauses(List *restrictinfo_list,
 6126 tgl                       465 ECB             :                        bool pseudoconstant)
                                466                 : {
 6126 tgl                       467 CBC      252629 :     List       *result = NIL;
 6126 tgl                       468 ECB             :     ListCell   *l;
                                469                 : 
 6126 tgl                       470 CBC      377522 :     foreach(l, restrictinfo_list)
                                471                 :     {
 2190                           472          124893 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
                                473                 : 
   69 tgl                       474 GNC      124893 :         if (rinfo->pseudoconstant == pseudoconstant &&
                                475          114408 :             !rinfo_is_constant_true(rinfo))
 6126 tgl                       476 GIC      114408 :             result = lappend(result, rinfo->clause);
                                477                 :     }
                                478          252629 :     return result;
                                479                 : }
                                480                 : 
                                481                 : /*
                                482                 :  * extract_actual_join_clauses
                                483                 :  *
 6126 tgl                       484 ECB             :  * Extract bare clauses from 'restrictinfo_list', separating those that
                                485                 :  * semantically match the join level from those that were pushed down.
                                486                 :  * Pseudoconstant and constant-TRUE clauses are excluded from the results.
                                487                 :  *
                                488                 :  * This is only used at outer joins, since for plain joins we don't care
                                489                 :  * about pushed-down-ness.
 8244                           490                 :  */
                                491                 : void
 6126 tgl                       492 CBC       16047 : extract_actual_join_clauses(List *restrictinfo_list,
                                493                 :                             Relids joinrelids,
 6126 tgl                       494 ECB             :                             List **joinquals,
                                495                 :                             List **otherquals)
 8244                           496                 : {
                                497                 :     ListCell   *l;
                                498                 : 
 8244 tgl                       499 GIC       16047 :     *joinquals = NIL;
                                500           16047 :     *otherquals = NIL;
                                501                 : 
 6126                           502           29925 :     foreach(l, restrictinfo_list)
                                503                 :     {
 2190                           504           13878 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
                                505                 : 
 1815                           506           13878 :         if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
                                507                 :         {
   69 tgl                       508 GNC        1874 :             if (!rinfo->pseudoconstant &&
                                509            1871 :                 !rinfo_is_constant_true(rinfo))
 6126 tgl                       510 GIC        1221 :                 *otherquals = lappend(*otherquals, rinfo->clause);
                                511                 :         }
                                512                 :         else
 6126 tgl                       513 ECB             :         {
                                514                 :             /* joinquals shouldn't have been marked pseudoconstant */
 6126 tgl                       515 GIC       12004 :             Assert(!rinfo->pseudoconstant);
   69 tgl                       516 GNC       12004 :             Assert(!rinfo_is_constant_true(rinfo));
 6126 tgl                       517 GIC       12004 :             *joinquals = lappend(*joinquals, rinfo->clause);
                                518                 :         }
                                519                 :     }
 8244                           520           16047 : }
 7441 tgl                       521 ECB             : 
                                522                 : /*
                                523                 :  * clause_is_computable_at
                                524                 :  *      Test whether a clause is computable at a given evaluation level.
                                525                 :  *
                                526                 :  * There are two conditions for whether an expression can actually be
                                527                 :  * evaluated at a given join level: the evaluation context must include
                                528                 :  * all the relids (both base and OJ) used by the expression, and we must
                                529                 :  * not have already evaluated any outer joins that null Vars/PHVs of the
                                530                 :  * expression and are not listed in their nullingrels.
                                531                 :  *
                                532                 :  * This function checks the second condition; we assume the caller already
                                533                 :  * saw to the first one.
                                534                 :  *
                                535                 :  * For speed reasons, we don't individually examine each Var/PHV of the
                                536                 :  * expression, but just look at the overall clause_relids (the union of the
                                537                 :  * varnos and varnullingrels).  This could give a misleading answer if the
                                538                 :  * Vars of a given varno don't all have the same varnullingrels; but that
                                539                 :  * really shouldn't happen within a single scalar expression or RestrictInfo
                                540                 :  * clause.  Despite that, this is still annoyingly expensive :-(
                                541                 :  */
                                542                 : bool
   69 tgl                       543 GNC      125738 : clause_is_computable_at(PlannerInfo *root,
                                544                 :                         Relids clause_relids,
                                545                 :                         Relids eval_relids)
                                546                 : {
                                547                 :     ListCell   *lc;
                                548                 : 
                                549                 :     /* Nothing to do if no outer joins have been performed yet. */
                                550          125738 :     if (!bms_overlap(eval_relids, root->outer_join_rels))
                                551           66602 :         return true;
                                552                 : 
                                553          202403 :     foreach(lc, root->join_info_list)
                                554                 :     {
                                555          149437 :         SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
                                556                 : 
                                557                 :         /* Ignore outer joins that are not yet performed. */
                                558          149437 :         if (!bms_is_member(sjinfo->ojrelid, eval_relids))
                                559           71872 :             continue;
                                560                 : 
                                561                 :         /* OK if clause lists it (we assume all Vars in it agree). */
                                562           77565 :         if (bms_is_member(sjinfo->ojrelid, clause_relids))
                                563            9853 :             continue;
                                564                 : 
                                565                 :         /* Else, trouble if clause mentions any nullable Vars. */
                                566           67712 :         if (bms_overlap(clause_relids, sjinfo->min_righthand) ||
                                567           61548 :             (sjinfo->jointype == JOIN_FULL &&
                                568               6 :              bms_overlap(clause_relids, sjinfo->min_lefthand)))
                                569            6170 :             return false;       /* doesn't work */
                                570                 :     }
                                571                 : 
                                572           52966 :     return true;                /* OK */
                                573                 : }
 5083 tgl                       574 ECB             : 
                                575                 : /*
 4007                           576                 :  * join_clause_is_movable_to
                                577                 :  *      Test whether a join clause is a safe candidate for parameterization
                                578                 :  *      of a scan on the specified base relation.
                                579                 :  *
                                580                 :  * A movable join clause is one that can safely be evaluated at a rel below
                                581                 :  * its normal semantic level (ie, its required_relids), if the values of
                                582                 :  * variables that it would need from other rels are provided.
                                583                 :  *
                                584                 :  * We insist that the clause actually reference the target relation; this
                                585                 :  * prevents undesirable movement of degenerate join clauses, and ensures
                                586                 :  * that there is a unique place that a clause can be moved down to.
                                587                 :  *
                                588                 :  * We cannot move an outer-join clause into the non-nullable side of its
                                589                 :  * outer join, as that would change the results (rows would be suppressed
                                590                 :  * rather than being null-extended).
                                591                 :  *
                                592                 :  * Also there must not be an outer join below the clause that would null the
                                593                 :  * Vars coming from the target relation.  Otherwise the clause might give
 2812                           594                 :  * results different from what it would give at its normal semantic level.
                                595                 :  *
                                596                 :  * Also, the join clause must not use any relations that have LATERAL
                                597                 :  * references to the target relation, since we could not put such rels on
                                598                 :  * the outer side of a nestloop with the target relation.
                                599                 :  *
                                600                 :  * Also, we reject is_clone versions of outer-join clauses.  This has the
                                601                 :  * effect of preventing us from generating variant parameterized paths
                                602                 :  * that differ only in which outer joins null the parameterization rel(s).
                                603                 :  * Generating one path from the minimally-parameterized has_clone version
                                604                 :  * is sufficient.
                                605                 :  */
                                606                 : bool
 3522 tgl                       607 GIC      103556 : join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel)
                                608                 : {
                                609                 :     /* Clause must physically reference target rel */
                                610          103556 :     if (!bms_is_member(baserel->relid, rinfo->clause_relids))
 4007                           611           15375 :         return false;
                                612                 : 
                                613                 :     /* Cannot move an outer-join clause into the join's outer side */
 3522                           614           88181 :     if (bms_is_member(baserel->relid, rinfo->outer_relids))
 4007                           615           39989 :         return false;
                                616                 : 
                                617                 :     /*
                                618                 :      * Target rel's Vars must not be nulled by any outer join.  We can check
                                619                 :      * this without groveling through the individual Vars by seeing whether
                                620                 :      * clause_relids (which includes all such Vars' varnullingrels) includes
                                621                 :      * any outer join that can null the target rel.  You might object that
                                622                 :      * this could reject the clause on the basis of an OJ relid that came from
                                623                 :      * some other rel's Var.  However, that would still mean that the clause
                                624                 :      * came from above that outer join and shouldn't be pushed down; so there
                                625                 :      * should be no false positives.
                                626                 :      */
   69 tgl                       627 GNC       48192 :     if (bms_overlap(rinfo->clause_relids, baserel->nulling_relids))
 3522 tgl                       628 GIC        2140 :         return false;
                                629                 : 
                                630                 :     /* Clause must not use any rels with LATERAL references to this rel */
                                631           46052 :     if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids))
 4007 tgl                       632 CBC           9 :         return false;
                                633                 : 
                                634                 :     /* Ignore clones, too */
   69 tgl                       635 GNC       46043 :     if (rinfo->is_clone)
                                636            4021 :         return false;
                                637                 : 
 4007 tgl                       638 GIC       42022 :     return true;
                                639                 : }
                                640                 : 
                                641                 : /*
                                642                 :  * join_clause_is_movable_into
 4007 tgl                       643 ECB             :  *      Test whether a join clause is movable and can be evaluated within
                                644                 :  *      the current join context.
                                645                 :  *
                                646                 :  * currentrelids: the relids of the proposed evaluation location
                                647                 :  * current_and_outer: the union of currentrelids and the required_outer
                                648                 :  *      relids (parameterization's outer relations)
                                649                 :  *
                                650                 :  * The API would be a bit clearer if we passed the current relids and the
                                651                 :  * outer relids separately and did bms_union internally; but since most
                                652                 :  * callers need to apply this function to multiple clauses, we make the
                                653                 :  * caller perform the union.
                                654                 :  *
                                655                 :  * Obviously, the clause must only refer to Vars available from the current
                                656                 :  * relation plus the outer rels.  We also check that it does reference at
                                657                 :  * least one current Var, ensuring that the clause will be pushed down to
                                658                 :  * a unique place in a parameterized join tree.  And we check that we're
                                659                 :  * not pushing the clause into its outer-join outer side.
   69                           660                 :  *
                                661                 :  * We used to need to check that we're not pushing the clause into a lower
                                662                 :  * outer join's inner side.  However, now that clause_relids includes
                                663                 :  * references to potentially-nulling outer joins, the other tests handle that
                                664                 :  * concern.  If the clause references any Var coming from the inside of a
                                665                 :  * lower outer join, its clause_relids will mention that outer join, causing
                                666                 :  * the evaluability check to fail; while if it references no such Vars, the
                                667                 :  * references-a-target-rel check will fail.
                                668                 :  *
                                669                 :  * There's no check here equivalent to join_clause_is_movable_to's test on
                                670                 :  * lateral_referencers.  We assume the caller wouldn't be inquiring unless
                                671                 :  * it'd verified that the proposed outer rels don't have lateral references
                                672                 :  * to the current rel(s).  (If we are considering join paths with the outer
                                673                 :  * rels on the outside and the current rels on the inside, then this should
                                674                 :  * have been checked at the outset of such consideration; see join_is_legal
                                675                 :  * and the path parameterization checks in joinpath.c.)  On the other hand,
                                676                 :  * in join_clause_is_movable_to we are asking whether the clause could be
                                677                 :  * moved for some valid set of outer rels, so we don't have the benefit of
                                678                 :  * relying on prior checks for lateral-reference validity.
                                679                 :  *
                                680                 :  * Likewise, we don't check is_clone here: rejecting the inappropriate
                                681                 :  * variants of a cloned clause must be handled upstream.
                                682                 :  *
                                683                 :  * Note: if this returns true, it means that the clause could be moved to
                                684                 :  * this join relation, but that doesn't mean that this is the lowest join
                                685                 :  * it could be moved to.  Caller may need to make additional calls to verify
                                686                 :  * that this doesn't succeed on either of the inputs of a proposed join.
                                687                 :  *
                                688                 :  * Note: get_joinrel_parampathinfo depends on the fact that if
                                689                 :  * current_and_outer is NULL, this function will always return false
                                690                 :  * (since one or the other of the first two tests must fail).
                                691                 :  */
                                692                 : bool
 4007 tgl                       693 GIC      121022 : join_clause_is_movable_into(RestrictInfo *rinfo,
                                694                 :                             Relids currentrelids,
                                695                 :                             Relids current_and_outer)
                                696                 : {
                                697                 :     /* Clause must be evaluable given available context */
                                698          121022 :     if (!bms_is_subset(rinfo->clause_relids, current_and_outer))
                                699           22085 :         return false;
 6981 tgl                       700 ECB             : 
                                701                 :     /* Clause must physically reference at least one target rel */
 4007 tgl                       702 GIC       98937 :     if (!bms_overlap(currentrelids, rinfo->clause_relids))
 4007 tgl                       703 CBC        7069 :         return false;
 6981 tgl                       704 ECB             : 
                                705                 :     /* Cannot move an outer-join clause into the join's outer side */
 4007 tgl                       706 GIC       91868 :     if (bms_overlap(currentrelids, rinfo->outer_relids))
 4007 tgl                       707 CBC         314 :         return false;
 7441 tgl                       708 ECB             : 
 4007 tgl                       709 GIC       91554 :     return true;
                                710                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a