* ExecTupleSplit - * * ExecTupleSplit receives tuples from its outer subplan. Every * input tuple will generate n output tuples (n is the number of * the DQAs exprs). Each output tuple only contain one DQA expr and * all GROUP BY exprs. */
| 167 | * all GROUP BY exprs. |
| 168 | */ |
| 169 | static TupleTableSlot * |
| 170 | ExecTupleSplit(PlanState *pstate) |
| 171 | { |
| 172 | TupleSplitState *node = castNode(TupleSplitState, pstate); |
| 173 | TupleTableSlot *result; |
| 174 | ExprContext *econtext; |
| 175 | TupleSplit *plan; |
| 176 | bool filter_out = false; |
| 177 | |
| 178 | econtext = node->ss.ps.ps_ExprContext; |
| 179 | plan = (TupleSplit *)node->ss.ps.plan; |
| 180 | |
| 181 | do { |
| 182 | /* if all DQAs of the last slot were processed, get a new slot */ |
| 183 | if (node->currentExprId == 0) |
| 184 | { |
| 185 | node->outerslot = ExecProcNode(outerPlanState(node)); |
| 186 | |
| 187 | if (TupIsNull(node->outerslot)) |
| 188 | return NULL; |
| 189 | |
| 190 | slot_getsomeattrs(node->outerslot, node->maxAttrNum); |
| 191 | |
| 192 | /* store original tupleslot isnull array */ |
| 193 | memcpy(node->isnull_orig, node->outerslot->tts_isnull, |
| 194 | node->outerslot->tts_nvalid * sizeof(bool)); |
| 195 | } |
| 196 | |
| 197 | econtext->ecxt_outertuple = node->outerslot; |
| 198 | |
| 199 | /* The filter is pushed down from relative DQA */ |
| 200 | ExprState * filter = NULL; |
| 201 | if (node->currentExprId < node->numDisDQAs) |
| 202 | filter = node->agg_filter_array[node->currentExprId]; |
| 203 | |
| 204 | if (filter) |
| 205 | { |
| 206 | Datum res; |
| 207 | bool isnull; |
| 208 | |
| 209 | res = ExecEvalExprSwitchContext(filter, econtext, &isnull); |
| 210 | |
| 211 | if (isnull || !DatumGetBool(res)) |
| 212 | { |
| 213 | /* skip tuple split once, if the tuple filter out */ |
| 214 | node->currentExprId = (node->currentExprId + 1) % node->numDisDQAs; |
| 215 | filter_out = true; |
| 216 | } |
| 217 | else |
| 218 | filter_out = false; |
| 219 | } |
| 220 | else |
| 221 | filter_out = false; |
| 222 | |
| 223 | } while(filter_out); |
| 224 | |
| 225 | /* reset the isnull array to the original state */ |
| 226 | bool *isnull = node->outerslot->tts_isnull; |
nothing calls this directly
no test coverage detected