Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita5358c1

Browse files
Move BitmapTableScan per-scan setup into a helper
Add BitmapTableScanSetup(), a helper which contains all of the code thatmust be done on every scan of the table in a bitmap table scan. Thisincludes scanning the index, building the bitmap, and setting up thescan descriptors.Pushing this setup into a helper function makes BitmapHeapNext() morereadable.Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>Discussion:https://postgr.es/m/CAN55FZ1vXu%2BZdT0_MM-i1vbTdfHHf0KR3cK6R5gs6dNNNpyrJw%40mail.gmail.com
1 parent115a365 commita5358c1

File tree

1 file changed

+107
-99
lines changed

1 file changed

+107
-99
lines changed

‎src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 107 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include"utils/rel.h"
4949
#include"utils/spccache.h"
5050

51+
staticvoidBitmapTableScanSetup(BitmapHeapScanState*node);
5152
staticTupleTableSlot*BitmapHeapNext(BitmapHeapScanState*node);
5253
staticinlinevoidBitmapDoneInitializingSharedState(ParallelBitmapHeapState*pstate);
5354
staticinlinevoidBitmapAdjustPrefetchIterator(BitmapHeapScanState*node);
@@ -57,6 +58,107 @@ static inline void BitmapPrefetch(BitmapHeapScanState *node,
5758
staticboolBitmapShouldInitializeSharedState(ParallelBitmapHeapState*pstate);
5859

5960

61+
/*
62+
* Do the underlying index scan, build the bitmap, set up the parallel state
63+
* needed for parallel workers to iterate through the bitmap, and set up the
64+
* underlying table scan descriptor.
65+
*
66+
* For prefetching, we use *two* iterators, one for the pages we are actually
67+
* scanning and another that runs ahead of the first for prefetching.
68+
* node->prefetch_pages tracks exactly how many pages ahead the prefetch
69+
* iterator is. Also, node->prefetch_target tracks the desired prefetch
70+
* distance, which starts small and increases up to the
71+
* node->prefetch_maximum. This is to avoid doing a lot of prefetching in a
72+
* scan that stops after a few tuples because of a LIMIT.
73+
*/
74+
staticvoid
75+
BitmapTableScanSetup(BitmapHeapScanState*node)
76+
{
77+
TBMIteratortbmiterator= {0};
78+
ParallelBitmapHeapState*pstate=node->pstate;
79+
dsa_area*dsa=node->ss.ps.state->es_query_dsa;
80+
81+
if (!pstate)
82+
{
83+
node->tbm= (TIDBitmap*)MultiExecProcNode(outerPlanState(node));
84+
85+
if (!node->tbm|| !IsA(node->tbm,TIDBitmap))
86+
elog(ERROR,"unrecognized result from subplan");
87+
}
88+
elseif (BitmapShouldInitializeSharedState(pstate))
89+
{
90+
/*
91+
* The leader will immediately come out of the function, but others
92+
* will be blocked until leader populates the TBM and wakes them up.
93+
*/
94+
node->tbm= (TIDBitmap*)MultiExecProcNode(outerPlanState(node));
95+
if (!node->tbm|| !IsA(node->tbm,TIDBitmap))
96+
elog(ERROR,"unrecognized result from subplan");
97+
98+
/*
99+
* Prepare to iterate over the TBM. This will return the dsa_pointer
100+
* of the iterator state which will be used by multiple processes to
101+
* iterate jointly.
102+
*/
103+
pstate->tbmiterator=tbm_prepare_shared_iterate(node->tbm);
104+
105+
#ifdefUSE_PREFETCH
106+
if (node->prefetch_maximum>0)
107+
{
108+
pstate->prefetch_iterator=
109+
tbm_prepare_shared_iterate(node->tbm);
110+
}
111+
#endif/* USE_PREFETCH */
112+
113+
/* We have initialized the shared state so wake up others. */
114+
BitmapDoneInitializingSharedState(pstate);
115+
}
116+
117+
tbmiterator=tbm_begin_iterate(node->tbm,dsa,
118+
pstate ?
119+
pstate->tbmiterator :
120+
InvalidDsaPointer);
121+
122+
#ifdefUSE_PREFETCH
123+
if (node->prefetch_maximum>0)
124+
node->prefetch_iterator=
125+
tbm_begin_iterate(node->tbm,dsa,
126+
pstate ?
127+
pstate->prefetch_iterator :
128+
InvalidDsaPointer);
129+
#endif/* USE_PREFETCH */
130+
131+
/*
132+
* If this is the first scan of the underlying table, create the table
133+
* scan descriptor and begin the scan.
134+
*/
135+
if (!node->ss.ss_currentScanDesc)
136+
{
137+
boolneed_tuples= false;
138+
139+
/*
140+
* We can potentially skip fetching heap pages if we do not need any
141+
* columns of the table, either for checking non-indexable quals or
142+
* for returning data. This test is a bit simplistic, as it checks
143+
* the stronger condition that there's no qual or return tlist at all.
144+
* But in most cases it's probably not worth working harder than that.
145+
*/
146+
need_tuples= (node->ss.ps.plan->qual!=NIL||
147+
node->ss.ps.plan->targetlist!=NIL);
148+
149+
node->ss.ss_currentScanDesc=
150+
table_beginscan_bm(node->ss.ss_currentRelation,
151+
node->ss.ps.state->es_snapshot,
152+
0,
153+
NULL,
154+
need_tuples);
155+
}
156+
157+
node->ss.ss_currentScanDesc->st.rs_tbmiterator=tbmiterator;
158+
node->initialized= true;
159+
}
160+
161+
60162
/* ----------------------------------------------------------------
61163
*BitmapHeapNext
62164
*
@@ -68,121 +170,27 @@ BitmapHeapNext(BitmapHeapScanState *node)
68170
{
69171
ExprContext*econtext;
70172
TableScanDescscan;
71-
TIDBitmap*tbm;
72173
TupleTableSlot*slot;
174+
175+
#ifdefUSE_PREFETCH
73176
ParallelBitmapHeapState*pstate=node->pstate;
74-
dsa_area*dsa=node->ss.ps.state->es_query_dsa;
177+
#endif
75178

76179
/*
77180
* extract necessary information from index scan node
78181
*/
79182
econtext=node->ss.ps.ps_ExprContext;
80183
slot=node->ss.ss_ScanTupleSlot;
81184
scan=node->ss.ss_currentScanDesc;
82-
tbm=node->tbm;
83185

84186
/*
85187
* If we haven't yet performed the underlying index scan, do it, and begin
86188
* the iteration over the bitmap.
87-
*
88-
* For prefetching, we use *two* iterators, one for the pages we are
89-
* actually scanning and another that runs ahead of the first for
90-
* prefetching. node->prefetch_pages tracks exactly how many pages ahead
91-
* the prefetch iterator is. Also, node->prefetch_target tracks the
92-
* desired prefetch distance, which starts small and increases up to the
93-
* node->prefetch_maximum. This is to avoid doing a lot of prefetching in
94-
* a scan that stops after a few tuples because of a LIMIT.
95189
*/
96190
if (!node->initialized)
97191
{
98-
TBMIteratortbmiterator;
99-
100-
if (!pstate)
101-
{
102-
tbm= (TIDBitmap*)MultiExecProcNode(outerPlanState(node));
103-
104-
if (!tbm|| !IsA(tbm,TIDBitmap))
105-
elog(ERROR,"unrecognized result from subplan");
106-
107-
node->tbm=tbm;
108-
}
109-
elseif (BitmapShouldInitializeSharedState(pstate))
110-
{
111-
/*
112-
* The leader will immediately come out of the function, but
113-
* others will be blocked until leader populates the TBM and wakes
114-
* them up.
115-
*/
116-
tbm= (TIDBitmap*)MultiExecProcNode(outerPlanState(node));
117-
if (!tbm|| !IsA(tbm,TIDBitmap))
118-
elog(ERROR,"unrecognized result from subplan");
119-
120-
node->tbm=tbm;
121-
122-
/*
123-
* Prepare to iterate over the TBM. This will return the
124-
* dsa_pointer of the iterator state which will be used by
125-
* multiple processes to iterate jointly.
126-
*/
127-
pstate->tbmiterator=tbm_prepare_shared_iterate(tbm);
128-
129-
#ifdefUSE_PREFETCH
130-
if (node->prefetch_maximum>0)
131-
{
132-
pstate->prefetch_iterator=
133-
tbm_prepare_shared_iterate(tbm);
134-
}
135-
#endif/* USE_PREFETCH */
136-
137-
/* We have initialized the shared state so wake up others. */
138-
BitmapDoneInitializingSharedState(pstate);
139-
}
140-
141-
tbmiterator=tbm_begin_iterate(tbm,dsa,
142-
pstate ?
143-
pstate->tbmiterator :
144-
InvalidDsaPointer);
145-
146-
#ifdefUSE_PREFETCH
147-
if (node->prefetch_maximum>0)
148-
node->prefetch_iterator=
149-
tbm_begin_iterate(tbm,dsa,
150-
pstate ?
151-
pstate->prefetch_iterator :
152-
InvalidDsaPointer);
153-
#endif/* USE_PREFETCH */
154-
155-
/*
156-
* If this is the first scan of the underlying table, create the table
157-
* scan descriptor and begin the scan.
158-
*/
159-
if (!scan)
160-
{
161-
boolneed_tuples= false;
162-
163-
/*
164-
* We can potentially skip fetching heap pages if we do not need
165-
* any columns of the table, either for checking non-indexable
166-
* quals or for returning data. This test is a bit simplistic, as
167-
* it checks the stronger condition that there's no qual or return
168-
* tlist at all. But in most cases it's probably not worth working
169-
* harder than that.
170-
*/
171-
need_tuples= (node->ss.ps.plan->qual!=NIL||
172-
node->ss.ps.plan->targetlist!=NIL);
173-
174-
scan=table_beginscan_bm(node->ss.ss_currentRelation,
175-
node->ss.ps.state->es_snapshot,
176-
0,
177-
NULL,
178-
need_tuples);
179-
180-
node->ss.ss_currentScanDesc=scan;
181-
}
182-
183-
scan->st.rs_tbmiterator=tbmiterator;
184-
node->initialized= true;
185-
192+
BitmapTableScanSetup(node);
193+
scan=node->ss.ss_currentScanDesc;
186194
gotonew_page;
187195
}
188196

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp