First run always fails due to arrowScanState.scanCompleted == true because either scanState.source = NONE or scanState.currentBatchIdx = INVALID_NODE_GROUP_IDX on the first run(look at initScanState function) tableScanSharedState.nextMorsel will drive scanInternal completely
| 80 | // run(look at initScanState function) tableScanSharedState.nextMorsel will drive scanInternal |
| 81 | // completely |
| 82 | bool ArrowNodeTable::scanInternal([[maybe_unused]] transaction::Transaction* transaction, |
| 83 | TableScanState& scanState) { |
| 84 | auto& arrowScanState = scanState.cast<ArrowNodeTableScanState>(); |
| 85 | if (arrowScanState.scanCompleted) { |
| 86 | return false; |
| 87 | } |
| 88 | |
| 89 | if (arrowScanState.currentBatchIdx >= arrays.size() || |
| 90 | arrowScanState.currentMorselStartOffset >= arrowScanState.currentMorselEndOffset) { |
| 91 | arrowScanState.scanCompleted = true; |
| 92 | return false; |
| 93 | } |
| 94 | |
| 95 | const auto& batch = arrays[arrowScanState.currentBatchIdx]; |
| 96 | auto batchLength = getArrowBatchLength(batch); |
| 97 | |
| 98 | if (batchLength == 0 || !batch.children || !schema.children || batch.n_children <= 0) { |
| 99 | arrowScanState.scanCompleted = true; |
| 100 | return false; |
| 101 | } |
| 102 | |
| 103 | scanState.resetOutVectors(); |
| 104 | |
| 105 | // Calculate the size of the current morsel |
| 106 | auto morselStart = arrowScanState.currentMorselStartOffset; |
| 107 | auto morselEnd = std::min((uint64_t)arrowScanState.currentMorselEndOffset, batchLength); |
| 108 | auto outputSize = static_cast<uint64_t>(morselEnd - morselStart); |
| 109 | |
| 110 | auto nextGlobalRowOffset = batchStartOffsets[arrowScanState.currentBatchIdx] + morselStart; |
| 111 | |
| 112 | scanState.outState->getSelVectorUnsafe().setSelSize(outputSize); |
| 113 | |
| 114 | NodeTable::applySemiMaskFilter(scanState, nextGlobalRowOffset, outputSize, |
| 115 | scanState.outState->getSelVectorUnsafe()); |
| 116 | |
| 117 | if (scanState.outState->getSelVector().getSelSize() == 0) { |
| 118 | return false; |
| 119 | } |
| 120 | |
| 121 | const auto outputToArrowColumnIdx = getOutputToArrowColumnIdx(scanState.columnIDs); |
| 122 | DASSERT(scanState.outputVectors.size() == outputToArrowColumnIdx.size()); |
| 123 | copyArrowMorselToOutputVectors(batch, arrowScanState.currentMorselStartOffset, outputSize, |
| 124 | scanState.outputVectors, outputToArrowColumnIdx); |
| 125 | |
| 126 | auto tableID = this->getTableID(); |
| 127 | for (uint64_t i = 0; i < outputSize; ++i) { |
| 128 | auto& nodeID = scanState.nodeIDVector->getValue<common::nodeID_t>(i); |
| 129 | nodeID.tableID = tableID; |
| 130 | nodeID.offset = nextGlobalRowOffset + i; |
| 131 | } |
| 132 | |
| 133 | arrowScanState.currentMorselStartOffset += outputSize; |
| 134 | |
| 135 | return true; |
| 136 | } |
| 137 | |
| 138 | common::node_group_idx_t ArrowNodeTable::getNumBatches( |
| 139 | [[maybe_unused]] const transaction::Transaction* transaction) const { |
nothing calls this directly
no test coverage detected