//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2018 ArangoDB GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Jan Christoph Uhde //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_AQL_CALACULATION_EXECUTOR_H #define ARANGOD_AQL_CALACULATION_EXECUTOR_H #include "Aql/ExecutionState.h" #include "Aql/ExecutorInfos.h" #include "Aql/InputAqlItemRow.h" #include "Aql/SharedAqlItemBlockPtr.h" #include "Aql/Stats.h" #include "Aql/types.h" #include #include namespace arangodb { namespace transaction { class Methods; } namespace aql { class Expression; class OutputAqlItemRow; class Query; template class SingleRowFetcher; struct Variable; struct CalculationExecutorInfos : public ExecutorInfos { CalculationExecutorInfos(RegisterId outputRegister, RegisterId nrInputRegisters, RegisterId nrOutputRegisters, std::unordered_set registersToClear, std::unordered_set registersToKeep, Query& query, Expression& expression, std::vector&& expInVars, std::vector&& expInRegs); CalculationExecutorInfos() = delete; CalculationExecutorInfos(CalculationExecutorInfos&&) = default; CalculationExecutorInfos(CalculationExecutorInfos const&) = delete; ~CalculationExecutorInfos() = default; RegisterId getOutputRegisterId() const noexcept; Query& getQuery() const noexcept; Expression& getExpression() const noexcept; std::vector const& getExpInVars() const noexcept; std::vector const& getExpInRegs() const noexcept; private: RegisterId _outputRegisterId; Query& _query; Expression& _expression; std::vector _expInVars; // input variables for expresseion std::vector _expInRegs; // input registers for expression }; enum class CalculationType { Condition, V8Condition, Reference }; template class CalculationExecutor { public: struct Properties { static constexpr bool preservesOrder = true; static constexpr BlockPassthrough allowsBlockPassthrough = BlockPassthrough::Enable; /* This could be set to true after some investigation/fixes */ static constexpr bool inputSizeRestrictsOutputSize = false; }; using Fetcher = SingleRowFetcher; using Infos = CalculationExecutorInfos; using Stats = NoStats; CalculationExecutor(Fetcher& fetcher, CalculationExecutorInfos&); ~CalculationExecutor(); /** * @brief produce the next Row of Aql Values. * * @return ExecutionState, and if successful exactly one new Row of AqlItems. */ std::pair produceRows(OutputAqlItemRow& output); std::tuple fetchBlockForPassthrough(size_t atMost); private: // specialized implementations void doEvaluation(InputAqlItemRow& input, OutputAqlItemRow& output); // Only for V8Conditions template > void enterContext(); // Only for V8Conditions template > void exitContext(); [[nodiscard]] bool shouldExitContextBetweenBlocks() const; private: CalculationExecutorInfos& _infos; Fetcher& _fetcher; InputAqlItemRow _currentRow; ExecutionState _rowState; // true iff we entered a V8 context and didn't exit it yet. // Necessary for owned contexts, which will not be exited when we call // exitContext; but only for assertions in maintainer mode. bool _hasEnteredContext; }; } // namespace aql } // namespace arangodb #endif