8000 Feature/aql subquery execution block impl execute implementation bypass skip by mchacki · Pull Request #11203 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content

Feature/aql subquery execution block impl execute implementation bypass skip #11203

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 1 commit
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
81b6699
Fixed range-handling for Modification Executors
mchacki Feb 29, 2020
01025a7
DataRange handling in ModificationExecutor
mchacki Feb 29, 2020
fe53317
Honor batch-size defined by UpstreamExecutor
mchacki Feb 29, 2020
4bae2e4
Fixed compile issue
mchacki Feb 29, 2020
8a6d636
More fixes in modification
mchacki Feb 29, 2020
9cc084b
Remvoed log devel
mchacki Feb 29, 2020
5c4e05e
Fixed profiler Test. for NoResults node we cahnge the behaviour
mchacki Feb 29, 2020
e25a5ca
Activated getSome failure tests in ExecuteRestHandler
mchacki Feb 29, 2020
08709e9
Fixed skipping in Index
mchacki Feb 29, 2020
e7b2b00
Let the MultiDependencySingleROwFetcher return the correct states.
mchacki Feb 29, 2020
368127b
Fixed non-maintainer compilation
mchacki Feb 29, 2020
6eaad9f
Attempt to fix windows compile issue
mchacki Feb 29, 2020
06c3099
Fixed the non-maintainer compile ina different way
mchacki Feb 29, 2020
68d6ebe
Added API in MultiAqlItemBlockInputRange to get Number of dependencies
mchacki Feb 29, 2020
abd617e
Comments
mchacki Feb 29, 2020
d149e39
Savepoint commit, does not compile, but no harm is done. Will start b…
mchacki Feb 29, 2020
52dcde5
Another savepoint commit. does not compile, yet.
mchacki Feb 29, 2020
5ae6cac
First d 8000 raft of new Style SortingGather not yet implemented: Paralleli…
mchacki Feb 29, 2020
8fb35bb
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Feb 29, 2020
d46e51c
Allow waiting within old-style subquery
mchacki Feb 29, 2020
94431f1
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Feb 29, 2020
1e5947a
Fixed invalid skipRwos in unsorted gather
mchacki Feb 29, 2020
b7aaa92
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 1, 2020
56c41b1
First draft of ParallelUnsortedGatherExecutor
mchacki Mar 1, 2020
474bf92
Removed unused local variables
mchacki Mar 1, 2020
854082d
Added some Assertions in MultiAqlItemBlockInputRange
mchacki Mar 1, 2020
692c3b7
Initialize dependdencies of MultiDependencyFetcher
mchacki Mar 1, 2020
d525917
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 1, 2020
03a03da
Fixed skipRows loop in UnsortingGatherNode
mchacki Mar 1, 2020
01bca14
Added an implementation for a SkipResult, in order to simplify exchan…
mchacki Mar 1, 2020
0a44131
Moved production API -> SkipResult
mchacki Mar 1, 2020
250fab7
Made tests compile with new SkipResult
mchacki Mar 1, 2020
bd53fa8
Added a test using skip and limit on subqueries
mchacki Mar 1, 2020
f72f45a
Prepared to use subqueries in SkipResult
mchacki Mar 1, 2020
9224b4c
Let subqueries modify the SkipResult subquery stack
mchacki Mar 2, 2020
fb6b9e1
Fixed return state of GatherNode
mchacki Mar 2, 2020
57ce96b
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 2, 2020
6be3180
Activate all spliced subquery tests \o/
mchacki Mar 2, 2020
563821c
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 2, 2020
6e8855b
Let SubqueryEnd honor the client request
mchacki Mar 2, 2020
c03498e
Added a Maintainer only test for the stack, if it is 36 compatible
mchacki Mar 2, 2020
d766db9
Added first part of side-effect executors. They now send upstream a f…
mchacki Mar 3, 2020
e6a8dcb
Add a fake FASTFORWARD call into a subquery-skipped ModificationExecu…
mchacki Mar 3, 2020
5659bc2
Added helper shadow row function for SideEffect executors
mchacki Mar 3, 2020
e28c231
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 3, 2020
b1c6af5
Let the Modification Executor also produce data, even if no FullCount…
mchacki Mar 4, 2020
ac94ae3
Revert "Let the Modification Executor also produce data, even if no F…
mchacki Mar 4, 2020
7695b10
Revert "Revert "Let the Modification Executor also produce data, even…
mchacki Mar 4, 2020
6bf1343
Implemented proper fastForwarding and skipReporting in ExecutorsWithS…
mchacki Mar 4, 2020
6c743bc
Removed unreachable code, somehow the G++ in our tests tries to comil…
mchacki Mar 4, 2020
970d17f
noexcept -> throw is nono good. Thank you compiler for helping me her…
mchacki Mar 4, 2020
3dba1bc
Implment copy on SkipResult
mchacki Mar 4, 2020
50c452f
Adapted SubqueryStartTest to allow easy testing for Skipping on outer…
mchacki Mar 5, 2020
1874871
Fixed koenig lookup of SkipResult ostream operator
mchacki Mar 5, 2020
62898ce
Removed special case of SubqueryStartExecutor and include it on the h…
mchacki Mar 5, 2020
a4d4017
Sorry needed to make the _operations vector mutual because of 3.6 com…
mchacki Mar 5, 2020
1fe6c3b
Attempt to fix windows compile issue
mchacki Mar 5, 2020
c7e25df
Fixed behvaiour of SubqueryEndExecutor
mchacki Mar 5, 2020
c5581e4
Another windows attempt
mchacki Mar 5, 2020
15a7d6e
Fixed modify test, which would actually iterate over too many documen…
mchacki Mar 5, 2020
c30ac78
Fixed tests that assert on existence of SubqueryNode, now there will …
mchacki Mar 5, 2020
fe1757b
Consider a hardLimitFastForward inside the Callstack like a needToSki…
mchacki Mar 5, 2020
3e4f6c7
Fixed all tests that are related to subqueries, which now need to ass…
mchacki Mar 6, 2020
435e841
Fixed jslint
mchacki Mar 6, 2020
f0bca7c
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 10, 2020
1622f08
Fixed the callstack that has been seperated from the clientCall. In s…
mchacki Mar 10, 2020
aef48b6
Fixed skip result forwarding in Scatter/Gather
mchacki Mar 11, 2020
666fe7d
Fixed assertion if the ConstFetcher gets a block with subquery level …
mchacki Mar 11, 2020
680bce4
Moved merging of SubquerySkips in MultiDependencies into the Fetcher
mchacki Mar 11, 2020
3be7aac
Removed dead code and fixed overproduction of Rows in Subquery Executor
mchacki Mar 11, 2020
7b94bb7
Fixed bypassing of skip in SideEffect executors if they trigger waiti…
mchacki Mar 11, 2020
5165f55
Refactored old SubqueryExecutor, there has been some issue with WAITI…
mchacki Mar 11, 2020
9db1c38
Removed debug logging in test
mchacki Mar 12, 2020
4ff1dd8
Fixed empty subquery executor
mchacki Mar 12, 2020
7c79a70
Added an assertion in the AqlResult that no invalid block tries to be…
mchacki Mar 12, 2020
ae61cee
Added clientId into profile tracing. Fixed return of invalid blocks i…
mchacki Mar 12, 2020
ca243b2
Removed invalid AqlExecuteResult from Test
mchacki Mar 12, 2020
48eec3e
Update tests/Aql/SubqueryStartExecutorTest.cpp
mchacki Mar 12, 2020
fe82b4b
Fixed comment, thanks to reviewer
mchacki Mar 12, 2020
54db163
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
mchacki Mar 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'feature/AqlSubqueryExecutionBlockImplExecuteImplementat…
…ion' of ssh://github.com/arangodb/ArangoDB into feature/AqlSubqueryExecutionBlockImplExecuteImplementation-bypass-skip
  • Loading branch information
mchacki committed Mar 10, 2020
commit f0bca7c7c211ffb85b574276dc5953dd0fb2c44e
6 changes: 6 additions & 0 deletions arangod/Aql/AqlCallStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ void AqlCallStack::pushCall(AqlCall&& call) {
_operations.emplace_back(std::move(call));
}

void AqlCallStack::pushCall(AqlCall const& call) {
// TODO is this correct on subqueries?
TRI_ASSERT(isRelevant());
_operations.emplace_back(call);
}

void AqlCallStack::pop() {
if (isRelevant()) {
// We have one element to pop
Expand Down
3 changes: 3 additions & 0 deletions arangod/Aql/AqlCallStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class AqlCallStack {
// Put another call on top of the stack.
void pushCall(AqlCall&& call);

// Put another call on top of the stack.
void pushCall(AqlCall const& call);

// Pops one subquery level.
// if this isRelevent it pops the top-most call from the stack.
// if this is not revelent it reduces the depth by 1.
Expand Down
73 changes: 29 additions & 44 deletions arangod/Aql/ExecutionBlockImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,13 @@ std::pair<ExecutionState, Result> ExecutionBlockImpl<Executor>::initializeCursor
_rowFetcher.~Fetcher();
new (&_rowFetcher) Fetcher(_dependencyProxy);

if constexpr (isMultiDepExecutor<Executor>) {
_lastRange.reset();
_rowFetcher.init();
} else {
_lastRange = DataRange(ExecutorState::HASMORE);
}

TRI_ASSERT(_skipped.nothingSkipped());
_skipped.reset();
TRI_ASSERT(_state == InternalState::DONE || _state == InternalState::FETCH_DATA);
Expand Down Expand Up @@ -1210,42 +1217,28 @@ static auto fastForwardType(AqlCall const& call, Executor const& e) -> FastForwa
}

template <class Executor>
auto ExecutionBlockImpl<Executor>::executeFetcher(AqlCallStack& stack, size_t const dependency)
auto ExecutionBlockImpl<Executor>::executeFetcher(AqlCallStack& stack, AqlCallType const& aqlCall)
-> std::tuple<ExecutionState, SkipResult, typename Fetcher::DataRange> {
// Silence compiler about unused dependency
(void)dependency;
if constexpr (isNewStyleExecutor<Executor>) {
if constexpr (is_one_of_v<Fetcher, MultiDependencySingleRowFetcher>) {
// TODO The logic in the MultiDependencySingleRowFetcher branch should be
// moved into the MultiDependencySingleRowFetcher.
static_assert(isMultiDepExecutor<Executor> ==
std::is_same_v<Fetcher, MultiDependencySingleRowFetcher>);
if constexpr (std::is_same_v<Fetcher, MultiDependencySingleRowFetcher>) {
static_assert(
!executorHasSideEffects<Executor>,
"there is a special implementation for side-effect executors to "
"exchange the stack. For the MultiDependencyFetcher this special "
"case is not implemented. There is no reason to disallow this "
"case here however, it is just not needed thus far.");
// TODO: This is a hack to guarantee we have enough space in our range
// to fit all inputs, in particular the one executed below
TRI_ASSERT(dependency < _dependencies.size());
_lastRange.resizeIfNecessary(ExecutorState::HASMORE, 0, _dependencies.size());

if constexpr (!isParallelExecutor) {
auto [state, skipped, range] = _rowFetcher.executeForDependency(dependency, stack);
// Note the aqlCall is an AqlCallSet in this case:
static_assert(std::is_same_v<AqlCallSet, std::decay_t<decltype(aqlCall)>>);
TRI_ASSERT(_lastRange.numberDependencies() == _dependencies.size());
auto const& [state, skipped, ranges] = _rowFetcher.execute(stack, aqlCall);
for (auto const& [dependency, range] : ranges) {
_lastRange.setDependency(dependency, range);
return {state, skipped, _lastRange};
} else {
_callsInFlight.resize(_dependencyProxy.numberDependencies());
if (!_callsInFlight[dependency].has_value()) {
_callsInFlight[dependency] = stack;
}
TRI_ASSERT(_callsInFlight[dependency].has_value());
auto [state, skipped, range] =
_rowFetcher.executeForDependency(dependency,
_callsInFlight[dependency].value());
if (state != ExecutionState::WAITING) {
_callsInFlight[dependency] = std::nullopt;
}
_lastRange.setDependency(dependency, range);
return {state, skipped, _lastRange};
}
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
Expand Down Expand Up @@ -1646,17 +1639,16 @@ auto ExecutionBlockImpl<Executor>::executeFastForward(typename Fetcher::DataRang
AqlCall dummy;
dummy.hardLimit = 0;
dummy.fullCount = true;
auto [state, stats, skippedLocal, call, dependency] =
executeSkipRowsRange(_lastRange, dummy);
_requestedDependency = dependency;
auto [state, stats, skippedLocal, call] = executeSkipRowsRange(_lastRange, dummy);

if constexpr (is_one_of_v<DataRange, AqlItemBlockInputMatrix, MultiAqlItemBlockInputRange>) {
// The executor will have used all Rows.
// However we need to drop them from the input
// here.
inputRange.skipAllRemainingDataRows();
}

return {state, stats, 0, call, dependency};
return {state, stats, 0, call};
}
case FastForwardVariant::FETCHER: {
LOG_QUERY("fa327", DEBUG) << printTypeInfo() << " bypass unused rows.";
Expand All @@ -1667,8 +1659,8 @@ auto ExecutionBlockImpl<Executor>::executeFastForward(typename Fetcher::DataRang
return fastForwardCall;
} else {
#ifndef _WIN32
// For some reason our Windows compiler complains about this static assert
// in the cases that should be in the above constexpr path.
// For some reason our Windows compiler complains about this static
// assert in the cases that should be in the above constexpr path.
// So simply not compile it in.
static_assert(std::is_same_v<AqlCallType, AqlCallSet>);
#endif
Expand Down Expand Up @@ -1967,15 +1959,18 @@ ExecutionBlockImpl<Executor>::executeWithoutTrace(AqlCallStack stack) {
case ExecState::FASTFORWARD: {
LOG_QUERY("96e2c", DEBUG)
<< printTypeInfo() << " all produced, fast forward to end up (sub-)query.";

AqlCall callCopy = clientCall;
if constexpr (executorHasSideEffects<Executor>) {
if (stack.needToSkipSubquery()) {
// Fast Forward call.
callCopy = AqlCall{0, false, 0, AqlCall::LimitType::HARD};
}
}
auto [state, stats, skippedLocal, call, dependency] =

auto [state, stats, skippedLocal, call] =
executeFastForward(_lastRange, callCopy);

if constexpr (executorHasSideEffects<Executor>) {
if (!stack.needToSkipSubquery()) {
// We need to modify the original call.
Expand All @@ -1987,7 +1982,6 @@ ExecutionBlockImpl<Executor>::executeWithoutTrace(AqlCallStack stack) {
clientCall = callCopy;
}

_requestedDependency = dependency;
_skipped.didSkip(skippedLocal);
_engine->_stats += stats;
localExecutorState = state;
Expand Down Expand Up @@ -2021,16 +2015,7 @@ ExecutionBlockImpl<Executor>::executeWithoutTrace(AqlCallStack stack) {
auto subqueryLevelBefore = stack.subqueryLevel();
#endif
std::tie(_upstreamState, skippedLocal, _lastRange) =
executeFetcher(stack, _requestedDependency);
if constexpr (std::is_same_v<Executor, SubqueryStartExecutor>) {
// Do not pop the call, we did not put it on.
// However we need it for accounting later.
} else {
// As the stack is copied into the fetcher, we need to pop off our call again.
// If we use other datastructures or moving we may hand over ownership of the stack here
// instead and no popCall is necessary.
stack.popCall();
}
executeFetcher(stack, _upstreamRequest);

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
TRI_ASSERT(subqueryLevelBefore == stack.subqueryLevel());
Expand Down
7 changes: 6 additions & 1 deletion arangod/Aql/ExecutionBlockImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class Query;
class ShadowAqlItemRow;
class SkipResult;
class ParallelUnsortedGatherExecutor;
class MultiDependencySingleRowFetcher;

template <typename T, typename... Es>
constexpr bool is_one_of_v = (std::is_same_v<T, Es> || ...);
Expand Down Expand Up @@ -257,7 +258,7 @@ class ExecutionBlockImpl final : public ExecutionBlock {
std::tuple<ExecutionState, SkipResult, SharedAqlItemBlockPtr> executeWithoutTrace(AqlCallStack stack);

std::tuple<ExecutionState, SkipResult, typename Fetcher::DataRange> executeFetcher(
AqlCallStack& stack, size_t const dependency);
AqlCallStack& stack, AqlCallType const& aqlCall);

std::tuple<ExecutorState, typename Executor::Stats, AqlCallType> executeProduceRows(
typename Fetcher::DataRange& input, OutputAqlItemRow& output);
Expand Down Expand Up @@ -350,6 +351,10 @@ class ExecutionBlockImpl final : public ExecutionBlock {
DataRange const& range) const
noexcept -> ExecState;

void initOnce();

[[nodiscard]] auto executorNeedsCall(AqlCallType& call) const noexcept -> bool;

private:
/**
* @brief Used to allow the row Fetcher to access selected methods of this
Expand Down
9 changes: 3 additions & 6 deletions arangod/Aql/MultiDependencySingleRowFetcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,6 @@ auto MultiDependencySingleRowFetcher::useStack(AqlCallStack const& stack) -> voi
auto MultiDependencySingleRowFetcher::executeForDependency(size_t const dependency,
AqlCallStack& stack)
-> std::tuple<ExecutionState, SkipResult, AqlItemBlockInputRange> {
if (_dependencyStates.empty()) {
initDependencies();
}
auto [state, skipped, block] = _dependencyProxy->executeForDependency(dependency, stack);

if (state == ExecutionState::WAITING) {
Expand All @@ -395,7 +392,7 @@ auto MultiDependencySingleRowFetcher::executeForDependency(size_t const dependen

auto MultiDependencySingleRowFetcher::execute(AqlCallStack const& stack,
AqlCallSet const& aqlCallSet)
-> std::tuple<ExecutionState, size_t, std::vector<std::pair<size_t, AqlItemBlockInputRange>>> {
-> std::tuple<ExecutionState, SkipResult, std::vector<std::pair<size_t, AqlItemBlockInputRange>>> {
TRI_ASSERT(_callsInFlight.size() == numberDependencies());

auto ranges = std::vector<std::pair<size_t, AqlItemBlockInputRange>>{};
Expand All @@ -404,7 +401,7 @@ auto MultiDependencySingleRowFetcher::execute(AqlCallStack const& stack,
auto depCallIdx = size_t{0};
auto allAskedDepsAreWaiting = true;
auto askedAtLeastOneDep = false;
auto skippedTotal = size_t{0};
auto skippedTotal = SkipResult{};
// Iterate in parallel over `_callsInFlight` and `aqlCall.calls`.
// _callsInFlight[i] corresponds to aqlCalls.calls[k] iff
// aqlCalls.calls[k].dependency = i.
Expand Down Expand Up @@ -440,7 +437,7 @@ auto MultiDependencySingleRowFetcher::execute(AqlCallStack const& stack,
maybeCallInFlight = std::nullopt;
allAskedDepsAreWaiting = false;
} else {
TRI_ASSERT(skipped == 0);
TRI_ASSERT(skipped.nothingSkipped());
}
skippedTotal += skipped;
ranges.emplace_back(dependency, range);
Expand Down
5 changes: 4 additions & 1 deletion arangod/Aql/MultiDependencySingleRowFetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ class MultiDependencySingleRowFetcher {
//@deprecated
auto useStack(AqlCallStack const& stack) -> void;

auto executeForDependency(size_t const dependency, AqlCallStack& stack)
[[nodiscard]] auto execute(AqlCallStack const&, AqlCallSet const&)
-> std::tuple<ExecutionState, SkipResult, std::vector<std::pair<size_t, AqlItemBlockInputRange>>>;

[[nodiscard]] auto executeForDependency(size_t dependency, AqlCallStack& stack)
-> std::tuple<ExecutionState, SkipResult, AqlItemBlockInputRange>;

[[nodiscard]] auto upstreamState() const -> ExecutionState;
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.
0