mirror of https://gitee.com/bigwinds/arangodb
bug-fix/internal-issue-#574 (#8991)
* restrict number of buckets to compare * do not use more sort buckets than requested * cleanup
This commit is contained in:
parent
704436de91
commit
0fb8b348db
|
@ -155,7 +155,7 @@ IResearchViewExecutorInfos::IResearchViewExecutorInfos(
|
|||
RegisterId numScoreRegisters,
|
||||
Query& query,
|
||||
std::vector<Scorer> const& scorers,
|
||||
IResearchViewSort const* sort,
|
||||
std::pair<iresearch::IResearchViewSort const*, size_t> const& sort,
|
||||
ExecutionPlan const& plan,
|
||||
Variable const& outVariable,
|
||||
aql::AstNode const& filterCondition,
|
||||
|
@ -688,9 +688,11 @@ size_t IResearchViewExecutor<ordered>::skip(size_t limit) {
|
|||
template <bool ordered>
|
||||
IResearchViewMergeExecutor<ordered>::IResearchViewMergeExecutor(Fetcher& fetcher, Infos& infos)
|
||||
: Base{fetcher, infos},
|
||||
_heap_it{ MinHeapContext{ *infos.sort(), _segments } } {
|
||||
TRI_ASSERT(infos.sort());
|
||||
TRI_ASSERT(!infos.sort()->empty());
|
||||
_heap_it{ MinHeapContext{ *infos.sort().first, infos.sort().second, _segments } } {
|
||||
TRI_ASSERT(infos.sort().first);
|
||||
TRI_ASSERT(!infos.sort().first->empty());
|
||||
TRI_ASSERT(infos.sort().first->size() >= infos.sort().second);
|
||||
TRI_ASSERT(infos.sort().second);
|
||||
TRI_ASSERT(ordered == (infos.getNumScoreRegisters() != 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ class IResearchViewExecutorInfos : public ExecutorInfos {
|
|||
RegisterId numScoreRegisters,
|
||||
Query& query,
|
||||
std::vector<iresearch::Scorer> const& scorers,
|
||||
iresearch::IResearchViewSort const* sort,
|
||||
std::pair<iresearch::IResearchViewSort const*, size_t> const& sort,
|
||||
ExecutionPlan const& plan,
|
||||
Variable const& outVariable,
|
||||
aql::AstNode const& filterCondition,
|
||||
|
@ -83,7 +83,10 @@ class IResearchViewExecutorInfos : public ExecutorInfos {
|
|||
int getDepth() const noexcept { return _depth; }
|
||||
bool volatileSort() const noexcept { return _volatileSort; }
|
||||
bool volatileFilter() const noexcept { return _volatileFilter; }
|
||||
iresearch::IResearchViewSort const* sort() const noexcept { return _sort; }
|
||||
|
||||
// first - sort
|
||||
// second - number of sort conditions to take into account
|
||||
std::pair<iresearch::IResearchViewSort const*, size_t> const& sort() const noexcept { return _sort; }
|
||||
|
||||
bool isScoreReg(RegisterId reg) const noexcept {
|
||||
return getOutputRegister() < reg && reg <= getOutputRegister() + getNumScoreRegisters();
|
||||
|
@ -95,7 +98,7 @@ class IResearchViewExecutorInfos : public ExecutorInfos {
|
|||
std::shared_ptr<iresearch::IResearchView::Snapshot const> const _reader;
|
||||
Query& _query;
|
||||
std::vector<iresearch::Scorer> const& _scorers;
|
||||
iresearch::IResearchViewSort const* _sort{};
|
||||
std::pair<iresearch::IResearchViewSort const*, size_t> _sort;
|
||||
ExecutionPlan const& _plan;
|
||||
Variable const& _outVariable;
|
||||
aql::AstNode const& _filterCondition;
|
||||
|
@ -449,8 +452,9 @@ class IResearchViewMergeExecutor : public IResearchViewExecutorBase<IResearchVie
|
|||
public:
|
||||
MinHeapContext(
|
||||
iresearch::IResearchViewSort const& sort,
|
||||
size_t sortBuckets,
|
||||
std::vector<Segment>& segments) noexcept
|
||||
: _less(sort),
|
||||
: _less(sort, sortBuckets),
|
||||
_segments(&segments) {
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,31 @@ IResearchViewNode::IResearchViewNode(aql::ExecutionPlan& plan, velocypack::Slice
|
|||
}
|
||||
|
||||
if (!primarySort.empty()) {
|
||||
_sort = &primarySort; // set sort from corresponding view
|
||||
size_t primarySortBuckets = primarySort.size();
|
||||
|
||||
auto const primarySortBucketsSlice = base.get("primarySortBuckets");
|
||||
|
||||
if (!primarySortBucketsSlice.isNone()) {
|
||||
if (!primarySortBucketsSlice.isNumber()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"invalid vpack format: 'primarySortBuckets' attribute is intended to be a number");
|
||||
}
|
||||
|
||||
primarySortBuckets = primarySortBucketsSlice.getNumber<size_t>();
|
||||
|
||||
if (primarySortBuckets > primarySort.size()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"invalid vpack format: value of 'primarySortBuckets' attribute '" + std::to_string(primarySortBuckets) +
|
||||
"' is greater than number of buckets specified in 'primarySort' attribute '" + std::to_string(primarySort.size()) +
|
||||
"' of the view '" + _view->name() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// set sort from corresponding view
|
||||
_sort.first = &primarySort;
|
||||
_sort.second = primarySortBuckets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,11 +896,15 @@ void IResearchViewNode::toVelocyPackHelper(VPackBuilder& nodes, unsigned flags)
|
|||
nodes.add("volatility", VPackValue(_volatilityMask));
|
||||
|
||||
// primarySort
|
||||
if (_sort && !_sort->empty()) {
|
||||
VPackArrayBuilder arrayScope(&nodes, "primarySort");
|
||||
_sort->toVelocyPack(nodes);
|
||||
if (_sort.first && !_sort.first->empty()) {
|
||||
{
|
||||
VPackArrayBuilder arrayScope(&nodes, "primarySort");
|
||||
_sort.first->toVelocyPack(nodes);
|
||||
}
|
||||
nodes.add("primarySortBuckets", VPackValue(_sort.second));
|
||||
}
|
||||
|
||||
|
||||
nodes.close();
|
||||
}
|
||||
|
||||
|
@ -1112,8 +1140,8 @@ std::unique_ptr<aql::ExecutionBlock> IResearchViewNode::createBlock(
|
|||
getRegisterPlan()->varInfo,
|
||||
getDepth()};
|
||||
|
||||
if (_sort) {
|
||||
TRI_ASSERT(!_sort->empty()); // guaranteed by optimizer rule
|
||||
if (_sort.first) {
|
||||
TRI_ASSERT(!_sort.first->empty()); // guaranteed by optimizer rule
|
||||
|
||||
if (!ordered) {
|
||||
return std::make_unique<aql::ExecutionBlockImpl<aql::IResearchViewMergeExecutor<false>>>(
|
||||
|
|
|
@ -132,13 +132,14 @@ class IResearchViewNode final : public arangodb::aql::ExecutionNode {
|
|||
}
|
||||
|
||||
/// @return sort condition satisfied by a sorted index
|
||||
IResearchViewSort const* sort() const noexcept {
|
||||
std::pair<IResearchViewSort const*, size_t> const& sort() const noexcept {
|
||||
return _sort;
|
||||
}
|
||||
|
||||
/// @brief set sort condition satisfied by a sorted index
|
||||
void sort(IResearchViewSort const* sort) noexcept {
|
||||
_sort = sort;
|
||||
void sort(IResearchViewSort const* sort, size_t size) noexcept {
|
||||
_sort.first = sort;
|
||||
_sort.second = sort ? std::min(size, sort->size()) : 0;
|
||||
}
|
||||
|
||||
/// @brief getVariablesUsedHere, modifying the set in-place
|
||||
|
@ -182,7 +183,9 @@ class IResearchViewNode final : public arangodb::aql::ExecutionNode {
|
|||
aql::AstNode const* _filterCondition;
|
||||
|
||||
/// @brief sort condition covered by the view
|
||||
IResearchViewSort const* _sort{};
|
||||
/// first - sort condition
|
||||
/// second - number of sort buckets to use
|
||||
std::pair<IResearchViewSort const*, size_t> _sort{};
|
||||
|
||||
/// @brief scorers related to the view
|
||||
std::vector<Scorer> _scorers;
|
||||
|
|
|
@ -248,7 +248,7 @@ bool optimizeSort(IResearchViewNode& viewNode, ExecutionPlan* plan) {
|
|||
}
|
||||
|
||||
assert(!primarySort.empty());
|
||||
viewNode.sort(&primarySort);
|
||||
viewNode.sort(&primarySort, sortElements.size());
|
||||
|
||||
sortNode->_reinsertInCluster = false;
|
||||
if (!arangodb::ServerState::instance()->isCoordinator()) {
|
||||
|
|
|
@ -147,15 +147,9 @@ arangodb::aql::AqlValue aqlFnTokens(arangodb::aql::ExpressionContext* expression
|
|||
auto data = arangodb::iresearch::getStringRef(args[0].slice());
|
||||
auto name = arangodb::iresearch::getStringRef(args[1].slice());
|
||||
auto* analyzers =
|
||||
arangodb::application_features::ApplicationServer::lookupFeature<arangodb::iresearch::IResearchAnalyzerFeature>();
|
||||
arangodb::application_features::ApplicationServer::getFeature<arangodb::iresearch::IResearchAnalyzerFeature>();
|
||||
|
||||
if (!analyzers) {
|
||||
irs::string_ref const message = "failure to find feature 'arangosearch' while "
|
||||
"computing result for function 'TOKENS'";
|
||||
|
||||
LOG_TOPIC("fbd91", WARN, arangodb::iresearch::TOPIC) << message;
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, message);
|
||||
}
|
||||
TRI_ASSERT(analyzers);
|
||||
|
||||
arangodb::iresearch::IResearchAnalyzerFeature::AnalyzerPool::ptr pool;
|
||||
|
||||
|
|
|
@ -566,15 +566,9 @@ void registerUpgradeTasks() {
|
|||
void registerViewFactory() {
|
||||
auto& viewType = arangodb::iresearch::DATA_SOURCE_TYPE;
|
||||
auto* viewTypes =
|
||||
arangodb::application_features::ApplicationServer::lookupFeature<arangodb::ViewTypesFeature>();
|
||||
arangodb::application_features::ApplicationServer::getFeature<arangodb::ViewTypesFeature>();
|
||||
|
||||
if (!viewTypes) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
std::string("failed to find feature '") +
|
||||
arangodb::ViewTypesFeature::name() +
|
||||
"' while registering view type '" +
|
||||
viewType.name() + "'");
|
||||
}
|
||||
TRI_ASSERT(viewTypes);
|
||||
|
||||
arangodb::Result res;
|
||||
|
||||
|
|
|
@ -39,18 +39,19 @@ namespace arangodb {
|
|||
namespace iresearch {
|
||||
|
||||
VPackComparer::VPackComparer()
|
||||
: _sort(&IResearchViewMeta::DEFAULT()._primarySort) {
|
||||
: VPackComparer(IResearchViewMeta::DEFAULT()._primarySort) {
|
||||
}
|
||||
|
||||
bool VPackComparer::less(const irs::bytes_ref& lhs, const irs::bytes_ref& rhs) const {
|
||||
TRI_ASSERT(_sort);
|
||||
TRI_ASSERT(_sort->size() >= _size);
|
||||
TRI_ASSERT(!lhs.empty());
|
||||
TRI_ASSERT(!rhs.empty());
|
||||
|
||||
VPackSlice lhsSlice(lhs.c_str());
|
||||
VPackSlice rhsSlice(rhs.c_str());
|
||||
|
||||
for (size_t i = 0, size = _sort->size(); i < size; ++i) {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
TRI_ASSERT(!lhsSlice.isNone());
|
||||
TRI_ASSERT(!rhsSlice.isNone());
|
||||
|
||||
|
|
|
@ -36,15 +36,20 @@ class VPackComparer final : public irs::comparer {
|
|||
VPackComparer();
|
||||
|
||||
explicit VPackComparer(IResearchViewSort const& sort) noexcept
|
||||
: _sort(&sort) {
|
||||
: _sort(&sort), _size(sort.size()) {
|
||||
}
|
||||
|
||||
VPackComparer(IResearchViewSort const& sort, size_t size) noexcept
|
||||
: _sort(&sort), _size(std::min(sort.size(), size)) {
|
||||
}
|
||||
|
||||
void reset(IResearchViewSort const& sort) noexcept {
|
||||
_sort = &sort;
|
||||
_size = sort.size();
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return _sort->empty();
|
||||
return 0 == _size;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -53,6 +58,7 @@ class VPackComparer final : public irs::comparer {
|
|||
|
||||
private:
|
||||
IResearchViewSort const* _sort;
|
||||
size_t _size; // number of buckets to compare
|
||||
}; // VPackComparer
|
||||
|
||||
} // iresearch
|
||||
|
|
|
@ -291,16 +291,11 @@ void JS_Create(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
PREVENT_EMBEDDED_TRANSACTION();
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::iresearch::IResearchAnalyzerFeature // feature type
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::getFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
|
||||
if (!analyzers) {
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_INTERNAL,
|
||||
"failure to find feature '" + arangodb::iresearch::IResearchAnalyzerFeature::name() + "'"
|
||||
);
|
||||
}
|
||||
TRI_ASSERT(analyzers);
|
||||
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature<
|
||||
arangodb::SystemDatabaseFeature
|
||||
|
@ -444,16 +439,11 @@ void JS_Get(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
PREVENT_EMBEDDED_TRANSACTION();
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::iresearch::IResearchAnalyzerFeature // feature type
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::getFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
|
||||
if (!analyzers) {
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE( // exception
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to find feature '") + arangodb::iresearch::IResearchAnalyzerFeature::name() + "'" // message
|
||||
);
|
||||
}
|
||||
TRI_ASSERT(analyzers);
|
||||
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::SystemDatabaseFeature // featue type
|
||||
|
@ -515,16 +505,11 @@ void JS_List(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::iresearch::IResearchAnalyzerFeature // feature type
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::getFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
|
||||
if (!analyzers) {
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE( // exception
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to find feature '") + arangodb::iresearch::IResearchAnalyzerFeature::name() + "'" // message
|
||||
);
|
||||
}
|
||||
TRI_ASSERT(analyzers);
|
||||
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::SystemDatabaseFeature // featue type
|
||||
|
@ -611,16 +596,11 @@ void JS_Remove(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
PREVENT_EMBEDDED_TRANSACTION();
|
||||
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::iresearch::IResearchAnalyzerFeature // feature type
|
||||
auto* analyzers = arangodb::application_features::ApplicationServer::getFeature<
|
||||
arangodb::iresearch::IResearchAnalyzerFeature
|
||||
>();
|
||||
|
||||
if (!analyzers) {
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE( // exception
|
||||
TRI_ERROR_INTERNAL, // code
|
||||
std::string("failure to find feature '") + arangodb::iresearch::IResearchAnalyzerFeature::name() + "'" // message
|
||||
);
|
||||
}
|
||||
TRI_ASSERT(analyzers);
|
||||
|
||||
auto* sysDatabase = arangodb::application_features::ApplicationServer::lookupFeature< // find feature
|
||||
arangodb::SystemDatabaseFeature // featue type
|
||||
|
|
|
@ -174,6 +174,151 @@ class IResearchViewNodeTest : public ::testing::Test {
|
|||
|
||||
} // namespace
|
||||
|
||||
TEST_F(IResearchViewNodeTest, constructSortedView) {
|
||||
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1,
|
||||
"testVocbase");
|
||||
// create view
|
||||
auto createJson = arangodb::velocypack::Parser::fromJson(
|
||||
"{ "
|
||||
" \"name\": \"testView\", "
|
||||
" \"type\": \"arangosearch\", "
|
||||
" \"primarySort\": [ "
|
||||
" { \"field\": \"my.nested.Fields\", \"asc\": false }, "
|
||||
" { \"field\": \"another.field\", \"asc\": true } ] "
|
||||
"}");
|
||||
auto logicalView = vocbase.createView(createJson->slice());
|
||||
ASSERT_TRUE(logicalView);
|
||||
|
||||
// dummy query
|
||||
arangodb::aql::Query query(false, vocbase, arangodb::aql::QueryString("RETURN 1"),
|
||||
nullptr, arangodb::velocypack::Parser::fromJson("{}"),
|
||||
arangodb::aql::PART_MAIN);
|
||||
query.prepare(arangodb::QueryRegistryFeature::registry());
|
||||
arangodb::aql::Variable const outVariable("variable", 0);
|
||||
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"options\": { \"waitForSync\" : "
|
||||
"true, \"collections\":[42] }, \"viewId\": \"" + std::to_string(logicalView->id()) + "\", "
|
||||
"\"primarySort\": [ { \"field\": \"my.nested.Fields\", \"asc\": false}, { \"field\": \"another.field\", \"asc\":true } ] }");
|
||||
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(node.sort().first); // primary sort is set
|
||||
EXPECT_EQ(2, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
EXPECT_TRUE(outVariable.name == node.outVariable().name);
|
||||
EXPECT_TRUE(query.plan() == node.plan());
|
||||
EXPECT_TRUE(42 == node.id());
|
||||
EXPECT_TRUE(logicalView == node.view());
|
||||
EXPECT_TRUE(node.scorers().empty());
|
||||
EXPECT_TRUE(!node.volatility().first); // filter volatility
|
||||
EXPECT_TRUE(!node.volatility().second); // sort volatility
|
||||
arangodb::HashSet<arangodb::aql::Variable const*> usedHere;
|
||||
node.getVariablesUsedHere(usedHere);
|
||||
EXPECT_TRUE(usedHere.empty());
|
||||
auto const setHere = node.getVariablesSetHere();
|
||||
EXPECT_TRUE(1 == setHere.size());
|
||||
EXPECT_TRUE(outVariable.id == setHere[0]->id);
|
||||
EXPECT_TRUE(outVariable.name == setHere[0]->name);
|
||||
EXPECT_TRUE(true == node.options().forceSync);
|
||||
EXPECT_TRUE(true == node.options().restrictSources);
|
||||
EXPECT_TRUE(1 == node.options().sources.size());
|
||||
EXPECT_TRUE(42 == *node.options().sources.begin());
|
||||
|
||||
EXPECT_TRUE(0. == node.getCost().estimatedCost); // no dependencies
|
||||
EXPECT_TRUE(0 == node.getCost().estimatedNrItems); // no dependencies
|
||||
}
|
||||
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"options\": { \"waitForSync\" : "
|
||||
"true, \"collections\":[42] }, \"viewId\": \"" + std::to_string(logicalView->id()) + "\", "
|
||||
"\"primarySort\": [ { \"field\": \"my.nested.Fields\", \"asc\": false}, { \"field\": \"another.field\", \"asc\":true } ], \"primarySortBuckets\": 1 }");
|
||||
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(node.sort().first); // primary sort is set
|
||||
EXPECT_EQ(1, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
EXPECT_TRUE(outVariable.name == node.outVariable().name);
|
||||
EXPECT_TRUE(query.plan() == node.plan());
|
||||
EXPECT_TRUE(42 == node.id());
|
||||
EXPECT_TRUE(logicalView == node.view());
|
||||
EXPECT_TRUE(node.scorers().empty());
|
||||
EXPECT_TRUE(!node.volatility().first); // filter volatility
|
||||
EXPECT_TRUE(!node.volatility().second); // sort volatility
|
||||
arangodb::HashSet<arangodb::aql::Variable const*> usedHere;
|
||||
node.getVariablesUsedHere(usedHere);
|
||||
EXPECT_TRUE(usedHere.empty());
|
||||
auto const setHere = node.getVariablesSetHere();
|
||||
EXPECT_TRUE(1 == setHere.size());
|
||||
EXPECT_TRUE(outVariable.id == setHere[0]->id);
|
||||
EXPECT_TRUE(outVariable.name == setHere[0]->name);
|
||||
EXPECT_TRUE(true == node.options().forceSync);
|
||||
EXPECT_TRUE(true == node.options().restrictSources);
|
||||
EXPECT_TRUE(1 == node.options().sources.size());
|
||||
EXPECT_TRUE(42 == *node.options().sources.begin());
|
||||
|
||||
EXPECT_TRUE(0. == node.getCost().estimatedCost); // no dependencies
|
||||
EXPECT_TRUE(0 == node.getCost().estimatedNrItems); // no dependencies
|
||||
}
|
||||
|
||||
// invalid 'primarySortBuckets' specified
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"viewId\": \"" + std::to_string(logicalView->id()) + "\", "
|
||||
"\"primarySort\": [ { \"field\": \"my.nested.Fields\", \"asc\": false}, { \"field\": \"another.field\", \"asc\":true } ], \"primarySortBuckets\": false }");
|
||||
|
||||
try {
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
EXPECT_TRUE(false);
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
EXPECT_TRUE(TRI_ERROR_BAD_PARAMETER == ex.code());
|
||||
}
|
||||
}
|
||||
|
||||
// invalid 'primarySortBuckets' specified
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"viewId\": \"" + std::to_string(logicalView->id()) + "\", "
|
||||
"\"primarySort\": [ { \"field\": \"my.nested.Fields\", \"asc\": false}, { \"field\": \"another.field\", \"asc\":true } ], \"primarySortBuckets\": 3 }");
|
||||
|
||||
try {
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
EXPECT_TRUE(false);
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
EXPECT_TRUE(TRI_ERROR_BAD_PARAMETER == ex.code());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IResearchViewNodeTest, construct) {
|
||||
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1,
|
||||
"testVocbase");
|
||||
|
@ -207,7 +352,8 @@ TEST_F(IResearchViewNodeTest, construct) {
|
|||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort()); // primary sort is not set by default
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(&outVariable == &node.outVariable());
|
||||
|
@ -445,7 +591,88 @@ TEST_F(IResearchViewNodeTest, constructFromVPackSingleServer) {
|
|||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
EXPECT_TRUE(outVariable.name == node.outVariable().name);
|
||||
EXPECT_TRUE(query.plan() == node.plan());
|
||||
EXPECT_TRUE(42 == node.id());
|
||||
EXPECT_TRUE(logicalView == node.view());
|
||||
EXPECT_TRUE(node.scorers().empty());
|
||||
EXPECT_TRUE(!node.volatility().first); // filter volatility
|
||||
EXPECT_TRUE(!node.volatility().second); // sort volatility
|
||||
arangodb::HashSet<arangodb::aql::Variable const*> usedHere;
|
||||
node.getVariablesUsedHere(usedHere);
|
||||
EXPECT_TRUE(usedHere.empty());
|
||||
auto const setHere = node.getVariablesSetHere();
|
||||
EXPECT_TRUE(1 == setHere.size());
|
||||
EXPECT_TRUE(outVariable.id == setHere[0]->id);
|
||||
EXPECT_TRUE(outVariable.name == setHere[0]->name);
|
||||
EXPECT_TRUE(false == node.options().forceSync);
|
||||
|
||||
EXPECT_TRUE(0. == node.getCost().estimatedCost); // no dependencies
|
||||
EXPECT_TRUE(0 == node.getCost().estimatedNrItems); // no dependencies
|
||||
}
|
||||
|
||||
// no options, ignore 'primarySortBuckets'
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"viewId\": \"" +
|
||||
std::to_string(logicalView->id()) + "\", \"primarySort\": [], \"primarySortBuckets\": false }");
|
||||
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
EXPECT_TRUE(outVariable.name == node.outVariable().name);
|
||||
EXPECT_TRUE(query.plan() == node.plan());
|
||||
EXPECT_TRUE(42 == node.id());
|
||||
EXPECT_TRUE(logicalView == node.view());
|
||||
EXPECT_TRUE(node.scorers().empty());
|
||||
EXPECT_TRUE(!node.volatility().first); // filter volatility
|
||||
EXPECT_TRUE(!node.volatility().second); // sort volatility
|
||||
arangodb::HashSet<arangodb::aql::Variable const*> usedHere;
|
||||
node.getVariablesUsedHere(usedHere);
|
||||
EXPECT_TRUE(usedHere.empty());
|
||||
auto const setHere = node.getVariablesSetHere();
|
||||
EXPECT_TRUE(1 == setHere.size());
|
||||
EXPECT_TRUE(outVariable.id == setHere[0]->id);
|
||||
EXPECT_TRUE(outVariable.name == setHere[0]->name);
|
||||
EXPECT_TRUE(false == node.options().forceSync);
|
||||
|
||||
EXPECT_TRUE(0. == node.getCost().estimatedCost); // no dependencies
|
||||
EXPECT_TRUE(0 == node.getCost().estimatedNrItems); // no dependencies
|
||||
}
|
||||
|
||||
// no options
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson(
|
||||
"{ \"id\":42, \"depth\":0, \"totalNrRegs\":0, \"varInfoList\":[], "
|
||||
"\"nrRegs\":[], \"nrRegsHere\":[], \"regsToClear\":[], "
|
||||
"\"varsUsedLater\":[], \"varsValid\":[], \"outVariable\": { "
|
||||
"\"name\":\"variable\", \"id\":0 }, \"viewId\": \"" +
|
||||
std::to_string(logicalView->id()) + "\", \"primarySort\": [], \"primarySortBuckets\": 42 }");
|
||||
|
||||
arangodb::iresearch::IResearchViewNode node(*query.plan(), // plan
|
||||
json->slice());
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
|
@ -485,7 +712,8 @@ TEST_F(IResearchViewNodeTest, constructFromVPackSingleServer) {
|
|||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
|
@ -528,7 +756,8 @@ TEST_F(IResearchViewNodeTest, constructFromVPackSingleServer) {
|
|||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
|
@ -570,7 +799,8 @@ TEST_F(IResearchViewNodeTest, constructFromVPackSingleServer) {
|
|||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
EXPECT_TRUE(node.shards().empty());
|
||||
EXPECT_TRUE(!node.sort());
|
||||
EXPECT_TRUE(!node.sort().first); // primary sort is not set by default
|
||||
EXPECT_EQ(0, node.sort().second); // primary sort is not set by default
|
||||
|
||||
EXPECT_TRUE(arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW == node.getType());
|
||||
EXPECT_TRUE(outVariable.id == node.outVariable().id);
|
||||
|
@ -1005,7 +1235,7 @@ TEST_F(IResearchViewNodeTest, clone) {
|
|||
nullptr, // no options
|
||||
{} // no scorers
|
||||
);
|
||||
node.sort(&sort);
|
||||
node.sort(&sort, 0);
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
|
@ -1310,7 +1540,7 @@ TEST_F(IResearchViewNodeTest, serializeSortedView) {
|
|||
nullptr, // no options
|
||||
{} // no sort condition
|
||||
);
|
||||
node.sort(&viewImpl.primarySort());
|
||||
node.sort(&viewImpl.primarySort(), 1);
|
||||
|
||||
EXPECT_TRUE(node.empty()); // view has no links
|
||||
EXPECT_TRUE(node.collections().empty()); // view has no links
|
||||
|
@ -1346,6 +1576,7 @@ TEST_F(IResearchViewNodeTest, serializeSortedView) {
|
|||
EXPECT_TRUE(node.volatility() == deserialized.volatility());
|
||||
EXPECT_TRUE(node.options().forceSync == deserialized.options().forceSync);
|
||||
EXPECT_TRUE(node.sort() == deserialized.sort());
|
||||
EXPECT_EQ(1, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(node.getCost() == deserialized.getCost());
|
||||
}
|
||||
|
@ -1371,6 +1602,7 @@ TEST_F(IResearchViewNodeTest, serializeSortedView) {
|
|||
EXPECT_TRUE(node.volatility() == deserialized.volatility());
|
||||
EXPECT_TRUE(node.options().forceSync == deserialized.options().forceSync);
|
||||
EXPECT_TRUE(node.sort() == deserialized.sort());
|
||||
EXPECT_EQ(1, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(node.getCost() == deserialized.getCost());
|
||||
}
|
||||
|
@ -1432,6 +1664,7 @@ TEST_F(IResearchViewNodeTest, serializeSortedView) {
|
|||
EXPECT_TRUE(node.volatility() == deserialized.volatility());
|
||||
EXPECT_TRUE(node.options().forceSync == deserialized.options().forceSync);
|
||||
EXPECT_TRUE(node.sort() == deserialized.sort());
|
||||
EXPECT_EQ(0, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(node.getCost() == deserialized.getCost());
|
||||
}
|
||||
|
@ -1457,6 +1690,7 @@ TEST_F(IResearchViewNodeTest, serializeSortedView) {
|
|||
EXPECT_TRUE(node.volatility() == deserialized.volatility());
|
||||
EXPECT_TRUE(node.options().forceSync == deserialized.options().forceSync);
|
||||
EXPECT_TRUE(node.sort() == deserialized.sort());
|
||||
EXPECT_EQ(0, node.sort().second);
|
||||
|
||||
EXPECT_TRUE(node.getCost() == deserialized.getCost());
|
||||
}
|
||||
|
|
|
@ -352,7 +352,8 @@ TEST_F(IResearchViewSortedTest, SingleField) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(1, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
auto queryResult = arangodb::tests::executeQuery(vocbase, query);
|
||||
|
@ -402,7 +403,8 @@ TEST_F(IResearchViewSortedTest, SingleField) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(1, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
std::vector<arangodb::ManagedDocumentResult const*> expectedDocs{
|
||||
|
@ -461,7 +463,8 @@ TEST_F(IResearchViewSortedTest, SingleField) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(1, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
std::vector<arangodb::ManagedDocumentResult const*> expectedDocs{
|
||||
|
@ -639,7 +642,8 @@ TEST_F(IResearchViewSortedTest, MultipleFields) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(4, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
auto queryResult = arangodb::tests::executeQuery(vocbase, query);
|
||||
|
@ -688,104 +692,8 @@ TEST_F(IResearchViewSortedTest, MultipleFields) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
|
||||
// check query execution
|
||||
auto queryResult = arangodb::tests::executeQuery(vocbase, query);
|
||||
ASSERT_TRUE(queryResult.result.ok());
|
||||
|
||||
auto result = queryResult.data->slice();
|
||||
EXPECT_TRUE(result.isArray());
|
||||
|
||||
arangodb::velocypack::ArrayIterator resultIt(result);
|
||||
EXPECT_TRUE(insertedDocs.size() == resultIt.size());
|
||||
|
||||
auto expectedDoc = insertedDocs.rbegin();
|
||||
for (auto const actualDoc : resultIt) {
|
||||
auto const resolved = actualDoc.resolveExternals();
|
||||
|
||||
EXPECT_TRUE(0 == arangodb::basics::VelocyPackHelper::compare(
|
||||
arangodb::velocypack::Slice(expectedDoc->vpack()), resolved, true));
|
||||
++expectedDoc;
|
||||
}
|
||||
EXPECT_TRUE(expectedDoc == insertedDocs.rend());
|
||||
}
|
||||
|
||||
// return all
|
||||
{
|
||||
std::string const query =
|
||||
"FOR d IN testView SORT d.same, d.same DESC RETURN d";
|
||||
|
||||
EXPECT_TRUE(arangodb::tests::assertRules(
|
||||
vocbase, query, {arangodb::aql::OptimizerRule::handleArangoSearchViewsRule}));
|
||||
|
||||
arangodb::SmallVector<arangodb::aql::ExecutionNode*>::allocator_type::arena_type a;
|
||||
arangodb::SmallVector<arangodb::aql::ExecutionNode*> nodes{a};
|
||||
auto preparedQuery = arangodb::tests::prepareQuery(vocbase, query);
|
||||
auto plan = preparedQuery->plan();
|
||||
ASSERT_TRUE(plan);
|
||||
plan->findVarUsage();
|
||||
|
||||
// ensure sort node is optimized out
|
||||
plan->findNodesOfType(nodes, arangodb::aql::ExecutionNode::SORT, true);
|
||||
EXPECT_TRUE(nodes.empty());
|
||||
|
||||
// check sort is set
|
||||
plan->findNodesOfType(nodes, arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW, true);
|
||||
EXPECT_TRUE(1 == nodes.size());
|
||||
auto* viewNode =
|
||||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
|
||||
// check query execution
|
||||
auto queryResult = arangodb::tests::executeQuery(vocbase, query);
|
||||
ASSERT_TRUE(queryResult.result.ok());
|
||||
|
||||
auto result = queryResult.data->slice();
|
||||
EXPECT_TRUE(result.isArray());
|
||||
|
||||
arangodb::velocypack::ArrayIterator resultIt(result);
|
||||
EXPECT_TRUE(insertedDocs.size() == resultIt.size());
|
||||
|
||||
auto expectedDoc = insertedDocs.rbegin();
|
||||
for (auto const actualDoc : resultIt) {
|
||||
auto const resolved = actualDoc.resolveExternals();
|
||||
|
||||
EXPECT_TRUE(0 == arangodb::basics::VelocyPackHelper::compare(
|
||||
arangodb::velocypack::Slice(expectedDoc->vpack()), resolved, true));
|
||||
++expectedDoc;
|
||||
}
|
||||
EXPECT_TRUE(expectedDoc == insertedDocs.rend());
|
||||
}
|
||||
|
||||
// return all
|
||||
{
|
||||
std::string const query = "FOR d IN testView SORT d.same RETURN d";
|
||||
|
||||
EXPECT_TRUE(arangodb::tests::assertRules(
|
||||
vocbase, query, {arangodb::aql::OptimizerRule::handleArangoSearchViewsRule}));
|
||||
|
||||
arangodb::SmallVector<arangodb::aql::ExecutionNode*>::allocator_type::arena_type a;
|
||||
arangodb::SmallVector<arangodb::aql::ExecutionNode*> nodes{a};
|
||||
auto preparedQuery = arangodb::tests::prepareQuery(vocbase, query);
|
||||
auto plan = preparedQuery->plan();
|
||||
ASSERT_TRUE(plan);
|
||||
plan->findVarUsage();
|
||||
|
||||
// ensure sort node is optimized out
|
||||
plan->findNodesOfType(nodes, arangodb::aql::ExecutionNode::SORT, true);
|
||||
EXPECT_TRUE(nodes.empty());
|
||||
|
||||
// check sort is set
|
||||
plan->findNodesOfType(nodes, arangodb::aql::ExecutionNode::ENUMERATE_IRESEARCH_VIEW, true);
|
||||
EXPECT_TRUE(1 == nodes.size());
|
||||
auto* viewNode =
|
||||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(3, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
auto queryResult = arangodb::tests::executeQuery(vocbase, query);
|
||||
|
@ -835,7 +743,8 @@ TEST_F(IResearchViewSortedTest, MultipleFields) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(3, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
std::vector<arangodb::ManagedDocumentResult const*> expectedDocs{
|
||||
|
@ -894,7 +803,8 @@ TEST_F(IResearchViewSortedTest, MultipleFields) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(4, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
std::vector<arangodb::ManagedDocumentResult const*> expectedDocs{
|
||||
|
@ -951,7 +861,8 @@ TEST_F(IResearchViewSortedTest, MultipleFields) {
|
|||
arangodb::aql::ExecutionNode::castTo<arangodb::iresearch::IResearchViewNode*>(
|
||||
nodes.front());
|
||||
ASSERT_TRUE(viewNode);
|
||||
EXPECT_TRUE(viewNode->sort());
|
||||
EXPECT_TRUE(viewNode->sort().first);
|
||||
EXPECT_EQ(2, viewNode->sort().second);
|
||||
|
||||
// check query execution
|
||||
std::vector<arangodb::ManagedDocumentResult const*> expectedDocs{};
|
||||
|
|
Loading…
Reference in New Issue