Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "postgres.h"
00023
00024 #include "executor/execdebug.h"
00025 #include "executor/nodeBitmapIndexscan.h"
00026 #include "executor/nodeIndexscan.h"
00027 #include "miscadmin.h"
00028 #include "utils/memutils.h"
00029
00030
00031
00032
00033
00034
00035 Node *
00036 MultiExecBitmapIndexScan(BitmapIndexScanState *node)
00037 {
00038 TIDBitmap *tbm;
00039 IndexScanDesc scandesc;
00040 double nTuples = 0;
00041 bool doscan;
00042
00043
00044 if (node->ss.ps.instrument)
00045 InstrStartNode(node->ss.ps.instrument);
00046
00047
00048
00049
00050 scandesc = node->biss_ScanDesc;
00051
00052
00053
00054
00055
00056
00057
00058 if (!node->biss_RuntimeKeysReady &&
00059 (node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0))
00060 {
00061 ExecReScan((PlanState *) node);
00062 doscan = node->biss_RuntimeKeysReady;
00063 }
00064 else
00065 doscan = true;
00066
00067
00068
00069
00070
00071
00072
00073 if (node->biss_result)
00074 {
00075 tbm = node->biss_result;
00076 node->biss_result = NULL;
00077 }
00078 else
00079 {
00080
00081 tbm = tbm_create(work_mem * 1024L);
00082 }
00083
00084
00085
00086
00087 while (doscan)
00088 {
00089 nTuples += (double) index_getbitmap(scandesc, tbm);
00090
00091 CHECK_FOR_INTERRUPTS();
00092
00093 doscan = ExecIndexAdvanceArrayKeys(node->biss_ArrayKeys,
00094 node->biss_NumArrayKeys);
00095 if (doscan)
00096 index_rescan(node->biss_ScanDesc,
00097 node->biss_ScanKeys, node->biss_NumScanKeys,
00098 NULL, 0);
00099 }
00100
00101
00102 if (node->ss.ps.instrument)
00103 InstrStopNode(node->ss.ps.instrument, nTuples);
00104
00105 return (Node *) tbm;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115 void
00116 ExecReScanBitmapIndexScan(BitmapIndexScanState *node)
00117 {
00118 ExprContext *econtext = node->biss_RuntimeContext;
00119
00120
00121
00122
00123
00124
00125 if (econtext)
00126 ResetExprContext(econtext);
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 if (node->biss_NumRuntimeKeys != 0)
00137 ExecIndexEvalRuntimeKeys(econtext,
00138 node->biss_RuntimeKeys,
00139 node->biss_NumRuntimeKeys);
00140 if (node->biss_NumArrayKeys != 0)
00141 node->biss_RuntimeKeysReady =
00142 ExecIndexEvalArrayKeys(econtext,
00143 node->biss_ArrayKeys,
00144 node->biss_NumArrayKeys);
00145 else
00146 node->biss_RuntimeKeysReady = true;
00147
00148
00149 if (node->biss_RuntimeKeysReady)
00150 index_rescan(node->biss_ScanDesc,
00151 node->biss_ScanKeys, node->biss_NumScanKeys,
00152 NULL, 0);
00153 }
00154
00155
00156
00157
00158
00159 void
00160 ExecEndBitmapIndexScan(BitmapIndexScanState *node)
00161 {
00162 Relation indexRelationDesc;
00163 IndexScanDesc indexScanDesc;
00164
00165
00166
00167
00168 indexRelationDesc = node->biss_RelationDesc;
00169 indexScanDesc = node->biss_ScanDesc;
00170
00171
00172
00173
00174 #ifdef NOT_USED
00175 if (node->biss_RuntimeContext)
00176 FreeExprContext(node->biss_RuntimeContext, true);
00177 #endif
00178
00179
00180
00181
00182 if (indexScanDesc)
00183 index_endscan(indexScanDesc);
00184 if (indexRelationDesc)
00185 index_close(indexRelationDesc, NoLock);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 BitmapIndexScanState *
00195 ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
00196 {
00197 BitmapIndexScanState *indexstate;
00198 bool relistarget;
00199
00200
00201 Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
00202
00203
00204
00205
00206 indexstate = makeNode(BitmapIndexScanState);
00207 indexstate->ss.ps.plan = (Plan *) node;
00208 indexstate->ss.ps.state = estate;
00209
00210
00211 indexstate->biss_result = NULL;
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 indexstate->ss.ss_currentRelation = NULL;
00236 indexstate->ss.ss_currentScanDesc = NULL;
00237
00238
00239
00240
00241
00242
00243 if (eflags & EXEC_FLAG_EXPLAIN_ONLY)
00244 return indexstate;
00245
00246
00247
00248
00249
00250
00251
00252
00253 relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
00254 indexstate->biss_RelationDesc = index_open(node->indexid,
00255 relistarget ? NoLock : AccessShareLock);
00256
00257
00258
00259
00260 indexstate->biss_RuntimeKeysReady = false;
00261 indexstate->biss_RuntimeKeys = NULL;
00262 indexstate->biss_NumRuntimeKeys = 0;
00263
00264
00265
00266
00267 ExecIndexBuildScanKeys((PlanState *) indexstate,
00268 indexstate->biss_RelationDesc,
00269 node->indexqual,
00270 false,
00271 &indexstate->biss_ScanKeys,
00272 &indexstate->biss_NumScanKeys,
00273 &indexstate->biss_RuntimeKeys,
00274 &indexstate->biss_NumRuntimeKeys,
00275 &indexstate->biss_ArrayKeys,
00276 &indexstate->biss_NumArrayKeys);
00277
00278
00279
00280
00281
00282
00283
00284 if (indexstate->biss_NumRuntimeKeys != 0 ||
00285 indexstate->biss_NumArrayKeys != 0)
00286 {
00287 ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext;
00288
00289 ExecAssignExprContext(estate, &indexstate->ss.ps);
00290 indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext;
00291 indexstate->ss.ps.ps_ExprContext = stdecontext;
00292 }
00293 else
00294 {
00295 indexstate->biss_RuntimeContext = NULL;
00296 }
00297
00298
00299
00300
00301 indexstate->biss_ScanDesc =
00302 index_beginscan_bitmap(indexstate->biss_RelationDesc,
00303 estate->es_snapshot,
00304 indexstate->biss_NumScanKeys);
00305
00306
00307
00308
00309
00310 if (indexstate->biss_NumRuntimeKeys == 0 &&
00311 indexstate->biss_NumArrayKeys == 0)
00312 index_rescan(indexstate->biss_ScanDesc,
00313 indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys,
00314 NULL, 0);
00315
00316
00317
00318
00319 return indexstate;
00320 }