| 317 | } // namespace |
| 318 | |
| 319 | void RowVector::copyRanges( |
| 320 | const BaseVector* source, |
| 321 | const folly::Range<const CopyRange*>& ranges) { |
| 322 | if (ranges.empty()) { |
| 323 | return; |
| 324 | } |
| 325 | |
| 326 | if (isAllNullVector(*source)) { |
| 327 | BaseVector::setNulls(mutableRawNulls(), ranges, true); |
| 328 | return; |
| 329 | } |
| 330 | |
| 331 | auto minTargetIndex = std::numeric_limits<vector_size_t>::max(); |
| 332 | auto maxTargetIndex = std::numeric_limits<vector_size_t>::min(); |
| 333 | applyToEachRange(ranges, [&](auto targetIndex, auto sourceIndex, auto count) { |
| 334 | minTargetIndex = std::min(minTargetIndex, targetIndex); |
| 335 | maxTargetIndex = std::max(maxTargetIndex, targetIndex + count); |
| 336 | }); |
| 337 | |
| 338 | SelectivityVector rows(maxTargetIndex); |
| 339 | rows.setValidRange(0, minTargetIndex, false); |
| 340 | rows.updateBounds(); |
| 341 | for (auto i = 0; i < children_.size(); ++i) { |
| 342 | BaseVector::ensureWritable( |
| 343 | rows, type()->asRow().childAt(i), pool(), children_[i]); |
| 344 | } |
| 345 | |
| 346 | DecodedVector decoded(*source); |
| 347 | if (decoded.isIdentityMapping() && !decoded.mayHaveNulls()) { |
| 348 | if (rawNulls_) { |
| 349 | setNulls(mutableRawNulls(), ranges, false); |
| 350 | } |
| 351 | auto* rowSource = source->loadedVector()->as<RowVector>(); |
| 352 | for (int i = 0; i < children_.size(); ++i) { |
| 353 | if (rowSource->childAt(i)) { |
| 354 | children_[i]->copyRanges(rowSource->childAt(i)->loadedVector(), ranges); |
| 355 | } else { |
| 356 | children_[i].reset(); |
| 357 | } |
| 358 | } |
| 359 | } else { |
| 360 | std::vector<BaseVector::CopyRange> baseRanges; |
| 361 | baseRanges.reserve(ranges.size()); |
| 362 | applyToEachRow(ranges, [&](auto targetIndex, auto sourceIndex) { |
| 363 | bool isNull = decoded.isNullAt(sourceIndex); |
| 364 | setNull(targetIndex, isNull); |
| 365 | if (isNull) { |
| 366 | return; |
| 367 | } |
| 368 | auto baseIndex = decoded.index(sourceIndex); |
| 369 | if (!baseRanges.empty() && |
| 370 | baseRanges.back().sourceIndex + 1 == baseIndex && |
| 371 | baseRanges.back().targetIndex + 1 == targetIndex) { |
| 372 | ++baseRanges.back().count; |
| 373 | } else { |
| 374 | baseRanges.push_back({ |
| 375 | .sourceIndex = baseIndex, |
| 376 | .targetIndex = targetIndex, |
no test coverage detected