LCOV - code coverage report
Current view: top level - contrib/pg_plan_advice - pgpa_join.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 2 2
Test Date: 2026-03-16 00:15:06 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * pgpa_join.h
       4              :  *    analysis of joins in Plan trees
       5              :  *
       6              :  * Copyright (c) 2016-2026, PostgreSQL Global Development Group
       7              :  *
       8              :  *    contrib/pg_plan_advice/pgpa_join.h
       9              :  *
      10              :  *-------------------------------------------------------------------------
      11              :  */
      12              : #ifndef PGPA_JOIN_H
      13              : #define PGPA_JOIN_H
      14              : 
      15              : #include "nodes/plannodes.h"
      16              : 
      17              : typedef struct pgpa_plan_walker_context pgpa_plan_walker_context;
      18              : typedef struct pgpa_join_unroller pgpa_join_unroller;
      19              : typedef struct pgpa_unrolled_join pgpa_unrolled_join;
      20              : 
      21              : /*
      22              :  * Although there are three main join strategies, we try to classify things
      23              :  * more precisely here: merge joins have the option of using materialization
      24              :  * on the inner side, and nested loops can use either materialization or
      25              :  * memoization.
      26              :  */
      27              : typedef enum
      28              : {
      29              :     JSTRAT_MERGE_JOIN_PLAIN = 0,
      30              :     JSTRAT_MERGE_JOIN_MATERIALIZE,
      31              :     JSTRAT_NESTED_LOOP_PLAIN,
      32              :     JSTRAT_NESTED_LOOP_MATERIALIZE,
      33              :     JSTRAT_NESTED_LOOP_MEMOIZE,
      34              :     JSTRAT_HASH_JOIN
      35              :     /* update NUM_PGPA_JOIN_STRATEGY if you add anything here */
      36              : } pgpa_join_strategy;
      37              : 
      38              : #define NUM_PGPA_JOIN_STRATEGY      ((int) JSTRAT_HASH_JOIN + 1)
      39              : 
      40              : /*
      41              :  * In an outer-deep join tree, every member of an unrolled join will be a scan,
      42              :  * but join trees with other shapes can contain unrolled joins.
      43              :  *
      44              :  * The plan node we store here will be the inner or outer child of the join
      45              :  * node, as appropriate, except that we look through subnodes that we regard as
      46              :  * part of the join method itself. For instance, for a Nested Loop that
      47              :  * materializes the inner input, we'll store the child of the Materialize node,
      48              :  * not the Materialize node itself.
      49              :  *
      50              :  * If setrefs processing elided one or more nodes from the plan tree, then
      51              :  * we'll store details about the topmost of those in elided_node; otherwise,
      52              :  * it will be NULL.
      53              :  *
      54              :  * Exactly one of scan and unrolled_join will be non-NULL.
      55              :  */
      56              : typedef struct
      57              : {
      58              :     Plan       *plan;
      59              :     ElidedNode *elided_node;
      60              :     struct pgpa_scan *scan;
      61              :     pgpa_unrolled_join *unrolled_join;
      62              : } pgpa_join_member;
      63              : 
      64              : /*
      65              :  * We convert outer-deep join trees to a flat structure; that is, ((A JOIN B)
      66              :  * JOIN C) JOIN D gets converted to outer = A, inner = <B C D>.  When joins
      67              :  * aren't outer-deep, substructure is required, e.g. (A JOIN B) JOIN (C JOIN D)
      68              :  * is represented as outer = A, inner = <B X>, where X is a pgpa_unrolled_join
      69              :  * covering C-D.
      70              :  */
      71              : struct pgpa_unrolled_join
      72              : {
      73              :     /* Outermost member; must not itself be an unrolled join. */
      74              :     pgpa_join_member outer;
      75              : 
      76              :     /* Number of inner members. Length of the strategy and inner arrays. */
      77              :     unsigned    ninner;
      78              : 
      79              :     /* Array of strategies, one per non-outermost member. */
      80              :     pgpa_join_strategy *strategy;
      81              : 
      82              :     /* Array of members, excluding the outermost. Deepest first. */
      83              :     pgpa_join_member *inner;
      84              : };
      85              : 
      86              : /*
      87              :  * Does this plan node inherit from Join?
      88              :  */
      89              : static inline bool
      90          714 : pgpa_is_join(Plan *plan)
      91              : {
      92          714 :     return IsA(plan, NestLoop) || IsA(plan, MergeJoin) || IsA(plan, HashJoin);
      93              : }
      94              : 
      95              : extern pgpa_join_unroller *pgpa_create_join_unroller(void);
      96              : extern void pgpa_unroll_join(pgpa_plan_walker_context *walker,
      97              :                              Plan *plan, bool beneath_any_gather,
      98              :                              pgpa_join_unroller *join_unroller,
      99              :                              pgpa_join_unroller **outer_join_unroller,
     100              :                              pgpa_join_unroller **inner_join_unroller);
     101              : extern pgpa_unrolled_join *pgpa_build_unrolled_join(pgpa_plan_walker_context *walker,
     102              :                                                     pgpa_join_unroller *join_unroller);
     103              : extern void pgpa_destroy_join_unroller(pgpa_join_unroller *join_unroller);
     104              : 
     105              : #endif
        

Generated by: LCOV version 2.0-1