LCOV - differential code coverage report
Current view: top level - src/backend/optimizer/util - joininfo.c (source / functions) Coverage Total Hit LBC UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 75.0 % 44 33 11 33
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 3 3 3
Baseline: lcov-20250906-005545-baseline Branches: 90.0 % 30 27 2 1 27
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 0.0 % 2 0 2
(360..) days: 78.6 % 42 33 9 33
Function coverage date bins:
(360..) days: 100.0 % 3 3 3
Branch coverage date bins:
(360..) days: 90.0 % 30 27 2 1 27

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * joininfo.c
                                  4                 :                :  *    joininfo list manipulation routines
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/optimizer/util/joininfo.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "nodes/makefuncs.h"
                                 18                 :                : #include "optimizer/joininfo.h"
                                 19                 :                : #include "optimizer/pathnode.h"
                                 20                 :                : #include "optimizer/paths.h"
                                 21                 :                : #include "optimizer/planmain.h"
                                 22                 :                : #include "optimizer/restrictinfo.h"
                                 23                 :                : 
                                 24                 :                : 
                                 25                 :                : /*
                                 26                 :                :  * have_relevant_joinclause
                                 27                 :                :  *      Detect whether there is a joinclause that involves
                                 28                 :                :  *      the two given relations.
                                 29                 :                :  *
                                 30                 :                :  * Note: the joinclause does not have to be evaluable with only these two
                                 31                 :                :  * relations.  This is intentional.  For example consider
                                 32                 :                :  *      SELECT * FROM a, b, c WHERE a.x = (b.y + c.z)
                                 33                 :                :  * If a is much larger than the other tables, it may be worthwhile to
                                 34                 :                :  * cross-join b and c and then use an inner indexscan on a.x.  Therefore
                                 35                 :                :  * we should consider this joinclause as reason to join b to c, even though
                                 36                 :                :  * it can't be applied at that join step.
                                 37                 :                :  */
                                 38                 :                : bool
 6843 tgl@sss.pgh.pa.us          39                 :CBC      191703 : have_relevant_joinclause(PlannerInfo *root,
                                 40                 :                :                          RelOptInfo *rel1, RelOptInfo *rel2)
                                 41                 :                : {
 7394                            42                 :         191703 :     bool        result = false;
                                 43                 :                :     List       *joininfo;
                                 44                 :                :     Relids      other_relids;
                                 45                 :                :     ListCell   *l;
                                 46                 :                : 
                                 47                 :                :     /*
                                 48                 :                :      * We could scan either relation's joininfo list; may as well use the
                                 49                 :                :      * shorter one.
                                 50                 :                :      */
                                 51         [ +  + ]:         191703 :     if (list_length(rel1->joininfo) <= list_length(rel2->joininfo))
                                 52                 :                :     {
                                 53                 :         143507 :         joininfo = rel1->joininfo;
 4894                            54                 :         143507 :         other_relids = rel2->relids;
                                 55                 :                :     }
                                 56                 :                :     else
                                 57                 :                :     {
 7394                            58                 :          48196 :         joininfo = rel2->joininfo;
 4894                            59                 :          48196 :         other_relids = rel1->relids;
                                 60                 :                :     }
                                 61                 :                : 
 7394                            62   [ +  +  +  +  :         208235 :     foreach(l, joininfo)
                                              +  + ]
                                 63                 :                :     {
                                 64                 :          93876 :         RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
                                 65                 :                : 
 4894                            66         [ +  + ]:          93876 :         if (bms_overlap(other_relids, rinfo->required_relids))
                                 67                 :                :         {
 7394                            68                 :          77344 :             result = true;
                                 69                 :          77344 :             break;
                                 70                 :                :         }
                                 71                 :                :     }
                                 72                 :                : 
                                 73                 :                :     /*
                                 74                 :                :      * We also need to check the EquivalenceClass data structure, which might
                                 75                 :                :      * contain relationships not emitted into the joininfo lists.
                                 76                 :                :      */
 6804                            77   [ +  +  +  +  :         191703 :     if (!result && rel1->has_eclass_joins && rel2->has_eclass_joins)
                                              +  + ]
                                 78                 :          86892 :         result = have_relevant_eclass_joinclause(root, rel1, rel2);
                                 79                 :                : 
 7394                            80                 :         191703 :     return result;
                                 81                 :                : }
                                 82                 :                : 
                                 83                 :                : 
                                 84                 :                : /*
                                 85                 :                :  * add_join_clause_to_rels
                                 86                 :                :  *    Add 'restrictinfo' to the joininfo list of each relation it requires.
                                 87                 :                :  *
                                 88                 :                :  * Note that the same copy of the restrictinfo node is linked to by all the
                                 89                 :                :  * lists it is in.  This allows us to exploit caching of information about
                                 90                 :                :  * the restriction clause (but we must be careful that the information does
                                 91                 :                :  * not depend on context).
                                 92                 :                :  *
                                 93                 :                :  * 'restrictinfo' describes the join clause
                                 94                 :                :  * 'join_relids' is the set of relations participating in the join clause
                                 95                 :                :  *               (some of these could be outer joins)
                                 96                 :                :  */
                                 97                 :                : void
 7398                            98                 :          34656 : add_join_clause_to_rels(PlannerInfo *root,
                                 99                 :                :                         RestrictInfo *restrictinfo,
                                100                 :                :                         Relids join_relids)
                                101                 :                : {
                                102                 :                :     int         cur_relid;
                                103                 :                : 
                                104                 :                :     /* Don't add the clause if it is always true */
  592 drowley@postgresql.o      105         [ -  + ]:          34656 :     if (restriction_is_always_true(root, restrictinfo))
  592 drowley@postgresql.o      106                 :LBC         (6) :         return;
                                107                 :                : 
                                108                 :                :     /*
                                109                 :                :      * Substitute the origin qual with constant-FALSE if it is provably always
                                110                 :                :      * false.
                                111                 :                :      *
                                112                 :                :      * Note that we need to keep the same rinfo_serial, since it is in
                                113                 :                :      * practice the same condition.  We also need to reset the
                                114                 :                :      * last_rinfo_serial counter, which is essential to ensure that the
                                115                 :                :      * RestrictInfos for the "same" qual condition get identical serial
                                116                 :                :      * numbers (see deconstruct_distribute_oj_quals).
                                117                 :                :      */
  592 drowley@postgresql.o      118         [ -  + ]:CBC       34656 :     if (restriction_is_always_false(root, restrictinfo))
                                119                 :                :     {
  592 drowley@postgresql.o      120                 :LBC         (6) :         int         save_rinfo_serial = restrictinfo->rinfo_serial;
  302 rguo@postgresql.org       121                 :            (6) :         int         save_last_rinfo_serial = root->last_rinfo_serial;
                                122                 :                : 
  592 drowley@postgresql.o      123                 :            (6) :         restrictinfo = make_restrictinfo(root,
                                124                 :            (6) :                                          (Expr *) makeBoolConst(false, false),
                                125                 :            (6) :                                          restrictinfo->is_pushed_down,
                                126                 :            (6) :                                          restrictinfo->has_clone,
                                127                 :            (6) :                                          restrictinfo->is_clone,
                                128                 :            (6) :                                          restrictinfo->pseudoconstant,
                                129                 :                :                                          0, /* security_level */
                                130                 :                :                                          restrictinfo->required_relids,
                                131                 :                :                                          restrictinfo->incompatible_relids,
                                132                 :                :                                          restrictinfo->outer_relids);
                                133                 :            (6) :         restrictinfo->rinfo_serial = save_rinfo_serial;
  302 rguo@postgresql.org       134                 :            (6) :         root->last_rinfo_serial = save_last_rinfo_serial;
                                135                 :                :     }
                                136                 :                : 
 3935 tgl@sss.pgh.pa.us         137                 :CBC       34656 :     cur_relid = -1;
                                138         [ +  + ]:         111722 :     while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
                                139                 :                :     {
  950                           140                 :          77066 :         RelOptInfo *rel = find_base_rel_ignore_join(root, cur_relid);
                                141                 :                : 
                                142                 :                :         /* We only need to add the clause to baserels */
                                143         [ +  + ]:          77066 :         if (rel == NULL)
                                144                 :           4727 :             continue;
 7394                           145                 :          72339 :         rel->joininfo = lappend(rel->joininfo, restrictinfo);
                                146                 :                :     }
                                147                 :                : }
                                148                 :                : 
                                149                 :                : /*
                                150                 :                :  * remove_join_clause_from_rels
                                151                 :                :  *    Delete 'restrictinfo' from all the joininfo lists it is in
                                152                 :                :  *
                                153                 :                :  * This reverses the effect of add_join_clause_to_rels.  It's used when we
                                154                 :                :  * discover that a relation need not be joined at all.
                                155                 :                :  *
                                156                 :                :  * 'restrictinfo' describes the join clause
                                157                 :                :  * 'join_relids' is the set of relations participating in the join clause
                                158                 :                :  *               (some of these could be outer joins)
                                159                 :                :  */
                                160                 :                : void
 5471                           161                 :           5428 : remove_join_clause_from_rels(PlannerInfo *root,
                                162                 :                :                              RestrictInfo *restrictinfo,
                                163                 :                :                              Relids join_relids)
                                164                 :                : {
                                165                 :                :     int         cur_relid;
                                166                 :                : 
 3935                           167                 :           5428 :     cur_relid = -1;
                                168         [ +  + ]:          16507 :     while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
                                169                 :                :     {
  950                           170                 :          11079 :         RelOptInfo *rel = find_base_rel_ignore_join(root, cur_relid);
                                171                 :                : 
                                172                 :                :         /* We would only have added the clause to baserels */
                                173         [ +  + ]:          11079 :         if (rel == NULL)
                                174                 :            126 :             continue;
                                175                 :                : 
                                176                 :                :         /*
                                177                 :                :          * Remove the restrictinfo from the list.  Pointer comparison is
                                178                 :                :          * sufficient.
                                179                 :                :          */
 5471                           180         [ -  + ]:          10953 :         Assert(list_member_ptr(rel->joininfo, restrictinfo));
                                181                 :          10953 :         rel->joininfo = list_delete_ptr(rel->joininfo, restrictinfo);
                                182                 :                :     }
                                183                 :           5428 : }
        

Generated by: LCOV version 2.4-beta