1
0
Fork 0

Bug fix/aql line cleanup (#8598)

This commit is contained in:
Heiko 2019-04-04 15:57:41 +02:00 committed by Jan
parent 5d83eb7442
commit 066ed742af
19 changed files with 28 additions and 328 deletions

View File

@ -102,9 +102,6 @@ class CollectNode : public ExecutionNode {
_options.method = method;
}
/// @brief getOptions
CollectOptions const& getOptions() const { return _options; }
/// @brief getOptions
CollectOptions& getOptions() { return _options; }

View File

@ -89,7 +89,6 @@ class ConstrainedSortExecutor {
Infos& _infos;
Fetcher& _fetcher;
ExecutionState _state;
std::vector<size_t> _sortedIndexes;
size_t _returnNext;
std::vector<uint32_t> _rows;
size_t _rowsPushed;

View File

@ -71,9 +71,6 @@ class DistinctCollectExecutorInfos : public ExecutorInfos {
/// @brief pairs, consisting of out register and in register
std::vector<std::pair<RegisterId, RegisterId>> _groupRegisters;
/// @brief input/output variables for the collection (out, in)
std::vector<std::pair<Variable const*, Variable const*>> _groupVariables;
/// @brief the transaction for this query
transaction::Methods* _trxPtr;
};

View File

@ -102,8 +102,6 @@ class ExecutionBlockImpl<DistributeExecutor> : public BlockWithClients {
ExecutorInfos const& infos() const { return _infos; }
Query const& getQuery() const { return _query; }
private:
ExecutorInfos _infos;

View File

@ -1,199 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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 Steemann
////////////////////////////////////////////////////////////////////////////////
#include "DocumentProducingBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/DocumentProducingNode.h"
#include "Aql/ExecutionNode.h"
#include "Aql/IndexNode.h"
#include "Aql/Variable.h"
#include "Basics/Exceptions.h"
#include "Basics/StaticStrings.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "Transaction/Helpers.h"
using namespace arangodb;
using namespace arangodb::aql;
namespace {
inline void handleProjections(DocumentProducingNode const* node,
transaction::Methods const* trxPtr, VPackSlice slice,
VPackBuilder& b, bool useRawDocumentPointers) {
for (auto const& it : node->projections()) {
if (it == StaticStrings::IdString) {
VPackSlice found = transaction::helpers::extractIdFromDocument(slice);
if (found.isCustom()) {
// _id as a custom type needs special treatment
b.add(it, VPackValue(transaction::helpers::extractIdString(trxPtr->resolver(),
found, slice)));
} else {
b.add(it, found);
}
} else if (it == StaticStrings::KeyString) {
VPackSlice found = transaction::helpers::extractKeyFromDocument(slice);
if (useRawDocumentPointers) {
b.add(VPackValue(it));
b.addExternal(found.begin());
} else {
b.add(it, found);
}
} else {
VPackSlice found = slice.get(it);
if (found.isNone()) {
// attribute not found
b.add(it, VPackValue(VPackValueType::Null));
} else {
if (useRawDocumentPointers) {
b.add(VPackValue(it));
b.addExternal(found.begin());
} else {
b.add(it, found);
}
}
}
}
}
} // namespace
DocumentProducingBlock::DocumentProducingBlock(DocumentProducingNode const* node,
transaction::Methods* trx)
: _trxPtr(trx),
_node(node),
_produceResult(dynamic_cast<ExecutionNode const*>(_node)->isVarUsedLater(
_node->outVariable())),
_useRawDocumentPointers(EngineSelectorFeature::ENGINE->useRawDocumentPointers()),
_allowCoveringIndexOptimization(true) {}
void DocumentProducingBlock::buildCallback() {
if (!_produceResult) {
// no result needed
_documentProducer = [](AqlItemBlock* res, VPackSlice, size_t registerId,
size_t& row, size_t fromRow) {
if (row != fromRow) {
// re-use already copied AQLValues
res->copyValuesFromRow(row, static_cast<RegisterId>(registerId), fromRow);
}
++row;
};
return;
}
if (!_node->projections().empty()) {
// return a projection
if (!_node->coveringIndexAttributePositions().empty()) {
// projections from an index value (covering index)
_documentProducer = [this](AqlItemBlock* res, VPackSlice slice,
size_t registerId, size_t& row, size_t fromRow) {
transaction::BuilderLeaser b(_trxPtr);
b->openObject(true);
if (_allowCoveringIndexOptimization) {
// a potential call by a covering index iterator...
bool const isArray = slice.isArray();
size_t i = 0;
VPackSlice found;
for (auto const& it : _node->projections()) {
if (isArray) {
// we will get a Slice with an array of index values. now we need
// to look up the array values from the correct positions to
// populate the result with the projection values this case will
// be triggered for indexes that can be set up on any number of
// attributes (hash/skiplist)
found = slice.at(_node->coveringIndexAttributePositions()[i]);
++i;
} else {
// no array Slice... this case will be triggered for indexes that
// contain simple string values, such as the primary index or the
// edge index
found = slice;
}
if (found.isNone()) {
// attribute not found
b->add(it, VPackValue(VPackValueType::Null));
} else {
if (_useRawDocumentPointers) {
b->add(VPackValue(it));
b->addExternal(found.begin());
} else {
b->add(it, found);
}
}
}
} else {
// projections from a "real" document
handleProjections(_node, _trxPtr, slice, *b.get(), _useRawDocumentPointers);
}
b->close();
res->emplaceValue(row, static_cast<arangodb::aql::RegisterId>(registerId),
b.get());
if (row != fromRow) {
// re-use already copied AQLValues
res->copyValuesFromRow(row, static_cast<RegisterId>(registerId), fromRow);
}
++row;
};
return;
}
// projections from a "real" document
_documentProducer = [this](AqlItemBlock* res, VPackSlice slice,
size_t registerId, size_t& row, size_t fromRow) {
transaction::BuilderLeaser b(_trxPtr);
b->openObject(true);
handleProjections(_node, _trxPtr, slice, *b.get(), _useRawDocumentPointers);
b->close();
res->emplaceValue(row, static_cast<arangodb::aql::RegisterId>(registerId), b.get());
if (row != fromRow) {
// re-use already copied AQLValues
res->copyValuesFromRow(row, static_cast<RegisterId>(registerId), fromRow);
}
++row;
};
return;
}
// return the document as is
_documentProducer = [this](AqlItemBlock* res, VPackSlice slice,
size_t registerId, size_t& row, size_t fromRow) {
uint8_t const* vpack = slice.begin();
if (_useRawDocumentPointers) {
res->emplaceValue(row, static_cast<arangodb::aql::RegisterId>(registerId),
AqlValueHintDocumentNoCopy(vpack));
} else {
res->emplaceValue(row, static_cast<arangodb::aql::RegisterId>(registerId),
AqlValueHintCopy(vpack));
}
if (row != fromRow) {
// re-use already copied AQLValues
res->copyValuesFromRow(row, static_cast<RegisterId>(registerId), fromRow);
}
++row;
};
}

View File

@ -1,77 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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 Steemann
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_AQL_DOCUMENT_PRODUCING_BLOCK_H
#define ARANGOD_AQL_DOCUMENT_PRODUCING_BLOCK_H 1
#include "Basics/Common.h"
#include <velocypack/Slice.h>
#include <functional>
namespace arangodb {
namespace transaction {
class Methods;
}
namespace aql {
class AqlItemBlock;
class DocumentProducingNode;
struct Variable;
class DocumentProducingBlock {
public:
typedef std::function<void(AqlItemBlock*, arangodb::velocypack::Slice, size_t, size_t&, size_t)> DocumentProducingFunction;
DocumentProducingBlock(DocumentProducingNode const* node, transaction::Methods* trx);
virtual ~DocumentProducingBlock() = default;
public:
inline bool produceResult() const { return _produceResult; }
void buildCallback();
private:
transaction::Methods* _trxPtr;
DocumentProducingNode const* _node;
/// @brief hether or not we want to build a result
bool const _produceResult;
/// @brief whether or not we are allowed to pass documents via raw pointers
/// only (true for MMFiles, false for RocksDB)
bool const _useRawDocumentPointers;
protected:
DocumentProducingFunction _documentProducer;
/// @brief whether or not we are allowed to use the covering index
/// optimization in a callback
bool _allowCoveringIndexOptimization;
};
} // namespace aql
} // namespace arangodb
#endif

View File

@ -67,10 +67,6 @@ class DocumentProducingNode {
return _coveringIndexAttributePositions;
}
void resetCoveringIndexAttributePositions() const {
_coveringIndexAttributePositions.clear();
}
void toVelocyPack(arangodb::velocypack::Builder& builder) const;
protected:

View File

@ -90,7 +90,7 @@ class ExecutionBlock {
virtual std::pair<ExecutionState, Result> initializeCursor(InputAqlItemRow const& input);
/// @brief shutdown, will be called exactly once for the whole query
virtual std::pair<ExecutionState, Result> shutdown(int);
virtual std::pair<ExecutionState, Result> shutdown(int errorCode);
/// @brief getSome, gets some more items, semantic is as follows: not
/// more than atMost items may be delivered. The method tries to

View File

@ -3406,7 +3406,6 @@ AqlValue Functions::DateSubtract(ExpressionContext* expressionContext,
// size == 3 unit / unit type
// size == 2 iso duration
year_month_day ymd{floor<days>(tp)};
if (parameters.size() == 3) {
AqlValue const& durationUnit = extractFunctionParameterValue(parameters, 1);
if (!durationUnit.isNumber()) { // unit must be number

View File

@ -74,14 +74,9 @@ class HashedCollectExecutorInfos : public ExecutorInfos {
std::vector<std::string> getAggregateTypes() const { return _aggregateTypes; }
bool getCount() const noexcept { return _count; }
transaction::Methods* getTransaction() const { return _trxPtr; }
RegisterId getInputRegister() const noexcept { return _inputRegister; }
RegisterId getCollectRegister() const noexcept { return _collectRegister; }
private:
// This is exactly the value in the parent member ExecutorInfo::_inRegs,
// respectively getInputRegisters().
RegisterId _inputRegister;
/// @brief aggregate types
std::vector<std::string> _aggregateTypes;

View File

@ -85,7 +85,6 @@ class IdExecutor {
private:
Fetcher& _fetcher;
std::unique_ptr<AqlItemBlock> _inputRegisterValues;
};
} // namespace aql
} // namespace arangodb

View File

@ -207,10 +207,9 @@ arangodb::OperationCursor* IndexExecutor::orderCursor(size_t currentIndex) {
resetCursor(currentIndex);
} else if (iterator == nullptr || !iterator->canRearm()) {
// inject a new index iterator into the existing cursor
cursor->rearm(
_infos.getTrxPtr()->indexScanForCondition(
_infos.getIndexes()[currentIndex], conditionNode,
_infos.getOutVariable(), _infos.getOptions()));
cursor->rearm(_infos.getTrxPtr()->indexScanForCondition(_infos.getIndexes()[currentIndex], conditionNode,
_infos.getOutVariable(),
_infos.getOptions()));
} else {
// try to rearm an existing iterator
if (iterator->rearm(conditionNode, _infos.getOutVariable(), _infos.getOptions())) {
@ -218,7 +217,8 @@ arangodb::OperationCursor* IndexExecutor::orderCursor(size_t currentIndex) {
resetCursor(currentIndex);
} else {
// iterator does not support the condition
cursor->rearm(std::make_unique<EmptyIndexIterator>(iterator->collection(), _infos.getTrxPtr()));
cursor->rearm(std::make_unique<EmptyIndexIterator>(iterator->collection(),
_infos.getTrxPtr()));
}
}
@ -391,8 +391,14 @@ bool IndexExecutor::advanceCursor() {
while (!getCursor()->hasMore()) {
if (!_infos.isAscending()) {
decrCurrentIndex();
if (_currentIndex == 0) {
setIsLastIndex(true);
}
} else {
incrCurrentIndex();
if (_infos.getIndexes().size() - 1 == _currentIndex) {
setIsLastIndex(true);
}
}
if (getCurrentIndex() < _infos.getIndexes().size()) {

View File

@ -76,8 +76,6 @@ class IndexExecutorInfos : public ExecutorInfos {
std::vector<size_t> const& getCoveringIndexAttributePositions() {
return _coveringIndexAttributePositions;
}
std::vector<std::vector<Variable const*>> getInVars() { return _inVars; }
std::vector<std::vector<RegisterId>> getInRegs() { return _inRegs; }
bool getProduceResult() { return _produceResult; }
bool getUseRawDocumentPointers() { return _useRawDocumentPointers; }
std::vector<transaction::Methods::IndexHandle> const& getIndexes() {
@ -216,19 +214,20 @@ class IndexExecutor {
inline arangodb::OperationCursor* getCursor(size_t pos) {
return _cursors[pos].get();
}
std::vector<std::unique_ptr<OperationCursor>>& getCursors() {
return _cursors;
}
void setIndexesExhausted(bool flag) { _indexesExhausted = flag; }
bool getIndexesExhausted() { return _indexesExhausted; }
void setLastIndex(bool flag) { _isLastIndex = flag; }
bool isLastIndex() { return _isLastIndex; }
void setIsLastIndex(bool flag) { _isLastIndex = flag; }
void setCurrentIndex(size_t pos) { _currentIndex = pos; }
void decrCurrentIndex() { _currentIndex--; }
void incrCurrentIndex() { _currentIndex++; }
void decrCurrentIndex() {
_currentIndex--;
}
void incrCurrentIndex() {
_currentIndex++;
}
size_t getCurrentIndex() const noexcept { return _currentIndex; }
private:

View File

@ -56,7 +56,6 @@ class LimitExecutorInfos : public ExecutorInfos {
LimitExecutorInfos(LimitExecutorInfos const&) = delete;
~LimitExecutorInfos() = default;
size_t getLimit() const noexcept { return _limit; };
size_t getOffset() const noexcept { return _offset; };
size_t getLimitPlusOffset() const noexcept { return _offset + _limit; };
bool isFullCountEnabled() const noexcept { return _fullCount; };

View File

@ -54,7 +54,6 @@ struct ModificationBase {
std::size_t _defaultBlockSize = ExecutionBlock::DefaultBatchSize();
velocypack::Builder _tmpBuilder; // default
bool _prepared = false;
std::size_t _blockIndex = 0; // cursor to the current positon
std::shared_ptr<AqlItemBlockShell> _block = nullptr;
@ -70,7 +69,6 @@ struct ModificationBase {
// MUST not reset _block
_justCopy = false;
_last_not_skip = std::numeric_limits<decltype(_last_not_skip)>::max();
_prepared = false;
_blockIndex = 0;
_tmpBuilder.clear();

View File

@ -287,9 +287,6 @@ class Query {
/// warnings. If there are none it will not modify the builder
void addWarningsToVelocyPack(arangodb::velocypack::Builder&) const;
/// @brief get a description of the query's current state
std::string getStateString() const;
/// @brief look up a graph in the _graphs collection
graph::Graph const* lookupGraphByName(std::string const& name);

View File

@ -813,7 +813,7 @@ RestStatus RestAqlHandler::handleUseQuery(std::string const& operation, Query* q
ExecutionState state;
Result res;
std::tie(state, res) =
query->engine()->shutdown(errorCode); // pass errorCode to shutdown
query->engine()->shutdown(errorCode);
if (state == ExecutionState::WAITING) {
return RestStatus::WAITING;
}

View File

@ -83,8 +83,6 @@ class ExecutionBlockImpl<ScatterExecutor> : public BlockWithClients {
ExecutorInfos const& infos() const { return _infos; }
Query const& getQuery() const { return _query; }
private:
ExecutorInfos _infos;

View File

@ -201,7 +201,6 @@ SET(ARANGOD_SOURCES
Aql/CountCollectExecutor.cpp
Aql/DistinctCollectExecutor.cpp
Aql/DistributeExecutor.cpp
Aql/DocumentProducingBlock.cpp
Aql/DocumentProducingNode.cpp
Aql/EngineInfoContainerCoordinator.cpp
Aql/EngineInfoContainerDBServer.cpp