1313#include " engine/QueryExecutionTree.h"
1414#include " index/IndexImpl.h"
1515#include " parser/ParsedQuery.h"
16- #include " util/Generator.h"
17- #include " util/GeneratorConverter.h"
1816#include " util/InputRangeUtils.h"
1917#include " util/Iterators.h"
2018
@@ -366,7 +364,7 @@ Permutation::ScanSpecAndBlocks IndexScan::getScanSpecAndBlocks() const {
366364}
367365
368366// _____________________________________________________________________________
369- Permutation::IdTableGenerator IndexScan::getLazyScan (
367+ CompressedRelationReader::IdTableGeneratorInputRange IndexScan::getLazyScan (
370368 std::optional<std::vector<CompressedBlockMetadata>> blocks) const {
371369 // If there is a LIMIT or OFFSET clause that constrains the scan
372370 // (which can happen with an explicit subquery), we cannot use the prefiltered
@@ -378,12 +376,12 @@ Permutation::IdTableGenerator IndexScan::getLazyScan(
378376 scanSpecAndBlocks_, filteredBlocks, additionalColumns (),
379377 cancellationHandle_, locatedTriplesSnapshot (), getLimitOffset ());
380378
381- return cppcoro::fromInputRange (
382- ad_utility::InputRangeTypeErased<IdTable, LazyScanMetadata>(
383- ad_utility::CachingTransformInputRange <
384- ad_utility::OwningView<Permutation::IdTableGenerator >,
385- decltype (makeApplyColumnSubset ()), LazyScanMetadata>{
386- std::move (lazyScanAllCols), makeApplyColumnSubset ()})) ;
379+ return CompressedRelationReader::IdTableGeneratorInputRange{
380+ ad_utility::CachingTransformInputRange<
381+ ad_utility::OwningView <
382+ CompressedRelationReader::IdTableGeneratorInputRange >,
383+ decltype (makeApplyColumnSubset ()), LazyScanMetadata>{
384+ std::move (lazyScanAllCols), makeApplyColumnSubset ()}} ;
387385};
388386
389387// _____________________________________________________________________________
@@ -394,7 +392,7 @@ std::optional<Permutation::MetadataAndBlocks> IndexScan::getMetadataForScan()
394392};
395393
396394// _____________________________________________________________________________
397- std::array<Permutation::IdTableGenerator , 2 >
395+ std::array<CompressedRelationReader::IdTableGeneratorInputRange , 2 >
398396IndexScan::lazyScanForJoinOfTwoScans (const IndexScan& s1, const IndexScan& s2) {
399397 AD_CONTRACT_CHECK (s1.numVariables_ <= 3 && s2.numVariables_ <= 3 );
400398 AD_CONTRACT_CHECK (s1.numVariables_ >= 1 && s2.numVariables_ >= 1 );
@@ -442,7 +440,8 @@ IndexScan::lazyScanForJoinOfTwoScans(const IndexScan& s1, const IndexScan& s2) {
442440}
443441
444442// _____________________________________________________________________________
445- Permutation::IdTableGenerator IndexScan::lazyScanForJoinOfColumnWithScan (
443+ CompressedRelationReader::IdTableGeneratorInputRange
444+ IndexScan::lazyScanForJoinOfColumnWithScan (
446445 ql::span<const Id> joinColumn) const {
447446 AD_EXPENSIVE_CHECK (ql::ranges::is_sorted (joinColumn));
448447 AD_CORRECTNESS_CHECK (numVariables_ <= 3 && numVariables_ > 0 );
@@ -461,9 +460,8 @@ Permutation::IdTableGenerator IndexScan::lazyScanForJoinOfColumnWithScan(
461460
462461// _____________________________________________________________________________
463462void IndexScan::updateRuntimeInfoForLazyScan (const LazyScanMetadata& metadata) {
464- updateRuntimeInformationWhenOptimizedOut (
465- RuntimeInformation::Status::lazilyMaterialized);
466463 auto & rti = runtimeInfo ();
464+ rti.status_ = RuntimeInformation::Status::lazilyMaterialized;
467465 rti.numRows_ = metadata.numElementsYielded_ ;
468466 rti.totalTime_ = metadata.blockingTime_ ;
469467 rti.addDetail (" num-blocks-read" , metadata.numBlocksRead_ );
@@ -481,6 +479,7 @@ void IndexScan::updateRuntimeInfoForLazyScan(const LazyScanMetadata& metadata) {
481479 updateIfPositive (metadata.numBlocksPostprocessed_ ,
482480 " num-blocks-postprocessed" );
483481 updateIfPositive (metadata.numBlocksWithUpdate_ , " num-blocks-with-update" );
482+ signalQueryUpdate ();
484483}
485484
486485// Store a Generator and its corresponding iterator as well as unconsumed values
@@ -629,13 +628,24 @@ Result::LazyResult IndexScan::createPrefilteredJoinSide(
629628Result::LazyResult IndexScan::createPrefilteredIndexScanSide (
630629 std::shared_ptr<SharedGeneratorState> innerState) {
631630 using LoopControl = ad_utility::LoopControl<Result::IdTableVocabPair>;
631+ using namespace std ::chrono_literals;
632632
633633 auto range = ad_utility::InputRangeFromLoopControlGet{
634634 [this , state = std::move (innerState),
635635 metadata = LazyScanMetadata{}]() mutable {
636636 // Handle UNDEF case using LoopControl pattern
637637 if (state->hasUndef ()) {
638- return LoopControl::breakWithYieldAll (chunkedIndexScan ());
638+ auto scan = std::make_shared<
639+ CompressedRelationReader::IdTableGeneratorInputRange>(
640+ getLazyScan ());
641+ scan->details ().numBlocksAll_ =
642+ getMetadataForScan ().value ().sizeBlockMetadata_ ;
643+ return LoopControl::breakWithYieldAll (
644+ ad_utility::CachingTransformInputRange (*scan, [this , scan](
645+ auto & table) {
646+ updateRuntimeInfoForLazyScan (scan->details ());
647+ return Result::IdTableVocabPair{std::move (table), LocalVocab{}};
648+ }));
639649 }
640650
641651 auto & pendingBlocks = state->pendingBlocks_ ;
@@ -648,6 +658,8 @@ Result::LazyResult IndexScan::createPrefilteredIndexScanSide(
648658 }
649659 state->fetch ();
650660 }
661+ metadata.numBlocksAll_ = state->metaBlocks_ .sizeBlockMetadata_ ;
662+ updateRuntimeInfoForLazyScan (metadata);
651663
652664 // We now have non-empty pending blocks
653665 auto scan = getLazyScan (std::move (pendingBlocks));
@@ -658,19 +670,16 @@ Result::LazyResult IndexScan::createPrefilteredIndexScanSide(
658670
659671 // Transform the scan to Result::IdTableVocabPair and yield all
660672 auto transformedScan = ad_utility::CachingTransformInputRange (
661- std::move (scan), [](auto & table) {
662- return Result::IdTableVocabPair{std::move (table), LocalVocab{}};
663- });
664-
665- // Use CallbackOnEndView to aggregate metadata after scan is consumed
666- auto callback = ad_utility::makeAssignableLambda (
667- [&metadata, &scanDetails]() mutable {
673+ std::move (scan),
674+ [&metadata, &scanDetails,
675+ originalMetadata = metadata](auto & table) mutable {
676+ // Make sure we don't add everything more than once.
677+ metadata = originalMetadata;
668678 metadata.aggregate (scanDetails);
679+ return Result::IdTableVocabPair{std::move (table), LocalVocab{}};
669680 });
670681
671- auto scanWithCallback = ad_utility::CallbackOnEndView{
672- std::move (transformedScan), std::move (callback)};
673- return LoopControl::yieldAll (std::move (scanWithCallback));
682+ return LoopControl::yieldAll (std::move (transformedScan));
674683 }};
675684 return Result::LazyResult{std::move (range)};
676685}
0 commit comments