1
0
Fork 0

Fixed issue #9795 Fixed NOT IN clause in ArangoSearch (#9836)

* Fixed issue #9795 Fixed NOT IN clause in ArangoSearch

* Update CHANGELOG
This commit is contained in:
Dronplane 2019-08-28 18:38:02 +03:00 committed by KVS85
parent 7aea108197
commit 1eef617a07
7 changed files with 1101 additions and 487 deletions

View File

@ -1,6 +1,9 @@
v3.5.1 (XXXX-XX-XX)
-------------------
* Fixed issue #9795: fix AQL `NOT IN` clause in SEARCH operations for ArangoSearch
views.
* Make minimum timeout for synchronous replication configurable via parameter
(--cluster.synchronous-replication-timeout-minimum) and increase default value
to prevent dropping followers unnecessarily.

View File

@ -793,7 +793,7 @@ arangodb::Result fromInArray(irs::boolean_filter* filter, QueryContext const& ct
if (filter) {
filter = arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NIN == node.type
? &static_cast<irs::boolean_filter&>(
filter->add<irs::Not>().filter<irs::And>())
filter->add<irs::Not>().filter<irs::Or>())
: &static_cast<irs::boolean_filter&>(filter->add<irs::Or>());
filter->boost(filterCtx.boost);
}
@ -934,7 +934,7 @@ arangodb::Result fromIn(irs::boolean_filter* filter, QueryContext const& ctx,
filter = arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NIN == node.type
? &static_cast<irs::boolean_filter&>(
filter->add<irs::Not>().filter<irs::And>())
filter->add<irs::Not>().filter<irs::Or>())
: &static_cast<irs::boolean_filter&>(filter->add<irs::Or>());
filter->boost(filterCtx.boost);

View File

@ -2563,7 +2563,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// simple attribute
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("a")).term("1");
root.add<irs::by_term>().field(mangleStringIdentity("a")).term("2");
root.add<irs::by_term>().field(mangleStringIdentity("a")).term("3");
@ -2577,7 +2577,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// simple offset
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("[1]")).term("1");
root.add<irs::by_term>().field(mangleStringIdentity("[1]")).term("2");
root.add<irs::by_term>().field(mangleStringIdentity("[1]")).term("3");
@ -2589,7 +2589,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// complex attribute name
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("1");
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("2");
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("3");
@ -2609,7 +2609,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// complex attribute name, offset
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleStringIdentity("a.b.c[323].e.f"))
.term("1");
@ -2637,7 +2637,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// complex attribute name, offset
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(1.5);
root.add<irs::by_term>()
.field(mangleStringIdentity("a.b.c[323].e.f"))
@ -2666,7 +2666,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// complex attribute name, offset, analyzer
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleString("a.b.c[323].e.f", "test_analyzer"))
.term("1");
@ -2694,7 +2694,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// complex attribute name, offset, analyzer, boost
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(2.5);
root.add<irs::by_term>()
.field(mangleString("a.b.c[323].e.f", "test_analyzer"))
@ -2723,7 +2723,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// heterogeneous array values
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleStringIdentity("quick.brown.fox"))
.term("1");
@ -2755,7 +2755,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// heterogeneous array values, analyzer
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleString("quick.brown.fox", "test_analyzer"))
.term("1");
@ -2783,7 +2783,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// heterogeneous array values, analyzer, boost
{
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(1.5);
root.add<irs::by_term>()
.field(mangleString("quick.brown.fox", "test_analyzer"))
@ -2829,7 +2829,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
arangodb::aql::AqlValueHintDouble{5.6})));
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleStringIdentity("a.b.c.e[4].f[5].g[3].g.a"))
.term("1");
@ -2915,7 +2915,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace("x", value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("1");
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("3");
@ -2945,7 +2945,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace("x", value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleString("a.b.c.e.f", "test_analyzer"))
.term("1");
@ -2975,7 +2975,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace("x", value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(3.5);
root.add<irs::by_term>()
.field(mangleString("a.b.c.e.f", "test_analyzer"))
@ -3010,7 +3010,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace(var.name, value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("1");
root.add<irs::by_term>().field(mangleNumeric("a.b.c.e.f")).term(term->value());
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("3");
@ -3039,7 +3039,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace(var.name, value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>()
.field(mangleString("a.b.c.e.f", "test_analyzer"))
.term("1");
@ -3072,7 +3072,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
ctx.vars.emplace(var.name, value);
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(1.5);
root.add<irs::by_term>()
.field(mangleString("a.b.c.e.f", "test_analyzer"))
@ -3172,12 +3172,12 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{
@ -3202,7 +3202,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
EXPECT_TRUE(expected == *begin);
}
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3282,12 +3282,12 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{
@ -3312,7 +3312,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
EXPECT_TRUE(expected == *begin);
}
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3392,12 +3392,12 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{
@ -3422,7 +3422,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
EXPECT_TRUE(expected == *begin);
}
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3502,13 +3502,13 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
EXPECT_TRUE(1.5f == andNode->boost());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
EXPECT_TRUE(1.5f == orNode->boost());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{
@ -3533,7 +3533,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
EXPECT_TRUE(expected == *begin);
}
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3613,12 +3613,12 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{
@ -3643,7 +3643,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
dynamic_cast<arangodb::iresearch::ByExpression const*>(&*begin));
}
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3721,11 +3721,11 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
EXPECT_TRUE(1 == actual.size());
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto begin = andNode->begin();
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = orNode->begin();
// 1st filter
{ EXPECT_TRUE(irs::empty() == *begin); }
@ -3741,7 +3741,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// 3rd filter
{ EXPECT_TRUE(irs::all() == *++begin); }
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3820,12 +3820,12 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& notNode = dynamic_cast<irs::Not&>(*actual.begin());
EXPECT_TRUE(irs::Not::type() == notNode.type());
auto const* andNode = dynamic_cast<irs::And const*>(notNode.filter());
EXPECT_TRUE(andNode);
EXPECT_TRUE(irs::And::type() == andNode->type());
EXPECT_TRUE(3 == andNode->size());
auto const* orNode = dynamic_cast<irs::Or const*>(notNode.filter());
EXPECT_TRUE(orNode);
EXPECT_TRUE(irs::Or::type() == orNode->type());
EXPECT_TRUE(3 == orNode->size());
auto begin = andNode->begin();
auto begin = orNode->begin();
// 1st filter
{ EXPECT_TRUE(irs::empty() == *begin); }
@ -3845,7 +3845,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
// 3rd filter
{ EXPECT_TRUE(irs::all() == *++begin); }
EXPECT_TRUE(andNode->end() == ++begin);
EXPECT_TRUE(orNode->end() == ++begin);
}
}
}
@ -3868,7 +3868,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& term = stream.attributes().get<irs::term_attribute>();
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("1");
root.add<irs::by_term>()
.field(mangleStringIdentity("a.b.c.e.f"))
@ -3902,7 +3902,7 @@ TEST_F(IResearchFilterInTest, BinaryNotIn) {
auto& term = stream.attributes().get<irs::term_attribute>();
irs::Or expected;
auto& root = expected.add<irs::Not>().filter<irs::And>();
auto& root = expected.add<irs::Not>().filter<irs::Or>();
root.boost(2.5);
root.add<irs::by_term>().field(mangleStringIdentity("a.b.c.e.f")).term("1");
root.add<irs::by_term>()

View File

@ -311,6 +311,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[1].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value IN [ true ] SORT BM25(d) ASC, "
@ -322,12 +323,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_LT(i, expected.size());
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
}
EXPECT_TRUE((i == expected.size()));
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value NOT IN [ true ] SORT BM25(d) ASC, "
"TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
}
// test bool via []
@ -335,6 +355,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[1].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] IN [ true, false ] SORT BM25(d) "
@ -346,12 +367,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] NOT IN [ true, false ] SORT BM25(d) "
"ASC, TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// test numeric
@ -361,6 +401,7 @@ TEST_F(IResearchQueryInTest, test) {
insertedDocs[11].slice(),
insertedDocs[13].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value IN [ 123, 1234 ] SORT BM25(d) ASC, "
@ -372,12 +413,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value NOT IN [ 123, 1234 ] SORT BM25(d) ASC, "
"TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// test numeric, limit 2
@ -386,6 +446,7 @@ TEST_F(IResearchQueryInTest, test) {
insertedDocs[8].slice(),
insertedDocs[11].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value IN [ 123, 1234 ] SORT BM25(d) ASC, "
@ -397,12 +458,33 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value NOT IN [ 123, 1234 ] SORT BM25(d) ASC, "
"TFIDF(d) DESC, d.seq LIMIT 2 RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
// this also must not be there (it is not in expected due to LIMIT clause)
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(insertedDocs[13].slice(), resolved, true));
++i;
}
EXPECT_EQ(i, 2);
}
EXPECT_TRUE((i == expected.size()));
}
// test numeric via []
@ -412,6 +494,7 @@ TEST_F(IResearchQueryInTest, test) {
insertedDocs[11].slice(),
insertedDocs[13].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] IN [ 123, 1234 ] SORT BM25(d) "
@ -423,12 +506,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] NOT IN [ 123, 1234 ] SORT BM25(d) "
"ASC, TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// test null
@ -436,6 +538,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[0].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value IN [ null ] SORT BM25(d) ASC, "
@ -447,12 +550,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value NOT IN [ null ] SORT BM25(d) ASC, "
"TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// test null via []
@ -460,6 +582,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[0].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] IN [ null, null ] SORT BM25(d) "
@ -471,12 +594,32 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_TRUE((i == expected.size()));
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] NOT IN [ null, null ] SORT BM25(d) "
"ASC, TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
}
// test object
@ -508,6 +651,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[2].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value IN [ \"abc\", \"xyz\" ] SORT BM25(d) "
@ -519,12 +663,32 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_TRUE((i == expected.size()));
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d.value NOT IN [ \"abc\", \"xyz\" ] SORT BM25(d) "
"ASC, TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
}
// test string via []
@ -532,6 +696,7 @@ TEST_F(IResearchQueryInTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[2].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] IN [ \"abc\", \"xyz\" ] SORT "
@ -543,11 +708,31 @@ TEST_F(IResearchQueryInTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_TRUE((i == expected.size()));
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH d['value'] NOT IN [ \"abc\", \"xyz\" ] SORT "
"BM25(d) ASC, TFIDF(d) DESC, d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
}
}

View File

@ -326,6 +326,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[1].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.value, false, true, false, true) "
@ -338,12 +339,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.value, false, true, false, true)) "
"SORT d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.value >= null && d.value <= null
@ -351,6 +371,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[0].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.value, null, null, true, true) "
@ -362,18 +383,37 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.value, null, null, true, true)) "
"SORT d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.value > null && d.value <= null
{
std::vector<arangodb::velocypack::Slice> expected = {};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.value, null, null, false, true) "
@ -385,13 +425,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.value, null, null, false, true)) "
"SORT d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name >= 'A' && d.name <= 'A'
@ -399,6 +457,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[6].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'A', 'A', true, true) SORT "
@ -410,18 +469,37 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'A', 'A', true, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name >= 'B' && d.name <= 'A'
{
std::vector<arangodb::velocypack::Slice> expected = {};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'B', 'A', true, true) SORT "
@ -433,13 +511,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'B', 'A', true, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name >= 'A' && d.name <= 'E'
@ -449,6 +545,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[8].slice(), insertedDocs[9].slice(),
insertedDocs[10].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'A', 'E', true, true) SORT "
@ -460,13 +557,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'A', 'E', true, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name >= 'A' && d.name < 'E'
@ -477,6 +592,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[8].slice(),
insertedDocs[9].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'A', 'E', true, false) SORT "
@ -488,13 +604,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'A', 'E', true, false)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name > 'A' && d.name <= 'E'
@ -505,6 +639,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[9].slice(),
insertedDocs[10].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'A', 'E', false, true) SORT "
@ -516,13 +651,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'A', 'E', false, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.name > 'A' && d.name < 'E'
@ -532,6 +685,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[8].slice(),
insertedDocs[9].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.name, 'A', 'E', false, false) "
@ -543,18 +697,37 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.name, 'A', 'E', false, false)) "
"SORT d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.seq >= 5 && d.seq <= -1
{
std::vector<arangodb::velocypack::Slice> expected = {};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.seq, 5, -1, true, true) SORT "
@ -566,13 +739,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.seq, 5, -1, true, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.seq >= 1 && d.seq <= 5
@ -582,6 +773,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[9].slice(), insertedDocs[10].slice(),
insertedDocs[11].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.seq, 1, 5, true, true) SORT d.seq "
@ -593,13 +785,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.seq, 1, 5, true, true)) SORT d.seq "
"RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.seq > -2 && d.seq <= 5
@ -610,6 +820,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[9].slice(), insertedDocs[10].slice(),
insertedDocs[11].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.seq, -2, 5, false, true) SORT "
@ -621,13 +832,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.seq, -2, 5, false, true)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.seq > 1 && d.seq < 5
@ -637,6 +866,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[9].slice(),
insertedDocs[10].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.seq, 1, 5, false, false) SORT "
@ -648,13 +878,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.seq, 1, 5, false, false)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.seq >= 1 && d.seq < 5
@ -665,6 +913,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
insertedDocs[9].slice(),
insertedDocs[10].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.seq, 1, 5, true, false) SORT "
@ -676,13 +925,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.seq, 1, 5, true, false)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.value > 3 && d.value < 4
@ -690,6 +957,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[3].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.value, 3, 4, false, false) SORT "
@ -701,13 +969,31 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.value, 3, 4, false, false)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
// d.value > -4 && d.value < -3
@ -715,6 +1001,7 @@ TEST_F(IResearchQueryInRangeTest, test) {
std::vector<arangodb::velocypack::Slice> expected = {
insertedDocs[3].slice(),
};
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH IN_RANGE(d.value, -4, -3, false, false) SORT "
@ -726,12 +1013,30 @@ TEST_F(IResearchQueryInRangeTest, test) {
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
EXPECT_TRUE((i < expected.size()));
EXPECT_TRUE((0 == arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true)));
EXPECT_LT(i, expected.size());
EXPECT_EQ(0, arangodb::basics::VelocyPackHelper::compare(expected[i++],
resolved, true));
}
EXPECT_EQ(i, expected.size());
}
//NOT
{
auto result = arangodb::tests::executeQuery(
vocbase,
"FOR d IN testView SEARCH NOT(IN_RANGE(d.value, -4, -3, false, false)) SORT "
"d.seq RETURN d");
ASSERT_TRUE(result.result.ok());
auto slice = result.data->slice();
EXPECT_TRUE(slice.isArray());
size_t i = 0;
for (arangodb::velocypack::ArrayIterator itr(slice); itr.valid(); ++itr) {
auto const resolved = itr.value().resolveExternals();
for (const auto& u : expected) {
EXPECT_NE(0, arangodb::basics::VelocyPackHelper::compare(u, resolved, true));
}
++i;
}
EXPECT_EQ(i, (insertedDocs.size() - expected.size()));
}
EXPECT_TRUE((i == expected.size()));
}
}

View File

@ -867,8 +867,75 @@
assertEqual(res.a, "foo");
assertTrue(res.score > 1 && res.score < 2);
});
}
},
testAttributeNotInRangeOpenInterval : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH NOT(IN_RANGE(doc.c, 1, 3, false, false)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 24);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c <= 1 || res.c >= 3);
});
},
testAttributeNotInRangeClosedInterval : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH NOT(IN_RANGE(doc.c, 1, 3, true, true)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 16);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c < 1 || res.c > 3);
});
},
testAttributeInRange : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c IN 1..3 OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 12);
result.forEach(function(res) {
assertTrue(res.c >= 1 || res.c <= 3);
});
},
testAttributeNotInRange : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c NOT IN 1..3 OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 16);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c < 1 || res.c > 3);
});
},
testAttributeInArray : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c IN [ 1, 3 ] OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 8);
result.forEach(function(res) {
assertTrue(res.c === 1 || res.c === 3);
});
},
testAttributeNotInArray : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c NOT IN [ 1, 3 ] OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 20);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c !== 1 && res.c !== 3);
});
},
testAttributeInExpression : function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 IN FLATTEN(c) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, db.UnitTestsCollection.toArray().length);
},
testAttributeNotInExpression: function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 NOT IN FLATTEN(c) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 0);
},
testAttributeInExpressionNonDet : function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 IN NOOPT(FLATTEN(c)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, db.UnitTestsCollection.toArray().length);
},
testAttributeNotInExpressionNonDet: function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 NOT IN NOOPT(FLATTEN(c)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 0);
}
};
}
}());

View File

@ -905,6 +905,60 @@ function iResearchAqlTestSuite () {
assertEqual(res.a, "foo");
assertTrue(res.score > 1 && res.score < 2);
});
},
testAttributeInRange : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c IN 1..3 OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 12);
result.forEach(function(res) {
assertTrue(res.c >= 1 || res.c <= 3);
});
},
testAttributeNotInRange : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c NOT IN 1..3 OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 16);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c < 1 || res.c > 3);
});
},
testAttributeInArray : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c IN [ 1, 3 ] OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 8);
result.forEach(function(res) {
assertTrue(res.c === 1 || res.c === 3);
});
},
testAttributeNotInArray : function () {
var result = db._query("FOR doc IN UnitTestsView SEARCH doc.c NOT IN [ 1, 3 ] OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 20);
result.forEach(function(res) {
assertTrue(res.c === undefined || res.c !== 1 && res.c !== 3);
});
},
testAttributeInExpression : function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 IN FLATTEN(c) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, db.UnitTestsCollection.toArray().length);
},
testAttributeNotInExpression: function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 NOT IN FLATTEN(c) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 0);
},
testAttributeInExpressionNonDet : function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 IN NOOPT(FLATTEN(c)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, db.UnitTestsCollection.toArray().length);
},
testAttributeNotInExpressionNonDet: function () {
var result = db._query("FOR c IN [[[1, 3]]] FOR doc IN UnitTestsView SEARCH 1 NOT IN NOOPT(FLATTEN(c)) OPTIONS { waitForSync : true } RETURN doc").toArray();
assertEqual(result.length, 0);
}
};