* Read the next tuple for gather merge. * * Fetch the sorted tuple out of the heap. */
| 545 | * Fetch the sorted tuple out of the heap. |
| 546 | */ |
| 547 | static TupleTableSlot * |
| 548 | gather_merge_getnext(GatherMergeState *gm_state) |
| 549 | { |
| 550 | int i; |
| 551 | |
| 552 | if (!gm_state->gm_initialized) |
| 553 | { |
| 554 | /* |
| 555 | * First time through: pull the first tuple from each participant, and |
| 556 | * set up the heap. |
| 557 | */ |
| 558 | gather_merge_init(gm_state); |
| 559 | } |
| 560 | else |
| 561 | { |
| 562 | /* |
| 563 | * Otherwise, pull the next tuple from whichever participant we |
| 564 | * returned from last time, and reinsert that participant's index into |
| 565 | * the heap, because it might now compare differently against the |
| 566 | * other elements of the heap. |
| 567 | */ |
| 568 | i = DatumGetInt32(binaryheap_first(gm_state->gm_heap)); |
| 569 | |
| 570 | if (gather_merge_readnext(gm_state, i, false)) |
| 571 | binaryheap_replace_first(gm_state->gm_heap, Int32GetDatum(i)); |
| 572 | else |
| 573 | { |
| 574 | /* reader exhausted, remove it from heap */ |
| 575 | (void) binaryheap_remove_first(gm_state->gm_heap); |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | if (binaryheap_empty(gm_state->gm_heap)) |
| 580 | { |
| 581 | /* All the queues are exhausted, and so is the heap */ |
| 582 | gather_merge_clear_tuples(gm_state); |
| 583 | return NULL; |
| 584 | } |
| 585 | else |
| 586 | { |
| 587 | /* Return next tuple from whichever participant has the leading one */ |
| 588 | i = DatumGetInt32(binaryheap_first(gm_state->gm_heap)); |
| 589 | return gm_state->gm_slots[i]; |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | /* |
| 594 | * Read tuple(s) for given reader in nowait mode, and load into its tuple |
no test coverage detected