| 153 | } |
| 154 | |
| 155 | RowVectorPtr TableScan::getOutput() { |
| 156 | SuspendedSection suspendedSection(driverCtx_->driver); |
| 157 | auto exitCurStatusGuard = folly::makeGuard([this]() { curStatus_ = ""; }); |
| 158 | |
| 159 | if (noMoreSplits_) { |
| 160 | return nullptr; |
| 161 | } |
| 162 | |
| 163 | const auto& queryConfig = operatorCtx_->task()->queryCtx()->queryConfig(); |
| 164 | |
| 165 | curStatus_ = "getOutput: enter"; |
| 166 | const auto startTimeMs = getCurrentTimeMs(); |
| 167 | for (;;) { |
| 168 | if (needNewSplit_) { |
| 169 | // Check if our Task needs us to yield or we've been running for too long |
| 170 | // w/o producing a result. In this case we return with the Yield blocking |
| 171 | // reason and an already fulfilled future. |
| 172 | curStatus_ = "getOutput: task->shouldStop"; |
| 173 | const StopReason taskStopReason = driverCtx_->task->shouldStop(); |
| 174 | if (shouldStop(taskStopReason) || |
| 175 | shouldYield(taskStopReason, startTimeMs)) { |
| 176 | blockingReason_ = BlockingReason::kYield; |
| 177 | blockingFuture_ = ContinueFuture{folly::Unit{}}; |
| 178 | // A point for test code injection. |
| 179 | BOLT_TEST_ADJUST( |
| 180 | "bytedance::bolt::exec::TableScan::getOutput::bail", this); |
| 181 | return nullptr; |
| 182 | } |
| 183 | |
| 184 | // A point for test code injection. |
| 185 | BOLT_TEST_ADJUST("bytedance::bolt::exec::TableScan::getOutput", this); |
| 186 | |
| 187 | exec::Split split; |
| 188 | curStatus_ = "getOutput: task->getSplitOrFuture"; |
| 189 | blockingReason_ = driverCtx_->task->getSplitOrFuture( |
| 190 | driverCtx_->splitGroupId, |
| 191 | planNodeId(), |
| 192 | split, |
| 193 | blockingFuture_, |
| 194 | maxPreloadedSplits_, |
| 195 | splitPreloader_); |
| 196 | if (blockingReason_ != BlockingReason::kNotBlocked) { |
| 197 | return nullptr; |
| 198 | } |
| 199 | |
| 200 | if (!split.hasConnectorSplit()) { |
| 201 | noMoreSplits_ = true; |
| 202 | pendingDynamicFilters_.clear(); |
| 203 | if (dataSource_) { |
| 204 | curStatus_ = "getOutput: noMoreSplits_=1, updating stats_"; |
| 205 | auto connectorStats = dataSource_->runtimeStats(); |
| 206 | auto lockedStats = stats_.wlock(); |
| 207 | if (connectorStats.count("rawBytesRead<4k") > 0) { |
| 208 | LOG(INFO) |
| 209 | << "IO pattern: " |
| 210 | << "totalBytesRead: " |
| 211 | << succinctBytes(connectorStats.at("rawBytesRead").value) |
| 212 | << ", totalScanTime: " |
nothing calls this directly
no test coverage detected