PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgpa_scan.h File Reference
#include "nodes/plannodes.h"
Include dependency graph for pgpa_scan.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pgpa_scan
 

Macros

#define NUM_PGPA_SCAN_STRATEGY   ((int) PGPA_SCAN_TID + 1)
 

Typedefs

typedef struct pgpa_plan_walker_context pgpa_plan_walker_context
 
typedef struct pgpa_scan pgpa_scan
 

Enumerations

enum  pgpa_scan_strategy {
  PGPA_SCAN_ORDINARY = 0 , PGPA_SCAN_SEQ , PGPA_SCAN_BITMAP_HEAP , PGPA_SCAN_FOREIGN ,
  PGPA_SCAN_INDEX , PGPA_SCAN_INDEX_ONLY , PGPA_SCAN_PARTITIONWISE , PGPA_SCAN_TID
}
 

Functions

pgpa_scanpgpa_build_scan (pgpa_plan_walker_context *walker, Plan *plan, ElidedNode *elided_node, bool beneath_any_gather, bool within_join_problem)
 

Macro Definition Documentation

◆ NUM_PGPA_SCAN_STRATEGY

#define NUM_PGPA_SCAN_STRATEGY   ((int) PGPA_SCAN_TID + 1)

Definition at line 68 of file pgpa_scan.h.

Typedef Documentation

◆ pgpa_plan_walker_context

◆ pgpa_scan

Enumeration Type Documentation

◆ pgpa_scan_strategy

Enumerator
PGPA_SCAN_ORDINARY 
PGPA_SCAN_SEQ 
PGPA_SCAN_BITMAP_HEAP 
PGPA_SCAN_FOREIGN 
PGPA_SCAN_INDEX 
PGPA_SCAN_INDEX_ONLY 
PGPA_SCAN_PARTITIONWISE 
PGPA_SCAN_TID 

Definition at line 55 of file pgpa_scan.h.

56{
65 /* update NUM_PGPA_SCAN_STRATEGY if you add anything here */
pgpa_scan_strategy
Definition pgpa_scan.h:56
@ PGPA_SCAN_SEQ
Definition pgpa_scan.h:58
@ PGPA_SCAN_INDEX
Definition pgpa_scan.h:61
@ PGPA_SCAN_INDEX_ONLY
Definition pgpa_scan.h:62
@ PGPA_SCAN_BITMAP_HEAP
Definition pgpa_scan.h:59
@ PGPA_SCAN_FOREIGN
Definition pgpa_scan.h:60
@ PGPA_SCAN_TID
Definition pgpa_scan.h:64
@ PGPA_SCAN_PARTITIONWISE
Definition pgpa_scan.h:63
@ PGPA_SCAN_ORDINARY
Definition pgpa_scan.h:57

Function Documentation

◆ pgpa_build_scan()

pgpa_scan * pgpa_build_scan ( pgpa_plan_walker_context walker,
Plan plan,
ElidedNode elided_node,
bool  beneath_any_gather,
bool  within_join_problem 
)
extern

Definition at line 44 of file pgpa_scan.c.

47{
49 Bitmapset *relids = NULL;
50 int rti = -1;
51 List *child_append_relid_sets = NIL;
53
54 if (elided_node != NULL)
55 {
56 nodetype = elided_node->elided_type;
57 relids = elided_node->relids;
58
59 /*
60 * If setrefs processing elided an Append or MergeAppend node that had
61 * only one surviving child, it could be either a partitionwise
62 * operation or a setop over subqueries, depending on the rtekind.
63 *
64 * A setop over subqueries, or a trivial SubqueryScan that was elided,
65 * is an "ordinary" scan i.e. one for which we do not need to generate
66 * advice because the planner has not made any meaningful choice.
67 *
68 * Note that the PGPA_SCAN_PARTITIONWISE case also includes
69 * partitionwise joins; this module considers those to be a form of
70 * scan, since they lack internal structure that we can decompose.
71 *
72 * Note also that it's possible for relids to be NULL here, if the
73 * elided Append node is part of a partitionwise aggregate. In that
74 * case, it doesn't matter what strategy we choose, but we do need to
75 * avoid calling unique_nonjoin_rtekind(), which would fail an
76 * assertion.
77 */
78 if ((nodetype == T_Append || nodetype == T_MergeAppend) &&
79 relids != NULL &&
81 walker->pstmt->rtable) == RTE_RELATION)
82 strategy = PGPA_SCAN_PARTITIONWISE;
83 else
84 strategy = PGPA_SCAN_ORDINARY;
85
86 /* Join RTIs can be present, but advice never refers to them. */
87 relids = pgpa_filter_out_join_relids(relids, walker->pstmt->rtable);
88 }
89 else if ((rti = pgpa_scanrelid(plan)) != 0)
90 {
91 relids = bms_make_singleton(rti);
92
93 switch (nodeTag(plan))
94 {
95 case T_SeqScan:
96 strategy = PGPA_SCAN_SEQ;
97 break;
99 strategy = PGPA_SCAN_BITMAP_HEAP;
100 break;
101 case T_IndexScan:
102 strategy = PGPA_SCAN_INDEX;
103 break;
104 case T_IndexOnlyScan:
105 strategy = PGPA_SCAN_INDEX_ONLY;
106 break;
107 case T_TidScan:
108 case T_TidRangeScan:
109 strategy = PGPA_SCAN_TID;
110 break;
111 default:
112
113 /*
114 * This case includes a ForeignScan targeting a single
115 * relation; no other strategy is possible in that case, but
116 * see below, where things are different in multi-relation
117 * cases.
118 */
119 strategy = PGPA_SCAN_ORDINARY;
120 break;
121 }
122 }
123 else if ((relids = pgpa_relids(plan)) != NULL)
124 {
125 switch (nodeTag(plan))
126 {
127 case T_ForeignScan:
128
129 /*
130 * If multiple relations are being targeted by a single
131 * foreign scan, then the foreign join has been pushed to the
132 * remote side, and we want that to be reflected in the
133 * generated advice.
134 */
135 strategy = PGPA_SCAN_FOREIGN;
136 break;
137 case T_Append:
138
139 /*
140 * Append nodes can represent partitionwise scans of a
141 * relation, but when they implement a set operation, they are
142 * just ordinary scans.
143 */
144 if (unique_nonjoin_rtekind(relids, walker->pstmt->rtable)
145 == RTE_RELATION)
146 strategy = PGPA_SCAN_PARTITIONWISE;
147 else
148 strategy = PGPA_SCAN_ORDINARY;
149
150 /* Be sure to account for pulled-up scans. */
151 child_append_relid_sets =
152 ((Append *) plan)->child_append_relid_sets;
153 break;
154 case T_MergeAppend:
155 /* Same logic here as for Append, above. */
156 if (unique_nonjoin_rtekind(relids, walker->pstmt->rtable)
157 == RTE_RELATION)
158 strategy = PGPA_SCAN_PARTITIONWISE;
159 else
160 strategy = PGPA_SCAN_ORDINARY;
161
162 /* Be sure to account for pulled-up scans. */
163 child_append_relid_sets =
164 ((MergeAppend *) plan)->child_append_relid_sets;
165 break;
166 default:
167 strategy = PGPA_SCAN_ORDINARY;
168 break;
169 }
170
171
172 /* Join RTIs can be present, but advice never refers to them. */
173 relids = pgpa_filter_out_join_relids(relids, walker->pstmt->rtable);
174 }
175
176 /*
177 * If this is an Append or MergeAppend node into which subordinate Append
178 * or MergeAppend paths were merged, each of those merged paths is
179 * effectively another scan for which we need to account.
180 */
181 foreach_node(Bitmapset, child_relids, child_append_relid_sets)
182 {
184
186 pgpa_filter_out_join_relids(child_relids,
187 walker->pstmt->rtable);
188 (void) pgpa_make_scan(walker, plan, strategy,
190 }
191
192 /*
193 * If this plan node has no associated RTIs, it's not a scan. When the
194 * 'within_join_problem' flag is set, that's unexpected, so throw an
195 * error, else return quietly.
196 */
197 if (relids == NULL)
198 {
200 elog(ERROR, "plan node has no RTIs: %d", (int) nodeTag(plan));
201 return NULL;
202 }
203
204 /*
205 * Add the appropriate set of RTIs to walker->no_gather_scans.
206 *
207 * Add nothing if we're beneath a Gather or Gather Merge node, since
208 * NO_GATHER advice is clearly inappropriate in that situation.
209 *
210 * Add nothing if this is an Append or MergeAppend node, whether or not
211 * elided. We'll emit NO_GATHER() for the underlying scan, which is good
212 * enough.
213 */
216 walker->no_gather_scans =
217 bms_add_members(walker->no_gather_scans, relids);
218
219 /* Caller tells us whether NO_GATHER() advice for this scan is needed. */
220 return pgpa_make_scan(walker, plan, strategy, relids);
221}
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:901
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:227
#define nodeTag(nodeptr)
Definition nodes.h:139
NodeTag
Definition nodes.h:27
@ RTE_RELATION
#define NIL
Definition pg_list.h:68
#define foreach_node(type, var, lst)
Definition pg_list.h:528
#define plan(x)
Definition pg_regress.c:164
static RTEKind unique_nonjoin_rtekind(Bitmapset *relids, List *rtable)
Definition pgpa_scan.c:249
static pgpa_scan * pgpa_make_scan(pgpa_plan_walker_context *walker, Plan *plan, pgpa_scan_strategy strategy, Bitmapset *relids)
Definition pgpa_scan.c:227
Bitmapset * pgpa_filter_out_join_relids(Bitmapset *relids, List *rtable)
Bitmapset * pgpa_relids(Plan *plan)
Index pgpa_scanrelid(Plan *plan)
static int fb(int x)
NodeTag elided_type
Definition plannodes.h:1872
Bitmapset * relids
Definition plannodes.h:1873
Definition pg_list.h:54

References bms_add_members(), bms_make_singleton(), ElidedNode::elided_type, elog, ERROR, fb(), foreach_node, NIL, nodeTag, pgpa_filter_out_join_relids(), pgpa_make_scan(), pgpa_relids(), PGPA_SCAN_BITMAP_HEAP, PGPA_SCAN_FOREIGN, PGPA_SCAN_INDEX, PGPA_SCAN_INDEX_ONLY, PGPA_SCAN_ORDINARY, PGPA_SCAN_PARTITIONWISE, PGPA_SCAN_SEQ, PGPA_SCAN_TID, pgpa_scanrelid(), plan, ElidedNode::relids, RTE_RELATION, and unique_nonjoin_rtekind().

Referenced by pgpa_build_unrolled_join(), and pgpa_walk_recursively().