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
00023 #include "postgres.h"
00024
00025 #include "executor/executor.h"
00026 #include "executor/nodeGroup.h"
00027
00028
00029
00030
00031
00032
00033
00034 TupleTableSlot *
00035 ExecGroup(GroupState *node)
00036 {
00037 ExprContext *econtext;
00038 int numCols;
00039 AttrNumber *grpColIdx;
00040 TupleTableSlot *firsttupleslot;
00041 TupleTableSlot *outerslot;
00042
00043
00044
00045
00046 if (node->grp_done)
00047 return NULL;
00048 econtext = node->ss.ps.ps_ExprContext;
00049 numCols = ((Group *) node->ss.ps.plan)->numCols;
00050 grpColIdx = ((Group *) node->ss.ps.plan)->grpColIdx;
00051
00052
00053
00054
00055
00056
00057 if (node->ss.ps.ps_TupFromTlist)
00058 {
00059 TupleTableSlot *result;
00060 ExprDoneCond isDone;
00061
00062 result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
00063 if (isDone == ExprMultipleResult)
00064 return result;
00065
00066 node->ss.ps.ps_TupFromTlist = false;
00067 }
00068
00069
00070
00071
00072 firsttupleslot = node->ss.ss_ScanTupleSlot;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 if (TupIsNull(firsttupleslot))
00084 {
00085 outerslot = ExecProcNode(outerPlanState(node));
00086 if (TupIsNull(outerslot))
00087 {
00088
00089 node->grp_done = TRUE;
00090 return NULL;
00091 }
00092
00093 ExecCopySlot(firsttupleslot, outerslot);
00094
00095
00096
00097
00098
00099 econtext->ecxt_outertuple = firsttupleslot;
00100
00101
00102
00103
00104
00105 if (ExecQual(node->ss.ps.qual, econtext, false))
00106 {
00107
00108
00109
00110 TupleTableSlot *result;
00111 ExprDoneCond isDone;
00112
00113 result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
00114
00115 if (isDone != ExprEndResult)
00116 {
00117 node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
00118 return result;
00119 }
00120 }
00121 else
00122 InstrCountFiltered1(node, 1);
00123 }
00124
00125
00126
00127
00128
00129
00130 for (;;)
00131 {
00132
00133
00134
00135 for (;;)
00136 {
00137 outerslot = ExecProcNode(outerPlanState(node));
00138 if (TupIsNull(outerslot))
00139 {
00140
00141 node->grp_done = TRUE;
00142 return NULL;
00143 }
00144
00145
00146
00147
00148
00149 if (!execTuplesMatch(firsttupleslot, outerslot,
00150 numCols, grpColIdx,
00151 node->eqfunctions,
00152 econtext->ecxt_per_tuple_memory))
00153 break;
00154 }
00155
00156
00157
00158
00159
00160
00161 ExecCopySlot(firsttupleslot, outerslot);
00162 econtext->ecxt_outertuple = firsttupleslot;
00163
00164
00165
00166
00167
00168 if (ExecQual(node->ss.ps.qual, econtext, false))
00169 {
00170
00171
00172
00173 TupleTableSlot *result;
00174 ExprDoneCond isDone;
00175
00176 result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
00177
00178 if (isDone != ExprEndResult)
00179 {
00180 node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
00181 return result;
00182 }
00183 }
00184 else
00185 InstrCountFiltered1(node, 1);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 GroupState *
00197 ExecInitGroup(Group *node, EState *estate, int eflags)
00198 {
00199 GroupState *grpstate;
00200
00201
00202 Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
00203
00204
00205
00206
00207 grpstate = makeNode(GroupState);
00208 grpstate->ss.ps.plan = (Plan *) node;
00209 grpstate->ss.ps.state = estate;
00210 grpstate->grp_done = FALSE;
00211
00212
00213
00214
00215 ExecAssignExprContext(estate, &grpstate->ss.ps);
00216
00217
00218
00219
00220 ExecInitScanTupleSlot(estate, &grpstate->ss);
00221 ExecInitResultTupleSlot(estate, &grpstate->ss.ps);
00222
00223
00224
00225
00226 grpstate->ss.ps.targetlist = (List *)
00227 ExecInitExpr((Expr *) node->plan.targetlist,
00228 (PlanState *) grpstate);
00229 grpstate->ss.ps.qual = (List *)
00230 ExecInitExpr((Expr *) node->plan.qual,
00231 (PlanState *) grpstate);
00232
00233
00234
00235
00236 outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags);
00237
00238
00239
00240
00241 ExecAssignScanTypeFromOuterPlan(&grpstate->ss);
00242
00243
00244
00245
00246 ExecAssignResultTypeFromTL(&grpstate->ss.ps);
00247 ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
00248
00249 grpstate->ss.ps.ps_TupFromTlist = false;
00250
00251
00252
00253
00254 grpstate->eqfunctions =
00255 execTuplesMatchPrepare(node->numCols,
00256 node->grpOperators);
00257
00258 return grpstate;
00259 }
00260
00261
00262
00263
00264
00265
00266 void
00267 ExecEndGroup(GroupState *node)
00268 {
00269 PlanState *outerPlan;
00270
00271 ExecFreeExprContext(&node->ss.ps);
00272
00273
00274 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00275
00276 outerPlan = outerPlanState(node);
00277 ExecEndNode(outerPlan);
00278 }
00279
00280 void
00281 ExecReScanGroup(GroupState *node)
00282 {
00283 node->grp_done = FALSE;
00284 node->ss.ps.ps_TupFromTlist = false;
00285
00286 ExecClearTuple(node->ss.ss_ScanTupleSlot);
00287
00288
00289
00290
00291
00292 if (node->ss.ps.lefttree &&
00293 node->ss.ps.lefttree->chgParam == NULL)
00294 ExecReScan(node->ss.ps.lefttree);
00295 }