* Store the next tuple for a given reader into the appropriate slot. * * Returns true if successful, false if not (either reader is exhausted, * or we didn't want to wait for a tuple). Sets done flag if reader * is found to be exhausted. */
| 634 | * is found to be exhausted. |
| 635 | */ |
| 636 | static bool |
| 637 | gather_merge_readnext(GatherMergeState *gm_state, int reader, bool nowait) |
| 638 | { |
| 639 | GMReaderTupleBuffer *tuple_buffer; |
| 640 | MinimalTuple tup; |
| 641 | |
| 642 | /* |
| 643 | * If we're being asked to generate a tuple from the leader, then we just |
| 644 | * call ExecProcNode as normal to produce one. |
| 645 | */ |
| 646 | if (reader == 0) |
| 647 | { |
| 648 | if (gm_state->need_to_scan_locally) |
| 649 | { |
| 650 | PlanState *outerPlan = outerPlanState(gm_state); |
| 651 | TupleTableSlot *outerTupleSlot; |
| 652 | EState *estate = gm_state->ps.state; |
| 653 | |
| 654 | /* Install our DSA area while executing the plan. */ |
| 655 | estate->es_query_dsa = gm_state->pei ? gm_state->pei->area : NULL; |
| 656 | outerTupleSlot = ExecProcNode(outerPlan); |
| 657 | estate->es_query_dsa = NULL; |
| 658 | |
| 659 | if (!TupIsNull(outerTupleSlot)) |
| 660 | { |
| 661 | gm_state->gm_slots[0] = outerTupleSlot; |
| 662 | return true; |
| 663 | } |
| 664 | /* need_to_scan_locally serves as "done" flag for leader */ |
| 665 | gm_state->need_to_scan_locally = false; |
| 666 | } |
| 667 | return false; |
| 668 | } |
| 669 | |
| 670 | /* Otherwise, check the state of the relevant tuple buffer. */ |
| 671 | tuple_buffer = &gm_state->gm_tuple_buffers[reader - 1]; |
| 672 | |
| 673 | if (tuple_buffer->nTuples > tuple_buffer->readCounter) |
| 674 | { |
| 675 | /* Return any tuple previously read that is still buffered. */ |
| 676 | tup = tuple_buffer->tuple[tuple_buffer->readCounter++]; |
| 677 | } |
| 678 | else if (tuple_buffer->done) |
| 679 | { |
| 680 | /* Reader is known to be exhausted. */ |
| 681 | return false; |
| 682 | } |
| 683 | else |
| 684 | { |
| 685 | /* Read and buffer next tuple. */ |
| 686 | tup = gm_readnext_tuple(gm_state, |
| 687 | reader, |
| 688 | nowait, |
| 689 | &tuple_buffer->done); |
| 690 | if (!tup) |
| 691 | return false; |
| 692 | |
| 693 | /* |
no test coverage detected