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 if ((nodetype == T_Append || nodetype == T_MergeAppend) &&
74 walker->pstmt->rtable) == RTE_RELATION)
75 strategy = PGPA_SCAN_PARTITIONWISE;
76 else
77 strategy = PGPA_SCAN_ORDINARY;
78
79 /* Join RTIs can be present, but advice never refers to them. */
80 relids = pgpa_filter_out_join_relids(relids, walker->pstmt->rtable);
81 }
82 else if ((rti = pgpa_scanrelid(plan)) != 0)
83 {
84 relids = bms_make_singleton(rti);
85
86 switch (nodeTag(plan))
87 {
88 case T_SeqScan:
89 strategy = PGPA_SCAN_SEQ;
90 break;
92 strategy = PGPA_SCAN_BITMAP_HEAP;
93 break;
94 case T_IndexScan:
95 strategy = PGPA_SCAN_INDEX;
96 break;
97 case T_IndexOnlyScan:
98 strategy = PGPA_SCAN_INDEX_ONLY;
99 break;
100 case T_TidScan:
101 case T_TidRangeScan:
102 strategy = PGPA_SCAN_TID;
103 break;
104 default:
105
106 /*
107 * This case includes a ForeignScan targeting a single
108 * relation; no other strategy is possible in that case, but
109 * see below, where things are different in multi-relation
110 * cases.
111 */
112 strategy = PGPA_SCAN_ORDINARY;
113 break;
114 }
115 }
116 else if ((relids = pgpa_relids(plan)) != NULL)
117 {
118 switch (nodeTag(plan))
119 {
120 case T_ForeignScan:
121
122 /*
123 * If multiple relations are being targeted by a single
124 * foreign scan, then the foreign join has been pushed to the
125 * remote side, and we want that to be reflected in the
126 * generated advice.
127 */
128 strategy = PGPA_SCAN_FOREIGN;
129 break;
130 case T_Append:
131
132 /*
133 * Append nodes can represent partitionwise scans of a
134 * relation, but when they implement a set operation, they are
135 * just ordinary scans.
136 */
137 if (unique_nonjoin_rtekind(relids, walker->pstmt->rtable)
138 == RTE_RELATION)
139 strategy = PGPA_SCAN_PARTITIONWISE;
140 else
141 strategy = PGPA_SCAN_ORDINARY;
142
143 /* Be sure to account for pulled-up scans. */
144 child_append_relid_sets =
145 ((Append *) plan)->child_append_relid_sets;
146 break;
147 case T_MergeAppend:
148 /* Same logic here as for Append, above. */
149 if (unique_nonjoin_rtekind(relids, walker->pstmt->rtable)
150 == RTE_RELATION)
151 strategy = PGPA_SCAN_PARTITIONWISE;
152 else
153 strategy = PGPA_SCAN_ORDINARY;
154
155 /* Be sure to account for pulled-up scans. */
156 child_append_relid_sets =
157 ((MergeAppend *) plan)->child_append_relid_sets;
158 break;
159 default:
160 strategy = PGPA_SCAN_ORDINARY;
161 break;
162 }
163
164
165 /* Join RTIs can be present, but advice never refers to them. */
166 relids = pgpa_filter_out_join_relids(relids, walker->pstmt->rtable);
167 }
168
169 /*
170 * If this is an Append or MergeAppend node into which subordinate Append
171 * or MergeAppend paths were merged, each of those merged paths is
172 * effectively another scan for which we need to account.
173 */
174 foreach_node(Bitmapset, child_relids, child_append_relid_sets)
175 {
177
179 pgpa_filter_out_join_relids(child_relids,
180 walker->pstmt->rtable);
181 (void) pgpa_make_scan(walker, plan, strategy,
183 }
184
185 /*
186 * If this plan node has no associated RTIs, it's not a scan. When the
187 * 'within_join_problem' flag is set, that's unexpected, so throw an
188 * error, else return quietly.
189 */
190 if (relids == NULL)
191 {
193 elog(ERROR, "plan node has no RTIs: %d", (int) nodeTag(plan));
194 return NULL;
195 }
196
197 /*
198 * Add the appropriate set of RTIs to walker->no_gather_scans.
199 *
200 * Add nothing if we're beneath a Gather or Gather Merge node, since
201 * NO_GATHER advice is clearly inappropriate in that situation.
202 *
203 * Add nothing if this is an Append or MergeAppend node, whether or not
204 * elided. We'll emit NO_GATHER() for the underlying scan, which is good
205 * enough.
206 */
209 walker->no_gather_scans =
210 bms_add_members(walker->no_gather_scans, relids);
211
212 /* Caller tells us whether NO_GATHER() advice for this scan is needed. */
213 return pgpa_make_scan(walker, plan, strategy, relids);
214}
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:226
#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:496
#define plan(x)
Definition pg_regress.c:161
static RTEKind unique_nonjoin_rtekind(Bitmapset *relids, List *rtable)
Definition pgpa_scan.c:242
static pgpa_scan * pgpa_make_scan(pgpa_plan_walker_context *walker, Plan *plan, pgpa_scan_strategy strategy, Bitmapset *relids)
Definition pgpa_scan.c:220
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:1870
Bitmapset * relids
Definition plannodes.h:1871
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().