8000 Feature/aql subquery execution block impl execute implementation expected number of rows by mchacki · Pull Request #11274 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content

Feature/aql subquery execution block impl execute implementation expected number of rows #11274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
35fe0e5
Added first draft of AqlCallObject
mchacki Oct 22, 2019
ead968c
Added AqlItemBlockInputRange
goedderz Oct 22, 2019
7c6bcba
Added Header file for AqlCallStack with comments. No implementation yet.
mchacki Oct 22, 2019
22d2977
Added AqlCallStack first draft implementation. Made everything compile
mchacki Oct 22, 2019
3ab4488
Added empty dummy stubs for execute() in ExecutionBlock
mchacki Oct 22, 2019
b079d78
Implementation of new API in FilterExecutor. Rough implementation in …
mchacki Oct 24, 2019
eb120a0
Fixed off by one error in InputRange. Fixed FilterExecutor
mchacki Oct 24, 2019
cb2cef2
Added some more tests if executor cannot fulfill atMost
mchacki Oct 24, 2019
a46941e
Added heplper functions to the AqlCall struct to avoid mangeling arou…
mchacki Oct 25, 2019
e248e45
Add a member DataRange to ExecutionBlockImpl. Also now all Fetcher ex…
mchacki Oct 25, 2019
c40cfc0
Added preliminary minimal implementation of execute to DependencyProx…
mchacki Oct 25, 2019
dccbbcf
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
hkernbach Oct 28, 2019
2368252
added first implementation of count collect datarange produceRows fun…
hkernbach Oct 28, 2019
acb414f
Revert "added first implementation of count collect datarange produce…
hkernbach Oct 28, 2019
b66f314
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Oct 29, 2019
5b0b8ce
Merge branch 'devel' into feature/AqlSubqueryOperationsStack
Oct 30, 2019
e0205b5
First draft of execute implementation, not yet handling ShadowRows th…
mchacki Oct 30, 2019
3eff385
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Oct 30, 2019
96c0fda
First working draft of execute() call in ExecutionBlockImpl. Tests ar…
mchacki Oct 31, 2019
4d019a1
Removed non finished implementation from this Branch. It moved to sep…
mchacki Oct 31, 2019
aa275b4 8000
working - not done yet
hkernbach Nov 8, 2019
fd33b7f
Revert "working - not done yet"
hkernbach Nov 8, 2019
4d030f4
Intermediate devel pull, might not compile
mchacki Nov 18, 2019
0300467
Finally merged with latest devel, seems to work
mchacki Nov 18, 2019
907628e
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Nov 18, 2019
11be23e
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Nov 18, 2019
c703b11
first implementation of a ShadowRow fetching interface on AqlItemBloc…
mchacki Nov 18, 2019
7911767
single row fetcher, execute + tests
hkernbach Nov 20, 2019
45f7771
Merge
hkernbach Nov 20, 2019
b91be5f
Fixed SingleRowFetcherTest. Also an AqlItemBlockInputRange can now ha…
mchacki Nov 27, 2019
8ba440c
Another fix on handling of shadow rows in InputRanges
mchacki Nov 27, 2019
b5dacbd
Improved human readable output of SortLimit test, while validating th…
mchacki Nov 27, 2019
a6281da
Removed debug profile execution of a query
mchacki Nov 27, 2019
7a8a1dc
Use simpleVPack printing for Trace of Execute, better to read by humans
mchacki Nov 27, 2019
40569e0
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Nov 28, 2019
d636a10
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Nov 28, 2019
2b13d48
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Nov 28, 2019
8307d15
Added tests for AqlItemBlockInputRange and adjusted implementation ac…
mchacki Nov 29, 2019
c973149
Fixed issue where ExecutionBlockImpl returns DONE, although there are…
mchacki Dec 2, 2019
d83e3ac
Final modification of ShadowRows in FilterExecutor. All but profiling…
mchacki Dec 2, 2019
9c8ae9d
Removed debug log includes
mchacki Dec 2, 2019
990c487
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Dec 3, 2019
e4dcdbc
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Dec 3, 2019
292bd2a
Moved responsibility for the client call into the output row. This ca…
mchacki Dec 3, 2019
ba3eea6
Fixed FilterExecutorTest
mchacki Dec 4, 2019
d8f80f9
Expose required features to AqlCall controlled by the output aql item…
mchacki Dec 4, 2019
6d18de7
Fixed bug with AqlCallStack pop operation that actually caused invali…
mchacki Dec 5, 2019
c84be59
outputRow now honors limits whan called for isFull.
mchacki Dec 5, 2019
2eb29ad
Fixed isFull() in OutputAqlItemRow
mchacki Dec 5, 2019
7151867
Use the inbound call in skipRows for executors, in order to do a more…
mchacki Dec 5, 2019
26c1996
Make linker happy with operator< on CallLimit
mchacki Dec 6, 2019
dfd6d49
Implement operator+ on AqlCall::Limit, also use std::visit for readab…
mchacki Dec 6, 2019
86db29c
FilterExecutor getSome now propagates offset + min(limits) to upstrea…
mchacki Dec 6, 2019
aa4323f
Fixed profiler tests for filter. These cannot be guaranteed anymore a…
mchacki Dec 6, 2019
63f76e5
Fixed JSLint
mchacki Dec 6, 2019
df27560
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Dec 13, 2019
7cddcfa
Remove special casing for FilterExecutor
Dec 13, 2019
73cf9af
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Dec 13, 2019
63b0da1
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
Dec 13, 2019
247e668
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Dec 13, 2019
c9d1f2f
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Dec 13, 2019
9123516
Add skeleton skip code
Dec 13, 2019
b27d945
Replace C&P accident
Dec 13, 2019
7ad6c9e
Simplify and implement skip for new executor interface
Dec 13, 2019
64186d3
Fixup skipping for filter executor
Dec 13, 2019
266b8ad
Rename some methods for clarity and consistency
Dec 20, 2019
1628196
Introduce function to allocate an output block
Dec 24, 2019
7e8180f
Fix skipSome simulation bug
Dec 24, 2019
4e86d17
Some small cleanups
Dec 24, 2019
cfaf773
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Dec 24, 2019
1ec2b8a
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Jan 2, 2020
f5ef0e7
Replaced assertion on atMost on the output size. Otherwise we got int…
mchacki Jan 2, 2020
862d316
Attempt at fixing execute
Jan 6, 2020
44d60bc
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Jan 10, 2020
2f938c5
Merge branch 'feature/AqlSubqueryOperationsStack' into feature/AqlSub…
goedderz Jan 10, 2020
f3ec9c2
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Jan 13, 2020
397fee6
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Jan 15, 2020
a79a89e
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Jan 15, 2020
9ee9a0f
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Jan 16, 2020
0624998
Merge branch 'feature/AqlSubqueryOperationsStack' into feature/AqlSub…
goedderz Jan 16, 2020
12b1b2b
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Jan 17, 2020
131c004
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Jan 17, 2020
a656f39
Fix merge conflict
goedderz Jan 17, 2020
508461e
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Jan 17, 2020
41c6d36
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Jan 23, 2020
e03496a
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Jan 23, 2020
fdd0fed
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Jan 23, 2020
7ac26a3
Merge branch 'devel' into feature/AqlSubqueryOperationsStack
Jan 24, 2020
c9c54e3
Merge branch 'feature/AqlSubqueryOperationsStack' into feature/AqlSub…
Jan 24, 2020
beb7003
Feature/aql subquery execution block impl execute implementation exec…
mchacki Jan 24, 2020
ba5435b
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Jan 24, 2020
1d5e5a5
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Jan 24, 2020
5b3e717
Feature/aql subquery execution block impl execute implementation shor…
mchacki Jan 27, 2020
56d9cf0
Feature/aql subquery execution block impl execute implementation exec…
mchacki Jan 28, 2020
7222d3e
Feature/aql subquery execution block impl execute implementation sort…
Jan 31, 2020
efd40c3
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Feb 3, 2020
2b2625b
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Feb 3, 2020
30d9f27
ReturnExecutor New style (#10831)
Feb 11, 2020
d4d3cd3
Merge branch 'devel' into feature/AqlSubqueryExecutionBlockImplExecut…
Feb 11, 2020
4028320
Merge branch 'devel' into feature/AqlSubqueryOperationsStack
Feb 11, 2020
3596c54
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Feb 12, 2020
a576003
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Feb 12, 2020
6359f0c
Tweak ExecutorTestHelper to test pipelines
Feb 12, 2020
c509e18
Revert "Tweak ExecutorTestHelper to test pipelines"
Feb 12, 2020
94da545
Added Stats return value to skipRowsRange (#11081)
mchacki Feb 13, 2020
518c042
Additional Assertion in ExecutionBlockImpl (#11077)
mchacki Feb 13, 2020
54043f3
Feature/aql subquery operations stack id executor (#10986)
mchacki Feb 14, 2020
3963940
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Feb 14, 2020
da03a1c
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Feb 14, 2020
44fdb29
Replaced the operator== and operator!= with `isSameBlockAndIndex`. (#…
Feb 14, 2020
95a7326
New style IndexExecutor. (#11029)
Feb 14, 2020
10cc623
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Feb 17, 2020
df13bbb
Merge branch 'feature/AqlSubqueryOperationsStack' of ssh://github.com…
mchacki Feb 17, 2020
2157a75
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Feb 17, 2020
dac0a10
Feature/aql subquery execution block impl execute implementation debu…
mchacki Feb 18, 2020
1871aeb
Feature/aql subquery operations stack hashed collect executor (#11103)
mchacki Feb 18, 2020
1a54762
Feature/aql subquery operations stack enumerate list (#10988)
hkernbach Feb 18, 2020
6d6edc9
Feature/aql subquery execution block impl execute implementation inje…
mchacki Feb 20, 2020
2077958
Tweak ExecutorTestHelper to test pipelines (#11079)
markuspf Feb 20, 2020
2e2e214
AQL execute in LimitExecutor (#10886)
goedderz Feb 21, 2020
e7f36c3
Feature/aql subquery operations stack calculation exec enumerate exec…
hkernbach Feb 21, 2020
557d5c5
Quickfix for compilation error due to merge
Feb 24, 2020
e6a31b7
Feature/aql subquery execution block impl execute implementation k sh…
markuspf Feb 25, 2020
b81dc94
Feature/aql subquery execution block impl execute implementation trav…
markuspf Feb 25, 2020
d8c41c2
Merge branch 'devel' of github.com:arangodb/arangodb into feature/Aql…
goedderz Feb 25, 2020
4fa0860
Merge branch 'feature/AqlSubqueryOperationsStack' of github.com:arang…
goedderz Feb 25, 2020
4dadc22
Move SubqueryStartExecutor to new interface (#11025)
markuspf Feb 26, 2020
1cd9adb
Feature/aql subquery execute remote node api flag (#11159)
goedderz Feb 27, 2020
be42def
Feature/aql subquery operations stack i research view executor (#11140)
hkernbach Feb 27, 2020
abd2740
Move SingleRemoteModificationExecutor to new interface (#11166)
markuspf Feb 27, 2020
39ecda2
Merge remote-tracking branch 'origin/devel' into feature/AqlSubqueryE…
Feb 27, 2020
9bf96cd
New style DistinctCollect (#11096)
Feb 27, 2020
c2ae621
Feature/aql subquery execution block impl execute implementation nore…
mchacki Feb 28, 2020
4fe26a9
Moved Constrained sort to execute API (#11173)
mchacki Feb 28, 2020
a0d6ec1
Feature/aql subquery operations stack aql item block input matrix (#1…
hkernbach Feb 28, 2020
28b9c04
Feature/aql subquery execute in restaqlhandler (#11175)
goedderz Feb 28, 2020
08ceffe
Support executors with multiple dependencies (#11181)
markuspf Feb 29, 2020
3ae0061
Move ModificationExecutors to new interface (#11165)
markuspf Feb 29, 2020
d4e7299
Feature/aql subquery operations stack materialize executor (#11192)
hkernbach Feb 29, 2020
9a76c0c
Feature/aql subquery execute remote (#11197)
goedderz Feb 29, 2020
98c7eb6
Added test for distinct collect with random order. (#11184)
Feb 29, 2020
609b0ff
Feature/aql subquery execution block impl execute implementation subq…
Feb 29, 2020
9bb106d
Feature/aql subquery execution block impl execute implementation coun…
mchacki Feb 29, 2020
2262370
Activate CalculationExecutors (#11177)
mchacki Feb 29, 2020
c69dc93
Fixed compile bug-due to hidden merge conflict
mchacki Feb 29, 2020
341ef5f
Feature/aql subquery execution block impl execute implementation base…
mchacki Mar 2, 2020
c653260
Fix memory leak in traversal (#11210)
markuspf Mar 3, 2020
41ce860
AqlSubqueryExecutionBlockImplExecuteImplementation use moveValueInto …
markuspf Mar 3, 2020
26242a1
Feature/aql subquery execution block impl execute implementation gath…
mchacki Mar 3, 2020
fd763cb
Feature/aql subquery execute parallel gather (#11215)
goedderz Mar 3, 2020
4794ebe
Feature/aql subquery execute parallel gather 2 (#11221)
goedderz Mar 10, 2020
25de4de
Feature/aql subquery execution block impl execute implementation bypa…
mchacki Mar 12, 2020
cb42580
Add some FilterExecutor and CalculationExecutor tests (#11231)
markuspf Mar 12, 2020
10b24b2
Merge devel into feature/AqlSubqueryExecutionBlockImplExecuteImplemen…
mchacki Mar 12, 2020
4b09567
Fixed assertion in SubqueryStart. On initial call it can be called wi…
mchacki Mar 13, 2020
ace0317
Added methods to count available rows in AqlItemBlockInputRange
mchacki Mar 13, 2020
b8d4b48
Allow a path to Ask the Executor how many rows are going to be produc…
mchacki Mar 13, 2020
94d7729
Let Return and SubqueryExecutors present how many data rows are to be…
mchacki Mar 13, 2020
db8a775
Implement a fast forwarding of Rows in IdExecutor
mchacki Mar 13, 2020
591d877
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Mar 13, 2020
e431ccf
Initialize all the bools
mchacki Mar 13, 2020
7c1069c
Fixed ASAN warning
mchacki Mar 13, 2020
bc40f02
Fixed ASAN warning in ShortestPathExecutor
mchacki Mar 13, 2020
c86f8fe
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 13, 2020
350f6d0
Fixed invalid access in block allocation if input is empty
mchacki Mar 13, 2020
a102483
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Mar 15, 2020
014d1a4
Reactivated expectedNumberOfRows on all SingleRowFetcher executors
mchacki Mar 15, 2020
dafce76
Deactivated Debug Logging in Enumerate Collection Executor test
mchacki Mar 15, 2020
920521b
Fixed SubqueryStartExecutor produceRows estimate
mchacki Mar 15, 2020
33b9d94
For now SubqueryEndExecutor cannot define expected number of rows. We…
mchacki Mar 15, 2020
9f618e4
SubqueryStart will have more output then limit defines (ShadowRow)
mchacki Mar 15, 2020
b00eff8
Fixed Filter numberOfExpectedRows
mchacki Mar 15, 2020
a6fd85c
Removed do-copy row test from ID executor. It now uses a fast-forward…
mchacki Mar 15, 2020
31f0b2e
Only estimate the number of Rows if the range is complete.
mchacki Mar 15, 2020
a6003ea
On Collect nodes we sometimes produce an additional empty row
mchacki Mar 15, 2020
9b853b3
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Mar 15, 2020
37f5e1f
Fixed endles loop in ParallelUnsortedGather, if the initial input is …
mchacki Mar 15, 2020
f4cbf4a
Apply suggestions from code review
mchacki Mar 20, 2020
c558a33
Merge branch 'devel' of ssh://github.com/arangodb/ArangoDB into featu…
mchacki Mar 20, 2020
File filter

Filter by extension

Filter by extension 10000

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions arangod/Aql/AqlItemBlockInputRange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,23 @@ auto AqlItemBlockInputRange::skipAll() noexcept -> std::size_t {
_skipped = 0;
return skipped;
}

auto AqlItemBlockInputRange::countDataRows() const noexcept -> std::size_t {
if (_block == nullptr) {
return 0;
}
auto const& block = getBlock();
return block->size() - block->getShadowRowIndexes().size();
}

auto AqlItemBlockInputRange::countShadowRows() const noexcept -> std::size_t {
if (_block == nullptr) {
return 0;
}
auto const& block = getBlock();
return block->getShadowRowIndexes().size();
}

[[nodiscard]] auto AqlItemBlockInputRange::finalState() const noexcept -> ExecutorState {
return _finalState;
}
16 changes: 16 additions & 0 deletions arangod/Aql/AqlItemBlockInputRange.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ class AqlItemBlockInputRange {

[[nodiscard]] auto skippedInFlight() const noexcept -> std::size_t;

/**
* @brief Count how many datarows are expected in this range
* Used to estimate amount of produced rows
* @return std::size_t
*/
[[nodiscard]] auto countDataRows() const noexcept -> std::size_t;

/**
* @brief Count how many shadowRows are expected in this range
* Used to estimate amount of produced rows
* @return std::size_t
*/
[[nodiscard]] auto countShadowRows() const noexcept -> std::size_t;

[[nodiscard]] auto finalState() const noexcept -> ExecutorState;

private:
bool isIndexValid(std::size_t index) const noexcept;

Expand Down
6 changes: 6 additions & 0 deletions arangod/Aql/CountCollectExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ std::pair<ExecutionState, size_t> CountCollectExecutor::expectedNumberOfRows(siz
return {ExecutionState::HASMORE, 1};
}

auto CountCollectExecutor::expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const
noexcept -> size_t {
return std::min<size_t>(1, call.getLimit());
}

const CountCollectExecutor::Infos& CountCollectExecutor::infos() const noexcept {
return _infos;
}
Expand Down
3 changes: 3 additions & 0 deletions arangod/Aql/CountCollectExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class CountCollectExecutor {

std::pair<ExecutionState, size_t> expectedNumberOfRows(size_t atMost) const;

[[nodiscard]] auto expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const noexcept -> size_t;

private:
Infos const& infos() const noexcept;

Expand Down
12 changes: 12 additions & 0 deletions arangod/Aql/DistinctCollectExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ std::pair<ExecutionState, size_t> DistinctCollectExecutor::expectedNumberOfRows(
return _fetcher.preFetchNumberOfRows(atMost);
}

[[nodiscard]] auto DistinctCollectExecutor::expectedNumberOfRowsNew(
AqlItemBlockInputRange const& input, AqlCall const& call) const noexcept -> size_t {
if (input.finalState() == ExecutorState::DONE) {
// Worst case assumption:
// For every input row we have a new group.
// We will never produce more then asked for
return std::min(call.getLimit(), input.countDataRows());
}
// Otherwise we do not know.
return call.getLimit();
}

void DistinctCollectExecutor::destroyValues() {
// destroy all AqlValues captured
for (auto& value : _seen) {
Expand Down
3 changes: 3 additions & 0 deletions arangod/Aql/DistinctCollectExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ class DistinctCollectExecutor {

std::pair<ExecutionState, size_t> expectedNumberOfRows(size_t atMost) const;

[[nodiscard]] auto expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const noexcept -> size_t;

private:
Infos const& infos() const noexcept;
void destroyValues();
Expand Down
55 changes: 47 additions & 8 deletions arangod/Aql/ExecutionBlockImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ CREATE_HAS_MEMBER_CHECK(skipRows, hasSkipRows);
CREATE_HAS_MEMBER_CHECK(fetchBlockForPassthrough, hasFetchBlockForPassthrough);
CREATE_HAS_MEMBER_CHECK(expectedNumberOfRows, hasExpectedNumberOfRows);
CREATE_HAS_MEMBER_CHECK(skipRowsRange, hasSkipRowsRange);
CREATE_HAS_MEMBER_CHECK(expectedNumberOfRowsNew, hasExpectedNumberOfRowsNew);

#ifdef ARANGODB_USE_GOOGLE_TESTS
// Forward declaration of Test Executors.
Expand Down Expand Up @@ -1032,7 +1033,7 @@ std::pair<ExecutionState, SharedAqlItemBlockPtr> ExecutionBlockImpl<Executor>::r

// TODO: We need to define the size of this block based on Input / Executor / Subquery depth
template <class Executor>
auto ExecutionBlockImpl<Executor>::allocateOutputBlock(AqlCall&& call)
auto ExecutionBlockImpl<Executor>::allocateOutputBlock(AqlCall&& call, DataRange const& inputRange)
-> std::unique_ptr<OutputAqlItemRow> {
if constexpr (Executor::Properties::allowsBlockPassthrough == BlockPassthrough::Enable) {
SharedAqlItemBlockPtr newBlock{nullptr};
Expand All @@ -1047,18 +1048,56 @@ auto ExecutionBlockImpl<Executor>::allocateOutputBlock(AqlCall&& call)

return createOutputRow(newBlock, std::move(call));
} else {
if constexpr (isMultiDepExecutor<Executor>) {
// MultiDepExecutor would require dependency handling.
// We do not have it here.
if (!inputRange.hasShadowRow() && !inputRange.hasDataRow()) {
// On empty input do not yet create output.
// We are going to ask again later
SharedAqlItemBlockPtr newBlock{nullptr};
return createOutputRow(newBlock, std::move(call));
}
} else {
if (!inputRange.hasShadowRow() && !inputRange.hasDataRow() &&
inputRange.upstreamState() == ExecutorState::HASMORE) {
// On empty input do not yet create output.
// We are going to ask again later
SharedAqlItemBlockPtr newBlock{nullptr};
return createOutputRow(newBlock, std::move(call));
}
}

// Non-Passthrough variant, we need to allocate the block ourselfs
size_t blockSize = ExecutionBlock::DefaultBatchSize;
if constexpr (hasExpectedNumberOfRowsNew<Executor>::value) {
blockSize = _executor.expectedNumberOfRowsNew(inputRange, call);
// The executor cannot expect to produce more then the limit!
if constexpr (!std::is_same_v<Executor, SubqueryStartExecutor>) {
// Except the subqueryStartExecutor, it's limit differs
// from it's output (it needs to count the new ShadowRows in addition)
TRI_ASSERT(blockSize <= call.getLimit());
}

blockSize += inputRange.countShadowRows();
// We have an upper bound by DefaultBatchSize;
blockSize = std::min(ExecutionBlock::DefaultBatchSize, blockSize);
}
if (blockSize == 0) {
// There is no data to be produced
SharedAqlItemBlockPtr newBlock{nullptr};
return createOutputRow(newBlock, std::move(call));
}
SharedAqlItemBlockPtr newBlock =
_engine->itemBlockManager().requestBlock(blockSize, _infos.numberOfOutputRegisters());
return createOutputRow(newBlock, std::move(call));
}
}

template <class Executor>
void ExecutionBlockImpl<Executor>::ensureOutputBlock(AqlCall&& call) {
void ExecutionBlockImpl<Executor>::ensureOutputBlock(AqlCall&& call,
DataRange const& inputRange) {
if (_outputItemRow == nullptr || !_outputItemRow->isInitialized()) {
_outputItemRow = allocateOutputBlock(std::move(call));
_outputItemRow = allocateOutputBlock(std::move(call), inputRange);
} else {
_outputItemRow->setCall(std::move(call));
}
Expand Down Expand Up @@ -1251,7 +1290,7 @@ auto ExecutionBlockImpl<Executor>::executeFetcher(AqlCallStack& stack, AqlCallTy
return {state, skipped, _lastRange};
} else if constexpr (executorHasSideEffects<Executor>) {
// If the executor has side effects, we cannot bypass any subqueries
// by skipping them. SO we need to fetch all shadow rows in order to
// by skipping them. So we need to fetch all shadow rows in order to
// trigger this Executor with everthing from above.
// NOTE: The Executor needs to discard shadowRows, and do the accouting.
static_assert(std::is_same_v<AqlCall, std::decay_t<decltype(aqlCall)>>);
Expand Down Expand Up @@ -1939,9 +1978,9 @@ ExecutionBlockImpl<Executor>::executeWithoutTrace(AqlCallStack stack) {
TRI_ASSERT(!stack.empty());
AqlCall const& subqueryCall = stack.peek();
AqlCall copyCall = subqueryCall;
ensureOutputBlock(std::move(copyCall));
ensureOutputBlock(std::move(copyCall), _lastRange);
} else {
ensureOutputBlock(std::move(clientCall));
ensureOutputBlock(std::move(clientCall), _lastRange);
}
TRI_ASSERT(_outputItemRow);
TRI_ASSERT(!_executorReturnedDone);
Expand Down Expand Up @@ -2133,9 +2172,9 @@ ExecutionBlockImpl<Executor>::executeWithoutTrace(AqlCallStack stack) {
TRI_ASSERT(!stack.empty());
AqlCall const& subqueryCall = stack.peek();
AqlCall copyCall = subqueryCall;
ensureOutputBlock(std::move(copyCall));
ensureOutputBlock(std::move(copyCall), _lastRange);
} else {
ensureOutputBlock(std::move(clientCall));
ensureOutputBlock(std::move(clientCall), _lastRange);
}

TRI_ASSERT(!_outputItemRow->allRowsUsed());
Expand Down
6 changes: 3 additions & 3 deletions arangod/Aql/ExecutionBlockImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,12 @@ class ExecutionBlockImpl final : public ExecutionBlock {
[[nodiscard]] ExecutionState fetchShadowRowInternal();

// Allocate an output block and install a call in it
[[nodiscard]] auto allocateOutputBlock(AqlCall&& call)
[[nodiscard]] auto allocateOutputBlock(AqlCall&& call, DataRange const& inputRange)
-> std::unique_ptr<OutputAqlItemRow>;

// Ensure that we have an output block of the desired dimenstions
// Ensure that we have an output block of the desired dimensions
// Will as a side effect modify _outputItemRow
void ensureOutputBlock(AqlCall&& call);
void ensureOutputBlock(AqlCall&& call, DataRange const& inputRange);

// Compute the next state based on the given call.
// Can only be one of Skip/Produce/FullCount/FastForward/Done
Expand Down
11 changes: 11 additions & 0 deletions arangod/Aql/FilterExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,14 @@ auto FilterExecutor::produceRows(AqlItemBlockInputRange& inputRange, OutputAqlIt
(std::min)(clientCall.softLimit, clientCall.hardLimit);
return {inputRange.upstreamState(), stats, upstreamCall};
}

[[nodiscard]] auto FilterExecutor::expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const
noexcept -> size_t {
if (input.finalState() == ExecutorState::DONE) {
return std::min(call.getLimit(), input.countDataRows());
}
// We do not know how many more rows will be returned from upstream.
// So we can only overestimate
return call.getLimit();
}
3 changes: 3 additions & 0 deletions arangod/Aql/FilterExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ class FilterExecutor {

[[nodiscard]] std::pair<ExecutionState, size_t> expectedNumberOfRows(size_t atMost) const;

[[nodiscard]] auto expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const noexcept -> size_t;

private:
Infos& _infos;
Fetcher& _fetcher;
Expand Down
22 changes: 22 additions & 0 deletions arangod/Aql/HashedCollectExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,28 @@ std::pair<ExecutionState, size_t> HashedCollectExecutor::expectedNumberOfRows(si
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}

[[nodiscard]] auto HashedCollectExecutor::expectedNumberOfRowsNew(
AqlItemBlockInputRange const& input, AqlCall const& call) const noexcept -> size_t {
if (!_isInitialized) {
if (input.finalState() == ExecutorState::DONE) {
// Worst case assumption:
// For every input row we have a new group.
// We will never produce more then asked for
auto estOnInput = input.countDataRows();
if (estOnInput == 0 && _infos.getGroupRegisters().empty()) {
// Special case, on empty input we will produce 1 output
estOnInput = 1;
}
return std::min(call.getLimit(), estOnInput);
}
// Otherwise we do not know.
return call.getLimit();
10000 }
// We know how many groups we have left
return std::min<size_t>(call.getLimit(),
std::distance(_currentGroup, _allGroups.end()));
}

const HashedCollectExecutor::Infos& HashedCollectExecutor::infos() const noexcept {
return _infos;
}
11 changes: 10 additions & 1 deletion arangod/Aql/HashedCollectExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ class HashedCollectExecutor {
*/
std::pair<ExecutionState, size_t> expectedNumberOfRows(size_t atMost) const;

/**
* @brief This Executor does not know how many distinct rows will be fetched
* from upstream, it can only report how many it has found by itself, plus
* it knows that it can only create as many new rows as pulled from upstream.
* So it will overestimate.
*/
[[nodiscard]] auto expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const noexcept -> size_t;

private:
using AggregateValuesType = std::vector<std::unique_ptr<Aggregator>>;
using GroupKeyType = std::vector<AqlValue>;
Expand Down Expand Up @@ -215,7 +224,7 @@ class HashedCollectExecutor {

/// @brief hashmap of all encountered groups
GroupMapType _allGroups;
GroupMapType::iterator _currentGroup;
GroupMapType::const_iterator _currentGroup;

bool _isInitialized; // init() was called successfully (e.g. it returned DONE)

Expand Down
17 changes: 7 additions & 10 deletions arangod/Aql/IdExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,22 @@ auto IdExecutor<UsedFetcher>::produceRows(AqlItemBlockInputRange& inputRange,
-> std::tuple<ExecutorState, CountStats, AqlCall> {
CountStats stats;
TRI_ASSERT(output.numRowsWritten() == 0);
// TODO: We can implement a fastForward copy here.
// We know that all rows we have will fit into the output
while (!output.isFull() && inputRange.hasDataRow()) {
auto const& [state, inputRow] = inputRange.nextDataRow();
TRI_ASSERT(inputRow);

if (inputRange.hasDataRow()) {
TRI_ASSERT(!output.isFull());
TRI_IF_FAILURE("SingletonBlock::getOrSkipSome") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
auto const& [state, inputRow] = inputRange.peekDataRow();

output.fastForwardAllRows(inputRow, inputRange.countDataRows());

/*Second parameter are to ignore registers that should be kept but are missing in the input row*/
output.copyRow(inputRow, std::is_same_v<UsedFetcher, ConstFetcher>);
TRI_ASSERT(output.produced());
output.advanceRow();
std::ignore = inputRange.skipAllRemainingDataRows();

TRI_IF_FAILURE("SingletonBlock::getOrSkipSomeSet") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
}
TRI_ASSERT(!inputRange.hasDataRow());
if (_infos.doCount()) {
stats.addCounted(output.numRowsWritten());
}
Expand Down
9 changes: 8 additions & 1 deletion arangod/Aql/NoResultsExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,11 @@ auto NoResultsExecutor::skipRowsRange(AqlItemBlockInputRange& inputRange, AqlCal
noexcept -> std::tuple<ExecutorState, Stats, size_t, AqlCall> {
return {inputRange.upstreamState(), NoStats{}, 0,
AqlCall{0, false, 0, AqlCall::LimitType::HARD}};
};
};

[[nodiscard]] auto NoResultsExecutor::expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const
noexcept -> size_t {
// Well nevermind the input, but we will always return 0 rows here.
return 0;
}
3 changes: 3 additions & 0 deletions arangod/Aql/NoResultsExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class NoResultsExecutor {
// Well nevermind the input, but we will always return 0 rows here.
return {ExecutionState::DONE, 0};
}

[[nodiscard]] auto expectedNumberOfRowsNew(AqlItemBlockInputRange const& input,
AqlCall const& call) const noexcept -> size_t;
};
} // namespace aql
} // namespace arangodb
Expand Down
24 changes: 24 additions & 0 deletions arangod/Aql/OutputAqlItemRow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,30 @@ void OutputAqlItemRow::copyRow(ItemRowType const& sourceRow, bool ignoreMissing)
doCopyRow(sourceRow, ignoreMissing);
}

auto OutputAqlItemRow::fastForwardAllRows(InputAqlItemRow const& sourceRow, size_t rows)
-> void {
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
TRI_ASSERT(sourceRow.internalBlockIs(_block));
#endif
TRI_ASSERT(_doNotCopyInputRow);
TRI_ASSERT(_call.getLimit() >= rows);
TRI_ASSERT(rows > 0);
// We have the guarantee that we have all data in our block.
// We only need to adjust internal indexes.
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
// Safely assert that the API is not missused.
TRI_ASSERT(_baseIndex + rows <= _block->size());
for (size_t i = _baseIndex; i < _baseIndex + rows; ++i) {
TRI_ASSERT(!_block->isShadowRow(i));
}
#endif
_baseIndex += rows;
TRI_ASSERT(_baseIndex > 0);
_lastBaseIndex = _baseIndex - 1;
_lastSourceRow = InputAqlItemRow{_block, _lastBaseIndex};
_call.didProduce(rows);
}

void OutputAqlItemRow::copyBlockInternalRegister(InputAqlItemRow const& sourceRow,
RegisterId input, RegisterId output) {
// This method is only allowed if the block of the input row is the same as
Expand Down
Loading
0