Branch data Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * pgpa_join.h
4 : : * analysis of joins in Plan trees
5 : : *
6 : : * Copyright (c) 2016-2025, 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 : 140223 : pgpa_is_join(Plan *plan)
91 : : {
92 [ + + + + ]: 140223 : 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
|