Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "executor/execdebug.h"
00019 #include "executor/nodeSort.h"
00020 #include "miscadmin.h"
00021 #include "utils/tuplesort.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 TupleTableSlot *
00039 ExecSort(SortState *node)
00040 {
00041 EState *estate;
00042 ScanDirection dir;
00043 Tuplesortstate *tuplesortstate;
00044 TupleTableSlot *slot;
00045
00046
00047
00048
00049 SO1_printf("ExecSort: %s\n",
00050 "entering routine");
00051
00052 estate = node->ss.ps.state;
00053 dir = estate->es_direction;
00054 tuplesortstate = (Tuplesortstate *) node->tuplesortstate;
00055
00056
00057
00058
00059
00060
00061 if (!node->sort_Done)
00062 {
00063 Sort *plannode = (Sort *) node->ss.ps.plan;
00064 PlanState *outerNode;
00065 TupleDesc tupDesc;
00066
00067 SO1_printf("ExecSort: %s\n",
00068 "sorting subplan");
00069
00070
00071
00072
00073
00074 estate->es_direction = ForwardScanDirection;
00075
00076
00077
00078
00079 SO1_printf("ExecSort: %s\n",
00080 "calling tuplesort_begin");
00081
00082 outerNode = outerPlanState(node);
00083 tupDesc = ExecGetResultType(outerNode);
00084
00085 tuplesortstate = tuplesort_begin_heap(tupDesc,
00086 plannode->numCols,
00087 plannode->sortColIdx,
00088 plannode->sortOperators,
00089 plannode->collations,
00090 plannode->nullsFirst,
00091 work_mem,
00092 node->randomAccess);
00093 if (node->bounded)
00094 tuplesort_set_bound(tuplesortstate, node->bound);
00095 node->tuplesortstate = (void *) tuplesortstate;
00096
00097
00098
00099
00100
00101 for (;;)
00102 {
00103 slot = ExecProcNode(outerNode);
00104
00105 if (TupIsNull(slot))
00106 break;
00107
00108 tuplesort_puttupleslot(tuplesortstate, slot);
00109 }
00110
00111
00112
00113
00114 tuplesort_performsort(tuplesortstate);
00115
00116
00117
00118
00119 estate->es_direction = dir;
00120
00121
00122
00123
00124 node->sort_Done = true;
00125 node->bounded_Done = node->bounded;
00126 node->bound_Done = node->bound;
00127 SO1_printf("ExecSort: %s\n", "sorting done");
00128 }
00129
00130 SO1_printf("ExecSort: %s\n",
00131 "retrieving tuple from tuplesort");
00132
00133
00134
00135
00136
00137 slot = node->ss.ps.ps_ResultTupleSlot;
00138 (void) tuplesort_gettupleslot(tuplesortstate,
00139 ScanDirectionIsForward(dir),
00140 slot);
00141 return slot;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 SortState *
00152 ExecInitSort(Sort *node, EState *estate, int eflags)
00153 {
00154 SortState *sortstate;
00155
00156 SO1_printf("ExecInitSort: %s\n",
00157 "initializing sort node");
00158
00159
00160
00161
00162 sortstate = makeNode(SortState);
00163 sortstate->ss.ps.plan = (Plan *) node;
00164 sortstate->ss.ps.state = estate;
00165
00166
00167
00168
00169
00170
00171 sortstate->randomAccess = (eflags & (EXEC_FLAG_REWIND |
00172 EXEC_FLAG_BACKWARD |
00173 EXEC_FLAG_MARK)) != 0;
00174
00175 sortstate->bounded = false;
00176 sortstate->sort_Done = false;
00177 sortstate->tuplesortstate = NULL;
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 ExecInitResultTupleSlot(estate, &sortstate->ss.ps);
00192 ExecInitScanTupleSlot(estate, &sortstate->ss);
00193
00194
00195
00196
00197
00198
00199
00200 eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
00201
00202 outerPlanState(sortstate) = ExecInitNode(outerPlan(node), estate, eflags);
00203
00204
00205
00206
00207
00208 ExecAssignResultTypeFromTL(&sortstate->ss.ps);
00209 ExecAssignScanTypeFromOuterPlan(&sortstate->ss);
00210 sortstate->ss.ps.ps_ProjInfo = NULL;
00211
00212 SO1_printf("ExecInitSort: %s\n",
00213 "sort node initialized");
00214
00215 return sortstate;
00216 }
00217
00218
00219
00220
00221
00222 void
00223 ExecEndSort(SortState *node)
00224 {
00225 SO1_printf("ExecEndSort: %s\n",
00226 "shutting down sort node");
00227
00228
00229
00230
00231 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00232
00233 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00234
00235
00236
00237
00238 if (node->tuplesortstate != NULL)
00239 tuplesort_end((Tuplesortstate *) node->tuplesortstate);
00240 node->tuplesortstate = NULL;
00241
00242
00243
00244
00245 ExecEndNode(outerPlanState(node));
00246
00247 SO1_printf("ExecEndSort: %s\n",
00248 "sort node shutdown");
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 void
00258 ExecSortMarkPos(SortState *node)
00259 {
00260
00261
00262
00263 if (!node->sort_Done)
00264 return;
00265
00266 tuplesort_markpos((Tuplesortstate *) node->tuplesortstate);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 void
00276 ExecSortRestrPos(SortState *node)
00277 {
00278
00279
00280
00281 if (!node->sort_Done)
00282 return;
00283
00284
00285
00286
00287 tuplesort_restorepos((Tuplesortstate *) node->tuplesortstate);
00288 }
00289
00290 void
00291 ExecReScanSort(SortState *node)
00292 {
00293
00294
00295
00296
00297
00298 if (!node->sort_Done)
00299 return;
00300
00301
00302 ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
00303
00304
00305
00306
00307
00308
00309
00310
00311 if (node->ss.ps.lefttree->chgParam != NULL ||
00312 node->bounded != node->bounded_Done ||
00313 node->bound != node->bound_Done ||
00314 !node->randomAccess)
00315 {
00316 node->sort_Done = false;
00317 tuplesort_end((Tuplesortstate *) node->tuplesortstate);
00318 node->tuplesortstate = NULL;
00319
00320
00321
00322
00323
00324 if (node->ss.ps.lefttree->chgParam == NULL)
00325 ExecReScan(node->ss.ps.lefttree);
00326 }
00327 else
00328 tuplesort_rescan((Tuplesortstate *) node->tuplesortstate);
00329 }