| 200 | } |
| 201 | |
| 202 | static TupleTableSlot * |
| 203 | execMotionSender(MotionState *node) |
| 204 | { |
| 205 | /* SENDER LOGIC */ |
| 206 | TupleTableSlot *outerTupleSlot; |
| 207 | PlanState *outerNode; |
| 208 | Motion *motion = (Motion *) node->ps.plan; |
| 209 | bool done = false; |
| 210 | |
| 211 | #ifdef MEASURE_MOTION_TIME |
| 212 | struct timeval time1; |
| 213 | struct timeval time2; |
| 214 | |
| 215 | gettimeofday(&time1, NULL); |
| 216 | #endif |
| 217 | |
| 218 | AssertState(motion->motionType == MOTIONTYPE_GATHER || |
| 219 | motion->motionType == MOTIONTYPE_GATHER_SINGLE || |
| 220 | motion->motionType == MOTIONTYPE_HASH || |
| 221 | motion->motionType == MOTIONTYPE_BROADCAST || |
| 222 | motion->motionType == MOTIONTYPE_BROADCAST_WORKERS || |
| 223 | (motion->motionType == MOTIONTYPE_EXPLICIT && motion->segidColIdx > 0)); |
| 224 | Assert(node->ps.state->interconnect_context); |
| 225 | |
| 226 | while (!done) |
| 227 | { |
| 228 | /* grab TupleTableSlot from our child. */ |
| 229 | outerNode = outerPlanState(node); |
| 230 | outerTupleSlot = ExecProcNode(outerNode); |
| 231 | |
| 232 | #ifdef MEASURE_MOTION_TIME |
| 233 | gettimeofday(&time2, NULL); |
| 234 | |
| 235 | node->otherTime.tv_sec += time2.tv_sec - time1.tv_sec; |
| 236 | node->otherTime.tv_usec += time2.tv_usec - time1.tv_usec; |
| 237 | |
| 238 | while (node->otherTime.tv_usec < 0) |
| 239 | { |
| 240 | node->otherTime.tv_usec += 1000000; |
| 241 | node->otherTime.tv_sec--; |
| 242 | } |
| 243 | |
| 244 | while (node->otherTime.tv_usec >= 1000000) |
| 245 | { |
| 246 | node->otherTime.tv_usec -= 1000000; |
| 247 | node->otherTime.tv_sec++; |
| 248 | } |
| 249 | #endif |
| 250 | |
| 251 | if (done || TupIsNull(outerTupleSlot)) |
| 252 | { |
| 253 | doSendEndOfStream(motion, node); |
| 254 | done = true; |
| 255 | } |
| 256 | else if (motion->motionType == MOTIONTYPE_GATHER_SINGLE && |
| 257 | GpIdentity.segindex != (gp_session_id % node->numInputSegs)) |
| 258 | { |
| 259 | /* |
no test coverage detected