2017-04-26 22:29:57 +08:00
|
|
|
#include <cmath>
|
2017-03-27 19:09:14 +08:00
|
|
|
#include <iterator>
|
|
|
|
#include <memory>
|
2017-10-02 16:34:38 +08:00
|
|
|
#include <unordered_map>
|
2017-03-27 19:09:14 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2018-10-04 21:23:07 +08:00
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
2017-03-27 19:09:14 +08:00
|
|
|
|
2018-06-27 17:08:21 +08:00
|
|
|
#include "query/context.hpp"
|
2017-03-27 19:09:14 +08:00
|
|
|
#include "query/frontend/ast/ast.hpp"
|
|
|
|
#include "query/frontend/opencypher/parser.hpp"
|
2017-04-13 16:01:16 +08:00
|
|
|
#include "query/interpret/awesome_memgraph_functions.hpp"
|
|
|
|
#include "query/interpret/eval.hpp"
|
2017-05-05 18:16:04 +08:00
|
|
|
#include "query/interpret/frame.hpp"
|
2017-10-30 17:45:36 +08:00
|
|
|
#include "query/path.hpp"
|
2019-11-22 01:38:01 +08:00
|
|
|
#include "storage/v2/storage.hpp"
|
2017-09-05 17:26:46 +08:00
|
|
|
#include "utils/string.hpp"
|
2017-07-25 19:01:08 +08:00
|
|
|
|
2017-05-19 21:49:25 +08:00
|
|
|
#include "query_common.hpp"
|
2017-03-27 19:09:14 +08:00
|
|
|
|
|
|
|
using namespace query;
|
2019-08-22 20:50:57 +08:00
|
|
|
using query::test_common::ToIntList;
|
2017-10-30 17:43:25 +08:00
|
|
|
using testing::ElementsAre;
|
|
|
|
using testing::UnorderedElementsAre;
|
2017-04-24 22:01:00 +08:00
|
|
|
|
|
|
|
namespace {
|
2017-05-20 01:25:54 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
class ExpressionEvaluatorTest : public ::testing::Test {
|
|
|
|
protected:
|
2019-11-22 01:38:01 +08:00
|
|
|
storage::Storage db;
|
|
|
|
storage::Storage::Accessor storage_dba{db.Access()};
|
|
|
|
query::DbAccessor dba{&storage_dba};
|
2017-03-27 19:09:14 +08:00
|
|
|
|
2018-05-22 22:45:52 +08:00
|
|
|
AstStorage storage;
|
2019-06-07 20:31:25 +08:00
|
|
|
utils::MonotonicBufferResource mem{1024};
|
|
|
|
EvaluationContext ctx{&mem};
|
2018-09-05 00:02:30 +08:00
|
|
|
SymbolTable symbol_table;
|
2017-09-13 23:09:04 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
Frame frame{128};
|
2019-11-22 01:38:01 +08:00
|
|
|
ExpressionEvaluator eval{&frame, symbol_table, ctx, &dba, storage::View::OLD};
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
|
|
|
|
Identifier *CreateIdentifierWithValue(std::string name,
|
|
|
|
const TypedValue &value) {
|
|
|
|
auto id = storage.Create<Identifier>(name, true);
|
|
|
|
auto symbol = symbol_table.CreateSymbol(name, true);
|
2019-02-05 20:16:07 +08:00
|
|
|
id->MapTo(symbol);
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
frame[symbol] = value;
|
|
|
|
return id;
|
|
|
|
}
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
|
|
|
|
template <class TExpression>
|
|
|
|
auto Eval(TExpression *expr) {
|
2019-11-22 01:38:01 +08:00
|
|
|
ctx.properties = NamesToProperties(storage.properties_, &dba);
|
|
|
|
ctx.labels = NamesToLabels(storage.labels_, &dba);
|
2019-06-07 20:31:25 +08:00
|
|
|
auto value = expr->Accept(eval);
|
|
|
|
EXPECT_EQ(value.GetMemoryResource(), &mem)
|
|
|
|
<< "ExpressionEvaluator must use the MemoryResource from "
|
|
|
|
"EvaluationContext for allocations!";
|
|
|
|
return value;
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
}
|
2018-09-05 00:02:30 +08:00
|
|
|
};
|
2017-04-24 22:01:00 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, OrOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<OrOperator>(storage.Create<PrimitiveLiteral>(true),
|
|
|
|
storage.Create<PrimitiveLiteral>(false));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<OrOperator>(storage.Create<PrimitiveLiteral>(true),
|
|
|
|
storage.Create<PrimitiveLiteral>(true));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), true);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, XorOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<XorOperator>(storage.Create<PrimitiveLiteral>(true),
|
|
|
|
storage.Create<PrimitiveLiteral>(false));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<XorOperator>(storage.Create<PrimitiveLiteral>(true),
|
|
|
|
storage.Create<PrimitiveLiteral>(true));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), false);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, AndOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(true),
|
|
|
|
storage.Create<PrimitiveLiteral>(true));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(false),
|
|
|
|
storage.Create<PrimitiveLiteral>(true));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), false);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, AndOperatorShortCircuit) {
|
2017-05-08 21:49:02 +08:00
|
|
|
{
|
2017-09-20 21:31:23 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(false),
|
|
|
|
storage.Create<PrimitiveLiteral>(5));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), false);
|
2017-05-08 21:49:02 +08:00
|
|
|
}
|
|
|
|
{
|
2017-11-08 20:13:58 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<AndOperator>(storage.Create<PrimitiveLiteral>(5),
|
|
|
|
storage.Create<PrimitiveLiteral>(false));
|
2018-09-05 00:02:30 +08:00
|
|
|
// We are evaluating left to right, so we don't short circuit here and
|
|
|
|
// raise due to `5`. This differs from neo4j, where they evaluate both
|
|
|
|
// sides and return `false` without checking for type of the first
|
|
|
|
// expression.
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-11-08 20:13:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, AndOperatorNull) {
|
2017-11-08 20:13:58 +08:00
|
|
|
{
|
|
|
|
// Null doesn't short circuit
|
2017-09-20 21:31:23 +08:00
|
|
|
auto *op = storage.Create<AndOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-05-08 21:49:02 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(5));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-11-08 20:13:58 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
auto *op = storage.Create<AndOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-11-08 20:13:58 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(true));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-08 21:49:02 +08:00
|
|
|
}
|
2017-11-08 20:13:58 +08:00
|
|
|
{
|
|
|
|
auto *op = storage.Create<AndOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-11-08 20:13:58 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(false));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-11-08 20:13:58 +08:00
|
|
|
ASSERT_TRUE(value.IsBool());
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), false);
|
2017-11-08 20:13:58 +08:00
|
|
|
}
|
2017-05-08 21:49:02 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, AdditionOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<AdditionOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 5);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, SubtractionOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<SubtractionOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), -1);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, MultiplicationOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<MultiplicationOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(2), storage.Create<PrimitiveLiteral>(3));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 6);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, DivisionOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<DivisionOperator>(storage.Create<PrimitiveLiteral>(50),
|
|
|
|
storage.Create<PrimitiveLiteral>(10));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 5);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, ModOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<ModOperator>(storage.Create<PrimitiveLiteral>(65),
|
|
|
|
storage.Create<PrimitiveLiteral>(10));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 5);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, EqualOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), false);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, NotEqualOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<NotEqualOperator>(storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), true);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, LessOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<LessOperator>(storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), false);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, GreaterOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<GreaterOperator>(storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), true);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, LessEqualOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<LessEqualOperator>(storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), false);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, GreaterEqualOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op = storage.Create<GreaterEqualOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(10),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<GreaterEqualOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(15),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), true);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<GreaterEqualOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(20),
|
|
|
|
storage.Create<PrimitiveLiteral>(15));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val3 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val3.ValueBool(), true);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, InListOperator) {
|
2017-05-07 19:48:34 +08:00
|
|
|
auto *list_literal = storage.Create<ListLiteral>(std::vector<Expression *>{
|
|
|
|
storage.Create<PrimitiveLiteral>(1), storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>("a")});
|
|
|
|
{
|
|
|
|
// Element exists in list.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>(2), list_literal);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), true);
|
2017-05-07 19:48:34 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Element doesn't exist in list.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>("x"), list_literal);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), false);
|
2017-05-07 19:48:34 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
auto *list_literal = storage.Create<ListLiteral>(std::vector<Expression *>{
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-05-07 19:48:34 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>("a")});
|
|
|
|
// Element doesn't exist in list with null element.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>("x"), list_literal);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-07 19:48:34 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Null list.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>("x"),
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-07 19:48:34 +08:00
|
|
|
}
|
2017-11-14 21:42:58 +08:00
|
|
|
{
|
|
|
|
// Null literal.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
|
|
|
list_literal);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-11-14 21:42:58 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
// Null literal, empty list.
|
|
|
|
auto *op = storage.Create<InListOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-11-14 21:42:58 +08:00
|
|
|
storage.Create<ListLiteral>(std::vector<Expression *>()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-11-14 21:42:58 +08:00
|
|
|
EXPECT_FALSE(value.ValueBool());
|
|
|
|
}
|
2017-05-07 19:48:34 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, ListIndexing) {
|
2017-05-04 21:16:57 +08:00
|
|
|
auto *list_literal = storage.Create<ListLiteral>(std::vector<Expression *>{
|
|
|
|
storage.Create<PrimitiveLiteral>(1), storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(3),
|
|
|
|
storage.Create<PrimitiveLiteral>(4)});
|
|
|
|
{
|
|
|
|
// Legal indexing.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-05-04 21:16:57 +08:00
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(2));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueInt(), 3);
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Out of bounds indexing.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-05-04 21:16:57 +08:00
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(4));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Out of bounds indexing with negative bound.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-05-04 21:16:57 +08:00
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(-100));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Legal indexing with negative index.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-05-04 21:16:57 +08:00
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(-2));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueInt(), 3);
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Indexing with one operator being null.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-05-04 21:16:57 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(-2));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Indexing with incompatible type.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>("bla"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, MapIndexing) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto *map_literal =
|
|
|
|
storage.Create<MapLiteral>(std::unordered_map<PropertyIx, Expression *>{
|
|
|
|
{storage.GetPropertyIx("a"), storage.Create<PrimitiveLiteral>(1)},
|
|
|
|
{storage.GetPropertyIx("b"), storage.Create<PrimitiveLiteral>(2)},
|
|
|
|
{storage.GetPropertyIx("c"), storage.Create<PrimitiveLiteral>(3)}});
|
2017-09-02 20:30:05 +08:00
|
|
|
{
|
|
|
|
// Legal indexing.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-09-02 20:30:05 +08:00
|
|
|
map_literal, storage.Create<PrimitiveLiteral>("b"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueInt(), 2);
|
2017-09-02 20:30:05 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Legal indexing, non-existing key.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-09-02 20:30:05 +08:00
|
|
|
map_literal, storage.Create<PrimitiveLiteral>("z"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-09-02 20:30:05 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
// Wrong key type.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2017-09-02 20:30:05 +08:00
|
|
|
map_literal, storage.Create<PrimitiveLiteral>(42));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-09-02 20:30:05 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Indexing with Null.
|
2018-07-02 16:46:40 +08:00
|
|
|
auto *op = storage.Create<SubscriptOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
map_literal,
|
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-09-02 20:30:05 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) {
|
2019-11-22 01:38:01 +08:00
|
|
|
auto edge_type = dba.NameToEdgeType("edge_type");
|
|
|
|
auto prop = dba.NameToProperty("prop");
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e11 = dba.InsertEdge(&v1, &v1, edge_type);
|
|
|
|
ASSERT_TRUE(e11.HasValue());
|
2020-01-22 23:20:13 +08:00
|
|
|
ASSERT_TRUE(v1.SetProperty(prop, storage::PropertyValue(42)).HasValue());
|
|
|
|
ASSERT_TRUE(e11->SetProperty(prop, storage::PropertyValue(43)).HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
dba.AdvanceCommand();
|
|
|
|
|
|
|
|
auto *vertex_id = CreateIdentifierWithValue("v1", TypedValue(v1));
|
|
|
|
auto *edge_id = CreateIdentifierWithValue("e11", TypedValue(*e11));
|
2018-07-02 16:46:40 +08:00
|
|
|
{
|
|
|
|
// Legal indexing.
|
|
|
|
auto *op1 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
vertex_id, storage.Create<PrimitiveLiteral>("prop"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value1 = Eval(op1);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value1.ValueInt(), 42);
|
2018-07-02 16:46:40 +08:00
|
|
|
|
|
|
|
auto *op2 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
edge_id, storage.Create<PrimitiveLiteral>("prop"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value2 = Eval(op2);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value2.ValueInt(), 43);
|
2018-07-02 16:46:40 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Legal indexing, non-existing key.
|
|
|
|
auto *op1 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
vertex_id, storage.Create<PrimitiveLiteral>("blah"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value1 = Eval(op1);
|
2018-07-02 16:46:40 +08:00
|
|
|
EXPECT_TRUE(value1.IsNull());
|
|
|
|
|
|
|
|
auto *op2 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
edge_id, storage.Create<PrimitiveLiteral>("blah"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value2 = Eval(op2);
|
2018-07-02 16:46:40 +08:00
|
|
|
EXPECT_TRUE(value2.IsNull());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
// Wrong key type.
|
|
|
|
auto *op1 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
vertex_id, storage.Create<PrimitiveLiteral>(1));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op1), QueryRuntimeException);
|
2018-07-02 16:46:40 +08:00
|
|
|
|
|
|
|
auto *op2 = storage.Create<SubscriptOperator>(
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
edge_id, storage.Create<PrimitiveLiteral>(1));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op2), QueryRuntimeException);
|
2018-07-02 16:46:40 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Indexing with Null.
|
|
|
|
auto *op1 = storage.Create<SubscriptOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
vertex_id, storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value1 = Eval(op1);
|
2018-07-02 16:46:40 +08:00
|
|
|
EXPECT_TRUE(value1.IsNull());
|
|
|
|
|
|
|
|
auto *op2 = storage.Create<SubscriptOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
edge_id, storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value2 = Eval(op2);
|
2018-07-02 16:46:40 +08:00
|
|
|
EXPECT_TRUE(value2.IsNull());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, ListSlicingOperator) {
|
2017-05-04 21:16:57 +08:00
|
|
|
auto *list_literal = storage.Create<ListLiteral>(std::vector<Expression *>{
|
|
|
|
storage.Create<PrimitiveLiteral>(1), storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(3),
|
|
|
|
storage.Create<PrimitiveLiteral>(4)});
|
|
|
|
|
|
|
|
auto extract_ints = [](TypedValue list) {
|
|
|
|
std::vector<int64_t> int_list;
|
2018-09-05 00:02:30 +08:00
|
|
|
for (auto x : list.ValueList()) {
|
|
|
|
int_list.push_back(x.ValueInt());
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
return int_list;
|
|
|
|
};
|
|
|
|
{
|
|
|
|
// Legal slicing with both bounds defined.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(4));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre(3, 4));
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Legal slicing with negative bound.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(-1));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre(3));
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Lower bound larger than upper bound.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(-4));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre());
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Bounds ouf or range.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(-100),
|
|
|
|
storage.Create<PrimitiveLiteral>(10));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre(1, 2, 3, 4));
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Lower bound undefined.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, nullptr, storage.Create<PrimitiveLiteral>(3));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre(1, 2, 3));
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Upper bound undefined.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(-2), nullptr);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_THAT(extract_ints(value), ElementsAre(3, 4));
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Bound of illegal type and null value bound.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
list_literal,
|
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-05-04 21:16:57 +08:00
|
|
|
storage.Create<PrimitiveLiteral>("mirko"));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// List of illegal type.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
storage.Create<PrimitiveLiteral>("a"),
|
|
|
|
storage.Create<PrimitiveLiteral>(-2), nullptr);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(op), QueryRuntimeException);
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Null value list with undefined upper bound.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()),
|
2017-05-04 21:16:57 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(-2), nullptr);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
;
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
// Null value index.
|
|
|
|
auto *op = storage.Create<ListSlicingOperator>(
|
|
|
|
list_literal, storage.Create<PrimitiveLiteral>(-2),
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
;
|
2017-05-04 21:16:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, IfOperator) {
|
2017-08-20 19:53:50 +08:00
|
|
|
auto *then_expression = storage.Create<PrimitiveLiteral>(10);
|
|
|
|
auto *else_expression = storage.Create<PrimitiveLiteral>(20);
|
|
|
|
{
|
|
|
|
auto *condition_true =
|
|
|
|
storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(2));
|
|
|
|
auto *op = storage.Create<IfOperator>(condition_true, then_expression,
|
|
|
|
else_expression);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 10);
|
2017-08-20 19:53:50 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
auto *condition_false =
|
|
|
|
storage.Create<EqualOperator>(storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(3));
|
|
|
|
auto *op = storage.Create<IfOperator>(condition_false, then_expression,
|
|
|
|
else_expression);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 20);
|
2017-08-20 19:53:50 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
auto *condition_exception =
|
|
|
|
storage.Create<AdditionOperator>(storage.Create<PrimitiveLiteral>(2),
|
|
|
|
storage.Create<PrimitiveLiteral>(3));
|
|
|
|
auto *op = storage.Create<IfOperator>(condition_exception, then_expression,
|
|
|
|
else_expression);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
ASSERT_THROW(Eval(op), QueryRuntimeException);
|
2017-08-20 19:53:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, NotOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<NotOperator>(storage.Create<PrimitiveLiteral>(false));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueBool(), true);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, UnaryPlusOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<UnaryPlusOperator>(storage.Create<PrimitiveLiteral>(5));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), 5);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, UnaryMinusOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<UnaryMinusOperator>(storage.Create<PrimitiveLiteral>(5));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(value.ValueInt(), -5);
|
2017-03-27 19:09:14 +08:00
|
|
|
}
|
2017-04-10 22:33:53 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, IsNullOperator) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *op =
|
|
|
|
storage.Create<IsNullOperator>(storage.Create<PrimitiveLiteral>(1));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val1 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val1.ValueBool(), false);
|
2017-04-28 18:06:18 +08:00
|
|
|
op = storage.Create<IsNullOperator>(
|
2020-01-22 23:20:13 +08:00
|
|
|
storage.Create<PrimitiveLiteral>(storage::PropertyValue()));
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto val2 = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(val2.ValueBool(), true);
|
2017-08-08 19:43:42 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, LabelsTest) {
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("ANIMAL")).HasValue());
|
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("DOG")).HasValue());
|
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("NICE_DOG")).HasValue());
|
|
|
|
dba.AdvanceCommand();
|
2017-05-05 18:16:04 +08:00
|
|
|
auto *identifier = storage.Create<Identifier>("n");
|
2018-09-05 00:02:30 +08:00
|
|
|
auto node_symbol = symbol_table.CreateSymbol("n", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
identifier->MapTo(node_symbol);
|
2019-11-22 01:38:01 +08:00
|
|
|
frame[node_symbol] = TypedValue(v1);
|
2017-05-05 18:16:04 +08:00
|
|
|
{
|
|
|
|
auto *op = storage.Create<LabelsTest>(
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
identifier, std::vector<LabelIx>{storage.GetLabelIx("DOG"),
|
|
|
|
storage.GetLabelIx("ANIMAL")});
|
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), true);
|
2017-05-05 18:16:04 +08:00
|
|
|
}
|
|
|
|
{
|
|
|
|
auto *op = storage.Create<LabelsTest>(
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
identifier, std::vector<LabelIx>{storage.GetLabelIx("DOG"),
|
|
|
|
storage.GetLabelIx("BAD_DOG"),
|
|
|
|
storage.GetLabelIx("ANIMAL")});
|
|
|
|
auto value = Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueBool(), false);
|
2017-05-05 18:16:04 +08:00
|
|
|
}
|
|
|
|
{
|
2019-06-04 22:11:31 +08:00
|
|
|
frame[node_symbol] = TypedValue();
|
2017-05-05 18:16:04 +08:00
|
|
|
auto *op = storage.Create<LabelsTest>(
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
identifier, std::vector<LabelIx>{storage.GetLabelIx("DOG"),
|
|
|
|
storage.GetLabelIx("BAD_DOG"),
|
|
|
|
storage.GetLabelIx("ANIMAL")});
|
|
|
|
auto value = Eval(op);
|
2017-05-16 16:55:02 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
2017-05-05 18:16:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, Aggregation) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto aggr = storage.Create<Aggregation>(storage.Create<PrimitiveLiteral>(42),
|
Collect Map added
Summary:
Tests are on the way. Please first comment if you're OK with this implementation, some points are discussable.
What works now:
```
bash:MEMGRAPH_ROOT/build/>./tests/manual/console 10
MG>MATCH (n) RETURN COLLECT("age_" + n.age, n.height)
+-----------------------------------------------------------------------------------------------------------------------------------+
| COLLECT("age_" + n.age, n.height) |
+-----------------------------------------------------------------------------------------------------------------------------------+
| {age_10: 176, age_13: 180, age_24: 172, age_25: 179, age_32: 123, age_33: 186, age_37: 147, age_43: 162, age_49: 126, age_6: 170} |
+-----------------------------------------------------------------------------------------------------------------------------------+
```
Reviewers: mislav.bradac, teon.banek, buda
Reviewed By: mislav.bradac, buda
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D695
2017-08-23 16:43:45 +08:00
|
|
|
nullptr, Aggregation::Op::COUNT);
|
2018-09-05 00:02:30 +08:00
|
|
|
auto aggr_sym = symbol_table.CreateSymbol("aggr", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
aggr->MapTo(aggr_sym);
|
2018-06-27 17:08:21 +08:00
|
|
|
frame[aggr_sym] = TypedValue(1);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(aggr);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(value.ValueInt(), 1);
|
2017-04-12 18:58:10 +08:00
|
|
|
}
|
2017-04-24 22:01:00 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, ListLiteral) {
|
2017-04-28 18:06:18 +08:00
|
|
|
auto *list_literal = storage.Create<ListLiteral>(
|
|
|
|
std::vector<Expression *>{storage.Create<PrimitiveLiteral>(1),
|
|
|
|
storage.Create<PrimitiveLiteral>("bla"),
|
|
|
|
storage.Create<PrimitiveLiteral>(true)});
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
TypedValue result = Eval(list_literal);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(result.IsList());
|
|
|
|
auto &result_elems = result.ValueList();
|
2017-04-28 18:06:18 +08:00
|
|
|
ASSERT_EQ(3, result_elems.size());
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(result_elems[0].IsInt());
|
|
|
|
;
|
|
|
|
EXPECT_TRUE(result_elems[1].IsString());
|
|
|
|
;
|
|
|
|
EXPECT_TRUE(result_elems[2].IsBool());
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, ParameterLookup) {
|
2020-01-22 23:20:13 +08:00
|
|
|
ctx.parameters.Add(0, storage::PropertyValue(42));
|
2018-09-05 00:02:30 +08:00
|
|
|
auto *param_lookup = storage.Create<ParameterLookup>(0);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(param_lookup);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(value.IsInt());
|
|
|
|
EXPECT_EQ(value.ValueInt(), 42);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, All) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *all =
|
|
|
|
ALL("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(1))));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
all->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(all);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(value.IsBool());
|
|
|
|
EXPECT_FALSE(value.ValueBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAllNullList) {
|
|
|
|
AstStorage storage;
|
2020-01-22 23:20:13 +08:00
|
|
|
auto *all = ALL("x", LITERAL(storage::PropertyValue()), WHERE(LITERAL(true)));
|
2018-09-05 00:02:30 +08:00
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
all->identifier_->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(all);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAllWhereWrongType) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *all = ALL("x", LIST(LITERAL(1)), WHERE(LITERAL(2)));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
all->identifier_->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(all), QueryRuntimeException);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionSingle) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *single =
|
|
|
|
SINGLE("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(1))));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
single->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(single);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(value.IsBool());
|
|
|
|
EXPECT_TRUE(value.ValueBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionSingle2) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *single = SINGLE("x", LIST(LITERAL(1), LITERAL(2)),
|
|
|
|
WHERE(GREATER(ident_x, LITERAL(0))));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
single->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(single);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(value.IsBool());
|
|
|
|
EXPECT_FALSE(value.ValueBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionSingleNullList) {
|
|
|
|
AstStorage storage;
|
2020-01-22 23:20:13 +08:00
|
|
|
auto *single =
|
|
|
|
SINGLE("x", LITERAL(storage::PropertyValue()), WHERE(LITERAL(true)));
|
2018-09-05 00:02:30 +08:00
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
single->identifier_->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(single);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
|
2020-06-10 22:11:35 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAny) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *any =
|
|
|
|
ANY("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(1))));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
|
|
|
any->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
|
|
|
auto value = Eval(any);
|
|
|
|
ASSERT_TRUE(value.IsBool());
|
|
|
|
EXPECT_TRUE(value.ValueBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAny2) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *any =
|
|
|
|
ANY("x", LIST(LITERAL(1), LITERAL(2)), WHERE(EQ(ident_x, LITERAL(0))));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
|
|
|
any->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
|
|
|
auto value = Eval(any);
|
|
|
|
ASSERT_TRUE(value.IsBool());
|
|
|
|
EXPECT_FALSE(value.ValueBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAnyNullList) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *any = ANY("x", LITERAL(storage::PropertyValue()), WHERE(LITERAL(true)));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
|
|
|
any->identifier_->MapTo(x_sym);
|
|
|
|
auto value = Eval(any);
|
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionAnyWhereWrongType) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *any = ANY("x", LIST(LITERAL(1)), WHERE(LITERAL(2)));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
|
|
|
any->identifier_->MapTo(x_sym);
|
|
|
|
EXPECT_THROW(Eval(any), QueryRuntimeException);
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionReduce) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_sum = IDENT("sum");
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *reduce = REDUCE("sum", LITERAL(0), "x", LIST(LITERAL(1), LITERAL(2)),
|
|
|
|
ADD(ident_sum, ident_x));
|
|
|
|
const auto sum_sym = symbol_table.CreateSymbol("sum", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
reduce->accumulator_->MapTo(sum_sym);
|
|
|
|
ident_sum->MapTo(sum_sym);
|
2018-09-05 00:02:30 +08:00
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
reduce->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(reduce);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_TRUE(value.IsInt());
|
|
|
|
EXPECT_EQ(value.ValueInt(), 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionExtract) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
2020-01-22 23:20:13 +08:00
|
|
|
auto *extract = EXTRACT(
|
|
|
|
"x", LIST(LITERAL(1), LITERAL(2), LITERAL(storage::PropertyValue())),
|
|
|
|
ADD(ident_x, LITERAL(1)));
|
2018-09-05 00:02:30 +08:00
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
extract->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(extract);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsList());
|
|
|
|
;
|
|
|
|
auto result = value.ValueList();
|
|
|
|
EXPECT_EQ(result[0].ValueInt(), 2);
|
|
|
|
EXPECT_EQ(result[1].ValueInt(), 3);
|
|
|
|
EXPECT_TRUE(result[2].IsNull());
|
2017-04-28 18:06:18 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionExtractNull) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *extract =
|
2020-01-22 23:20:13 +08:00
|
|
|
EXTRACT("x", LITERAL(storage::PropertyValue()), ADD(ident_x, LITERAL(1)));
|
2018-09-05 00:02:30 +08:00
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
extract->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto value = Eval(extract);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(value.IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, FunctionExtractExceptions) {
|
|
|
|
AstStorage storage;
|
|
|
|
auto *ident_x = IDENT("x");
|
|
|
|
auto *extract = EXTRACT("x", LITERAL("bla"), ADD(ident_x, LITERAL(1)));
|
|
|
|
const auto x_sym = symbol_table.CreateSymbol("x", true);
|
2019-02-05 20:16:07 +08:00
|
|
|
extract->identifier_->MapTo(x_sym);
|
|
|
|
ident_x->MapTo(x_sym);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(extract), QueryRuntimeException);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
|
2018-10-25 20:51:17 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, Coalesce) {
|
|
|
|
// coalesce()
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(Eval(COALESCE()), QueryRuntimeException);
|
2018-10-25 20:51:17 +08:00
|
|
|
|
|
|
|
// coalesce(null, null)
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_TRUE(
|
2019-11-22 01:38:01 +08:00
|
|
|
Eval(COALESCE(LITERAL(TypedValue()), LITERAL(TypedValue()))).IsNull());
|
2018-10-25 20:51:17 +08:00
|
|
|
|
|
|
|
// coalesce(null, 2, 3)
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_EQ(
|
|
|
|
Eval(COALESCE(LITERAL(TypedValue()), LITERAL(2), LITERAL(3))).ValueInt(),
|
|
|
|
2);
|
2018-10-25 20:51:17 +08:00
|
|
|
|
|
|
|
// coalesce(null, 2, assert(false), 3)
|
2019-06-04 22:11:31 +08:00
|
|
|
EXPECT_EQ(Eval(COALESCE(LITERAL(TypedValue()), LITERAL(2),
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
FN("ASSERT", LITERAL(false)), LITERAL(3)))
|
2018-10-25 20:51:17 +08:00
|
|
|
.ValueInt(),
|
|
|
|
2);
|
|
|
|
|
|
|
|
// (null, assert(false))
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
EXPECT_THROW(
|
2019-06-04 22:11:31 +08:00
|
|
|
Eval(COALESCE(LITERAL(TypedValue()), FN("ASSERT", LITERAL(false)))),
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
QueryRuntimeException);
|
2018-10-25 20:51:17 +08:00
|
|
|
|
|
|
|
// coalesce([null, null])
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_FALSE(Eval(COALESCE(LITERAL(TypedValue(
|
|
|
|
std::vector<TypedValue>{TypedValue(), TypedValue()}))))
|
2018-10-25 20:51:17 +08:00
|
|
|
.IsNull());
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:12:24 +08:00
|
|
|
TEST_F(ExpressionEvaluatorTest, RegexMatchInvalidArguments) {
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_TRUE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL(TypedValue()), LITERAL("regex")))
|
|
|
|
.IsNull());
|
2019-02-27 18:12:24 +08:00
|
|
|
EXPECT_TRUE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL(3), LITERAL("regex"))).IsNull());
|
|
|
|
EXPECT_TRUE(Eval(storage.Create<RegexMatch>(LIST(LITERAL("string")),
|
|
|
|
LITERAL("regex")))
|
|
|
|
.IsNull());
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_TRUE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("string"), LITERAL(TypedValue())))
|
|
|
|
.IsNull());
|
2019-02-27 18:12:24 +08:00
|
|
|
EXPECT_THROW(Eval(storage.Create<RegexMatch>(LITERAL("string"), LITERAL(42))),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_THROW(Eval(storage.Create<RegexMatch>(LITERAL("string"),
|
|
|
|
LIST(LITERAL("regex")))),
|
|
|
|
QueryRuntimeException);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, RegexMatchInvalidRegex) {
|
|
|
|
EXPECT_THROW(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL("*ext"))),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_THROW(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL("[ext"))),
|
|
|
|
QueryRuntimeException);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorTest, RegexMatch) {
|
|
|
|
EXPECT_FALSE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL(".*ex")))
|
|
|
|
.ValueBool());
|
|
|
|
EXPECT_TRUE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL(".*ext")))
|
|
|
|
.ValueBool());
|
|
|
|
EXPECT_FALSE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL("[ext]")))
|
|
|
|
.ValueBool());
|
|
|
|
EXPECT_TRUE(
|
|
|
|
Eval(storage.Create<RegexMatch>(LITERAL("text"), LITERAL(".+[ext]")))
|
|
|
|
.ValueBool());
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
|
|
|
|
protected:
|
2020-01-22 23:20:13 +08:00
|
|
|
std::pair<std::string, storage::PropertyId> prop_age =
|
2019-11-22 01:38:01 +08:00
|
|
|
std::make_pair("age", dba.NameToProperty("age"));
|
2020-01-22 23:20:13 +08:00
|
|
|
std::pair<std::string, storage::PropertyId> prop_height =
|
2019-11-22 01:38:01 +08:00
|
|
|
std::make_pair("height", dba.NameToProperty("height"));
|
2019-02-05 20:16:07 +08:00
|
|
|
Identifier *identifier = storage.Create<Identifier>("element");
|
2018-09-05 00:02:30 +08:00
|
|
|
Symbol symbol = symbol_table.CreateSymbol("element", true);
|
|
|
|
|
2019-02-05 20:16:07 +08:00
|
|
|
void SetUp() { identifier->MapTo(symbol); }
|
2018-09-05 00:02:30 +08:00
|
|
|
|
2020-01-22 23:20:13 +08:00
|
|
|
auto Value(std::pair<std::string, storage::PropertyId> property) {
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
auto *op = storage.Create<PropertyLookup>(
|
|
|
|
identifier, storage.GetPropertyIx(property.first));
|
|
|
|
return Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2020-01-22 23:20:13 +08:00
|
|
|
ASSERT_TRUE(
|
|
|
|
v1.SetProperty(prop_age.second, storage::PropertyValue(10)).HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
dba.AdvanceCommand();
|
|
|
|
frame[symbol] = TypedValue(v1);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
|
|
|
EXPECT_TRUE(Value(prop_height).IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e12 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("edge_type"));
|
|
|
|
ASSERT_TRUE(e12.HasValue());
|
2020-01-22 23:20:13 +08:00
|
|
|
ASSERT_TRUE(
|
|
|
|
e12->SetProperty(prop_age.second, storage::PropertyValue(10)).HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
dba.AdvanceCommand();
|
|
|
|
frame[symbol] = TypedValue(*e12);
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
|
|
|
EXPECT_TRUE(Value(prop_height).IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorPropertyLookup, Null) {
|
2019-06-04 22:11:31 +08:00
|
|
|
frame[symbol] = TypedValue();
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_TRUE(Value(prop_age).IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(ExpressionEvaluatorPropertyLookup, MapLiteral) {
|
2019-06-06 19:16:37 +08:00
|
|
|
frame[symbol] = TypedValue(
|
|
|
|
std::map<std::string, TypedValue>{{prop_age.first, TypedValue(10)}});
|
2018-09-05 00:02:30 +08:00
|
|
|
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
|
|
|
EXPECT_TRUE(Value(prop_height).IsNull());
|
|
|
|
}
|
|
|
|
|
|
|
|
class FunctionTest : public ExpressionEvaluatorTest {
|
|
|
|
protected:
|
2018-10-11 21:04:49 +08:00
|
|
|
std::vector<Expression *> ExpressionsFromTypedValues(
|
|
|
|
const std::vector<TypedValue> &tvs) {
|
2018-09-05 00:02:30 +08:00
|
|
|
std::vector<Expression *> expressions;
|
2018-10-11 21:04:49 +08:00
|
|
|
expressions.reserve(tvs.size());
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tvs.size(); ++i) {
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
auto *ident =
|
|
|
|
storage.Create<Identifier>("arg_" + std::to_string(i), true);
|
|
|
|
auto sym = symbol_table.CreateSymbol("arg_" + std::to_string(i), true);
|
2019-02-05 20:16:07 +08:00
|
|
|
ident->MapTo(sym);
|
2018-10-11 21:04:49 +08:00
|
|
|
frame[sym] = tvs[i];
|
Clean-up TypedValue misuse
Summary:
In a bunch of places `TypedValue` was used where `PropertyValue` should be. A lot of times it was only because `TypedValue` serialization code could be reused for `PropertyValue`, only without providing callbacks for `VERTEX`, `EDGE` and `PATH`. So first I wrote separate serialization code for `PropertyValue` and put it into storage folder. Then I fixed all the places where `TypedValue` was incorrectly used instead of `PropertyValue`. I also disabled implicit `TypedValue` to `PropertyValue` conversion in hopes of preventing misuse in the future.
After that, I wrote code for `VertexAccessor` and `EdgeAccessor` serialization and put it into `storage` folder because it was almost duplicated in distributed BFS and pull produce RPC messages. On the sender side, some subset of records (old or new or both) is serialized, and on the reciever side, records are deserialized and immediately put into transaction cache.
Then I rewrote the `TypedValue` serialization functions (`SaveCapnpTypedValue` and `LoadCapnpTypedValue`) to not take callbacks for `VERTEX`, `EDGE` and `PATH`, but use accessor serialization functions instead. That means that any code that wants to use `TypedValue` serialization must hold a reference to `GraphDbAccessor` and `DataManager`, so that should make clients reconsider if they really want to use `TypedValue` instead of `PropertyValue`.
Reviewers: teon.banek, msantl
Reviewed By: teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1598
2018-09-13 18:12:07 +08:00
|
|
|
expressions.push_back(ident);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
2018-10-11 21:04:49 +08:00
|
|
|
|
|
|
|
return expressions;
|
|
|
|
}
|
|
|
|
|
|
|
|
TypedValue EvaluateFunctionWithExprs(
|
|
|
|
const std::string &function_name,
|
|
|
|
const std::vector<Expression *> &expressions) {
|
2018-09-05 00:02:30 +08:00
|
|
|
auto *op = storage.Create<Function>(function_name, expressions);
|
Remove GraphDbAccessor and storage types from Ast
Summary:
This diff removes the need for a database when parsing a query and
creating an Ast. Instead of storing storage::{Label,Property,EdgeType}
in Ast nodes, we store the name and an index into all of the names. This
allows for easy creation of a map from {Label,Property,EdgeType} index
into the concrete storage type. Obviously, this comes with a performance
penalty during execution, but it should be minor. The upside is that the
query/frontend minimally depends on storage (PropertyValue), which makes
writing tests easier as well as running them a lot faster (there is no
database setup). This is most noticeable in the ast_serialization test
which took a long time due to start up of a distributed database.
Reviewers: mtomic, llugovic
Reviewed By: mtomic
Subscribers: mferencevic, pullbot
Differential Revision: https://phabricator.memgraph.io/D1774
2019-01-14 21:41:37 +08:00
|
|
|
return Eval(op);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
2018-10-11 21:04:49 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
template <class... TArgs>
|
2018-10-11 21:04:49 +08:00
|
|
|
TypedValue EvaluateFunction(const std::string &function_name,
|
2019-06-05 21:50:29 +08:00
|
|
|
std::tuple<TArgs...> args) {
|
|
|
|
std::vector<TypedValue> tv_args;
|
|
|
|
tv_args.reserve(args.size());
|
|
|
|
for (auto &arg : args) tv_args.emplace_back(std::move(arg));
|
2018-10-11 21:04:49 +08:00
|
|
|
return EvaluateFunctionWithExprs(function_name,
|
2019-06-05 21:50:29 +08:00
|
|
|
ExpressionsFromTypedValues(tv_args));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... TArgs>
|
|
|
|
TypedValue EvaluateFunction(const std::string &function_name,
|
|
|
|
TArgs &&... args) {
|
|
|
|
return EvaluateFunctionWithExprs(
|
|
|
|
function_name, ExpressionsFromTypedValues(
|
|
|
|
std::vector<TypedValue>{TypedValue(args)...}));
|
2018-10-11 21:04:49 +08:00
|
|
|
}
|
2018-09-05 00:02:30 +08:00
|
|
|
};
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
template <class... TArgs>
|
|
|
|
static TypedValue MakeTypedValueList(TArgs &&... args) {
|
|
|
|
return TypedValue(std::vector<TypedValue>{TypedValue(args)...});
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, EndNode) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ENDNODE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ENDNODE", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("label1")).HasValue());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("label2")).HasValue());
|
|
|
|
auto e = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("t"));
|
|
|
|
ASSERT_TRUE(e.HasValue());
|
|
|
|
ASSERT_TRUE(*EvaluateFunction("ENDNODE", *e)
|
2019-09-11 22:10:53 +08:00
|
|
|
.ValueVertex()
|
2019-11-22 01:38:01 +08:00
|
|
|
.HasLabel(storage::View::NEW, dba.NameToLabel("label2")));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ENDNODE", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Head) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("HEAD"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("HEAD", TypedValue()).IsNull());
|
|
|
|
auto argument = MakeTypedValueList(3, 4, 5);
|
|
|
|
ASSERT_EQ(EvaluateFunction("HEAD", argument).ValueInt(), 3);
|
|
|
|
argument.ValueList().clear();
|
|
|
|
ASSERT_TRUE(EvaluateFunction("HEAD", argument).IsNull());
|
|
|
|
ASSERT_THROW(EvaluateFunction("HEAD", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Properties) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("PROPERTIES"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("PROPERTIES", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(
|
2020-01-22 23:20:13 +08:00
|
|
|
v1.SetProperty(dba.NameToProperty("height"), storage::PropertyValue(5))
|
|
|
|
.HasValue());
|
|
|
|
ASSERT_TRUE(
|
|
|
|
v1.SetProperty(dba.NameToProperty("age"), storage::PropertyValue(10))
|
|
|
|
.HasValue());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("type1"));
|
|
|
|
ASSERT_TRUE(e.HasValue());
|
|
|
|
ASSERT_TRUE(
|
2020-01-22 23:20:13 +08:00
|
|
|
e->SetProperty(dba.NameToProperty("height"), storage::PropertyValue(3))
|
|
|
|
.HasValue());
|
|
|
|
ASSERT_TRUE(
|
|
|
|
e->SetProperty(dba.NameToProperty("age"), storage::PropertyValue(15))
|
|
|
|
.HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
dba.AdvanceCommand();
|
2017-04-24 22:01:00 +08:00
|
|
|
|
|
|
|
auto prop_values_to_int = [](TypedValue t) {
|
|
|
|
std::unordered_map<std::string, int> properties;
|
2019-05-30 19:33:20 +08:00
|
|
|
for (auto property : t.ValueMap()) {
|
2019-06-03 22:54:20 +08:00
|
|
|
properties[std::string(property.first)] = property.second.ValueInt();
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
return properties;
|
|
|
|
};
|
2017-11-23 23:36:54 +08:00
|
|
|
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THAT(prop_values_to_int(EvaluateFunction("PROPERTIES", v1)),
|
2018-09-05 00:02:30 +08:00
|
|
|
UnorderedElementsAre(testing::Pair("height", 5),
|
|
|
|
testing::Pair("age", 10)));
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THAT(prop_values_to_int(EvaluateFunction("PROPERTIES", *e)),
|
2018-09-05 00:02:30 +08:00
|
|
|
UnorderedElementsAre(testing::Pair("height", 3),
|
|
|
|
testing::Pair("age", 15)));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("PROPERTIES", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Last) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("LAST"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("LAST", TypedValue()).IsNull());
|
|
|
|
auto argument = MakeTypedValueList(3, 4, 5);
|
|
|
|
ASSERT_EQ(EvaluateFunction("LAST", argument).ValueInt(), 5);
|
|
|
|
argument.ValueList().clear();
|
|
|
|
ASSERT_TRUE(EvaluateFunction("LAST", argument).IsNull());
|
|
|
|
ASSERT_THROW(EvaluateFunction("LAST", 5), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Size) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("SIZE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("SIZE", TypedValue()).IsNull());
|
|
|
|
auto argument = MakeTypedValueList(3, 4, 5);
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIZE", argument).ValueInt(), 3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIZE", "john").ValueInt(), 4);
|
|
|
|
ASSERT_EQ(
|
|
|
|
EvaluateFunction(
|
|
|
|
"SIZE", std::map<std::string, TypedValue>{{"a", TypedValue(5)},
|
|
|
|
{"b", TypedValue(true)},
|
|
|
|
{"c", TypedValue("123")}})
|
|
|
|
.ValueInt(),
|
|
|
|
3);
|
|
|
|
ASSERT_THROW(EvaluateFunction("SIZE", 5), QueryRuntimeException);
|
2017-09-18 20:40:36 +08:00
|
|
|
|
2019-11-22 01:38:01 +08:00
|
|
|
auto v0 = dba.InsertVertex();
|
2017-09-18 20:40:36 +08:00
|
|
|
query::Path path(v0);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("SIZE", path).ValueInt(), 0);
|
2019-11-22 01:38:01 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto edge = dba.InsertEdge(&v0, &v1, dba.NameToEdgeType("type"));
|
|
|
|
ASSERT_TRUE(edge.HasValue());
|
|
|
|
path.Expand(*edge);
|
2017-09-18 20:40:36 +08:00
|
|
|
path.Expand(v1);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("SIZE", path).ValueInt(), 1);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, StartNode) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("STARTNODE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("STARTNODE", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("label1")).HasValue());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("label2")).HasValue());
|
|
|
|
auto e = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("t"));
|
|
|
|
ASSERT_TRUE(e.HasValue());
|
|
|
|
ASSERT_TRUE(*EvaluateFunction("STARTNODE", *e)
|
2019-09-11 22:10:53 +08:00
|
|
|
.ValueVertex()
|
2019-11-22 01:38:01 +08:00
|
|
|
.HasLabel(storage::View::NEW, dba.NameToLabel("label1")));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("STARTNODE", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Degree) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("DEGREE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("DEGREE", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto v2 = dba.InsertVertex();
|
|
|
|
auto v3 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e12 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("t"));
|
|
|
|
ASSERT_TRUE(e12.HasValue());
|
|
|
|
ASSERT_TRUE(dba.InsertEdge(&v3, &v2, dba.NameToEdgeType("t")).HasValue());
|
|
|
|
dba.AdvanceCommand();
|
|
|
|
ASSERT_EQ(EvaluateFunction("DEGREE", v1).ValueInt(), 1);
|
|
|
|
ASSERT_EQ(EvaluateFunction("DEGREE", v2).ValueInt(), 2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("DEGREE", v3).ValueInt(), 1);
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("DEGREE", 2), QueryRuntimeException);
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("DEGREE", *e12), QueryRuntimeException);
|
2017-08-09 17:48:36 +08:00
|
|
|
}
|
|
|
|
|
2018-10-11 19:39:36 +08:00
|
|
|
TEST_F(FunctionTest, InDegree) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("INDEGREE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("INDEGREE", TypedValue()).IsNull());
|
2019-11-22 01:38:01 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto v2 = dba.InsertVertex();
|
|
|
|
auto v3 = dba.InsertVertex();
|
|
|
|
auto e12 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("t"));
|
|
|
|
ASSERT_TRUE(e12.HasValue());
|
|
|
|
ASSERT_TRUE(dba.InsertEdge(&v3, &v2, dba.NameToEdgeType("t")).HasValue());
|
|
|
|
dba.AdvanceCommand();
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_EQ(EvaluateFunction("INDEGREE", v1).ValueInt(), 0);
|
|
|
|
ASSERT_EQ(EvaluateFunction("INDEGREE", v2).ValueInt(), 2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("INDEGREE", v3).ValueInt(), 0);
|
|
|
|
ASSERT_THROW(EvaluateFunction("INDEGREE", 2), QueryRuntimeException);
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("INDEGREE", *e12), QueryRuntimeException);
|
2018-10-11 19:39:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FunctionTest, OutDegree) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("OUTDEGREE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("OUTDEGREE", TypedValue()).IsNull());
|
2019-11-22 01:38:01 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto v2 = dba.InsertVertex();
|
|
|
|
auto v3 = dba.InsertVertex();
|
|
|
|
auto e12 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("t"));
|
|
|
|
ASSERT_TRUE(e12.HasValue());
|
|
|
|
ASSERT_TRUE(dba.InsertEdge(&v3, &v2, dba.NameToEdgeType("t")).HasValue());
|
|
|
|
dba.AdvanceCommand();
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_EQ(EvaluateFunction("OUTDEGREE", v1).ValueInt(), 1);
|
|
|
|
ASSERT_EQ(EvaluateFunction("OUTDEGREE", v2).ValueInt(), 0);
|
|
|
|
ASSERT_EQ(EvaluateFunction("OUTDEGREE", v3).ValueInt(), 1);
|
|
|
|
ASSERT_THROW(EvaluateFunction("OUTDEGREE", 2), QueryRuntimeException);
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("OUTDEGREE", *e12), QueryRuntimeException);
|
2018-10-11 19:39:36 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToBoolean) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TOBOOLEAN"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOBOOLEAN", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", 123).ValueBool(), true);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", -213).ValueBool(), true);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", 0).ValueBool(), false);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", " trUE \n\t").ValueBool(), true);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", "\n\tFalsE").ValueBool(), false);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOBOOLEAN", "\n\tFALSEA ").IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", true).ValueBool(), true);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", false).ValueBool(), false);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToFloat) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TOFLOAT"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOFLOAT", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOFLOAT", " -3.5 \n\t").ValueDouble(), -3.5);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOFLOAT", "\n\t0.5e-1").ValueDouble(), 0.05);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOFLOAT", "\n\t3.4e-3X ").IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOFLOAT", -3.5).ValueDouble(), -3.5);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOFLOAT", -3).ValueDouble(), -3.0);
|
|
|
|
ASSERT_THROW(EvaluateFunction("TOFLOAT", true), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToInteger) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TOINTEGER"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOINTEGER", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", false).ValueInt(), 0);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", true).ValueInt(), 1);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", "\n\t3").ValueInt(), 3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", " -3.5 \n\t").ValueInt(), -3);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TOINTEGER", "\n\t3X ").IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", -3.5).ValueInt(), -3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("TOINTEGER", 3.5).ValueInt(), 3);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FunctionTest, Type) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TYPE"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TYPE", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("label1")).HasValue());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("label2")).HasValue());
|
|
|
|
auto e = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("type1"));
|
|
|
|
ASSERT_TRUE(e.HasValue());
|
|
|
|
ASSERT_EQ(EvaluateFunction("TYPE", *e).ValueString(), "type1");
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TYPE", 2), QueryRuntimeException);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FunctionTest, Labels) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("LABELS"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("LABELS", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(v.AddLabel(dba.NameToLabel("label1")).HasValue());
|
|
|
|
ASSERT_TRUE(v.AddLabel(dba.NameToLabel("label2")).HasValue());
|
|
|
|
dba.AdvanceCommand();
|
2017-04-24 22:01:00 +08:00
|
|
|
std::vector<std::string> labels;
|
2019-11-22 01:38:01 +08:00
|
|
|
auto _labels = EvaluateFunction("LABELS", v).ValueList();
|
2019-05-30 18:30:36 +08:00
|
|
|
labels.reserve(_labels.size());
|
2017-04-24 22:01:00 +08:00
|
|
|
for (auto label : _labels) {
|
2019-05-30 18:30:36 +08:00
|
|
|
labels.emplace_back(label.ValueString());
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
ASSERT_THAT(labels, UnorderedElementsAre("label1", "label2"));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("LABELS", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, NodesRelationships) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("NODES"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("RELATIONSHIPS"), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction("NODES", TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("RELATIONSHIPS", TypedValue()).IsNull());
|
2017-10-30 17:45:36 +08:00
|
|
|
|
|
|
|
{
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
|
|
|
auto v2 = dba.InsertVertex();
|
|
|
|
auto v3 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e1 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("Type"));
|
|
|
|
ASSERT_TRUE(e1.HasValue());
|
|
|
|
auto e2 = dba.InsertEdge(&v2, &v3, dba.NameToEdgeType("Type"));
|
|
|
|
ASSERT_TRUE(e2.HasValue());
|
|
|
|
query::Path path{v1, *e1, v2, *e2, v3};
|
|
|
|
dba.AdvanceCommand();
|
2017-10-30 17:45:36 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
auto _nodes = EvaluateFunction("NODES", path).ValueList();
|
2019-11-22 01:38:01 +08:00
|
|
|
std::vector<query::VertexAccessor> nodes;
|
2017-10-30 17:45:36 +08:00
|
|
|
for (const auto &node : _nodes) {
|
2019-11-22 01:38:01 +08:00
|
|
|
nodes.push_back(node.ValueVertex());
|
2017-10-30 17:45:36 +08:00
|
|
|
}
|
|
|
|
EXPECT_THAT(nodes, ElementsAre(v1, v2, v3));
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
auto _edges = EvaluateFunction("RELATIONSHIPS", path).ValueList();
|
2019-11-22 01:38:01 +08:00
|
|
|
std::vector<query::EdgeAccessor> edges;
|
2017-10-30 17:45:36 +08:00
|
|
|
for (const auto &edge : _edges) {
|
2019-11-22 01:38:01 +08:00
|
|
|
edges.push_back(edge.ValueEdge());
|
2017-10-30 17:45:36 +08:00
|
|
|
}
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_THAT(edges, ElementsAre(*e1, *e2));
|
2017-10-30 17:45:36 +08:00
|
|
|
}
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("NODES", 2), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("RELATIONSHIPS", 2), QueryRuntimeException);
|
2017-10-30 17:45:36 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Range) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RANGE"), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction("RANGE", 1, 2, TypedValue()).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction("RANGE", 1, TypedValue(), 1.3),
|
2017-05-10 21:17:43 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RANGE", 1, 2, 0), QueryRuntimeException);
|
2019-08-22 20:50:57 +08:00
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 1, 3)), ElementsAre(1, 2, 3));
|
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", -1, 5, 2)),
|
2017-05-10 21:17:43 +08:00
|
|
|
ElementsAre(-1, 1, 3, 5));
|
2019-08-22 20:50:57 +08:00
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 2, 10, 3)),
|
2017-05-10 21:17:43 +08:00
|
|
|
ElementsAre(2, 5, 8));
|
2019-08-22 20:50:57 +08:00
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 2, 2, 2)), ElementsAre(2));
|
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 3, 0, 5)), ElementsAre());
|
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 5, 1, -2)),
|
2017-05-10 21:17:43 +08:00
|
|
|
ElementsAre(5, 3, 1));
|
2019-08-22 20:50:57 +08:00
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 6, 1, -2)),
|
2017-05-10 21:17:43 +08:00
|
|
|
ElementsAre(6, 4, 2));
|
2019-08-22 20:50:57 +08:00
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", 2, 2, -3)), ElementsAre(2));
|
|
|
|
EXPECT_THAT(ToIntList(EvaluateFunction("RANGE", -2, 4, -1)), ElementsAre());
|
2017-05-10 21:17:43 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Keys) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("KEYS"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("KEYS", TypedValue()).IsNull());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v1 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(
|
2020-01-22 23:20:13 +08:00
|
|
|
v1.SetProperty(dba.NameToProperty("height"), storage::PropertyValue(5))
|
|
|
|
.HasValue());
|
|
|
|
ASSERT_TRUE(
|
|
|
|
v1.SetProperty(dba.NameToProperty("age"), storage::PropertyValue(10))
|
|
|
|
.HasValue());
|
2019-04-15 17:36:43 +08:00
|
|
|
auto v2 = dba.InsertVertex();
|
2019-11-22 01:38:01 +08:00
|
|
|
auto e = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("type1"));
|
|
|
|
ASSERT_TRUE(e.HasValue());
|
|
|
|
ASSERT_TRUE(
|
2020-01-22 23:20:13 +08:00
|
|
|
e->SetProperty(dba.NameToProperty("width"), storage::PropertyValue(3))
|
|
|
|
.HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_TRUE(
|
2020-01-22 23:20:13 +08:00
|
|
|
e->SetProperty(dba.NameToProperty("age"), storage::PropertyValue(15))
|
|
|
|
.HasValue());
|
2019-11-22 01:38:01 +08:00
|
|
|
dba.AdvanceCommand();
|
2017-04-24 22:01:00 +08:00
|
|
|
|
|
|
|
auto prop_keys_to_string = [](TypedValue t) {
|
|
|
|
std::vector<std::string> keys;
|
2018-09-05 00:02:30 +08:00
|
|
|
for (auto property : t.ValueList()) {
|
2019-05-30 18:30:36 +08:00
|
|
|
keys.emplace_back(property.ValueString());
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
return keys;
|
|
|
|
};
|
2019-11-22 01:38:01 +08:00
|
|
|
ASSERT_THAT(prop_keys_to_string(EvaluateFunction("KEYS", v1)),
|
|
|
|
UnorderedElementsAre("height", "age"));
|
|
|
|
ASSERT_THAT(prop_keys_to_string(EvaluateFunction("KEYS", *e)),
|
|
|
|
UnorderedElementsAre("width", "age"));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("KEYS", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Tail) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TAIL"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("TAIL", TypedValue()).IsNull());
|
|
|
|
auto argument = MakeTypedValueList();
|
|
|
|
ASSERT_EQ(EvaluateFunction("TAIL", argument).ValueList().size(), 0U);
|
|
|
|
argument = MakeTypedValueList(3, 4, true, "john");
|
|
|
|
auto list = EvaluateFunction("TAIL", argument).ValueList();
|
2017-04-24 22:01:00 +08:00
|
|
|
ASSERT_EQ(list.size(), 3U);
|
2018-09-05 00:02:30 +08:00
|
|
|
ASSERT_EQ(list[0].ValueInt(), 4);
|
|
|
|
ASSERT_EQ(list[1].ValueBool(), true);
|
|
|
|
ASSERT_EQ(list[2].ValueString(), "john");
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("TAIL", 2), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2019-01-07 22:43:29 +08:00
|
|
|
TEST_F(FunctionTest, UniformSample) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("UNIFORMSAMPLE"), QueryRuntimeException);
|
2019-01-07 22:43:29 +08:00
|
|
|
ASSERT_TRUE(
|
2019-06-05 21:50:29 +08:00
|
|
|
EvaluateFunction("UNIFORMSAMPLE", TypedValue(), TypedValue()).IsNull());
|
|
|
|
ASSERT_TRUE(EvaluateFunction("UNIFORMSAMPLE", TypedValue(), 1).IsNull());
|
2019-08-12 22:00:04 +08:00
|
|
|
ASSERT_TRUE(
|
|
|
|
EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(), TypedValue())
|
|
|
|
.IsNull());
|
2019-01-07 22:43:29 +08:00
|
|
|
ASSERT_TRUE(
|
2019-06-05 21:50:29 +08:00
|
|
|
EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(), 1).IsNull());
|
2019-01-07 22:43:29 +08:00
|
|
|
ASSERT_THROW(
|
2019-06-05 21:50:29 +08:00
|
|
|
EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(1, 2, 3), -1),
|
2019-01-07 22:43:29 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_EQ(EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(1, 2, 3), 0)
|
|
|
|
.ValueList()
|
|
|
|
.size(),
|
|
|
|
0);
|
|
|
|
ASSERT_EQ(EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(1, 2, 3), 2)
|
|
|
|
.ValueList()
|
|
|
|
.size(),
|
|
|
|
2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(1, 2, 3), 3)
|
|
|
|
.ValueList()
|
|
|
|
.size(),
|
|
|
|
3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("UNIFORMSAMPLE", MakeTypedValueList(1, 2, 3), 5)
|
|
|
|
.ValueList()
|
|
|
|
.size(),
|
|
|
|
5);
|
2019-01-07 22:43:29 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Abs) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ABS"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ABS", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("ABS", -2).ValueInt(), 2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ABS", -2.5).ValueDouble(), 2.5);
|
|
|
|
ASSERT_THROW(EvaluateFunction("ABS", true), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2017-04-26 22:29:57 +08:00
|
|
|
// Test if log works. If it does then all functions wrapped with
|
|
|
|
// WRAP_CMATH_FLOAT_FUNCTION macro should work and are not gonna be tested for
|
|
|
|
// correctnes..
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Log) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("LOG"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("LOG", TypedValue()).IsNull());
|
|
|
|
ASSERT_DOUBLE_EQ(EvaluateFunction("LOG", 2).ValueDouble(), log(2));
|
|
|
|
ASSERT_DOUBLE_EQ(EvaluateFunction("LOG", 1.5).ValueDouble(), log(1.5));
|
2017-04-26 22:29:57 +08:00
|
|
|
// Not portable, but should work on most platforms.
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_TRUE(std::isnan(EvaluateFunction("LOG", -1.5).ValueDouble()));
|
|
|
|
ASSERT_THROW(EvaluateFunction("LOG", true), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
// Function Round wraps round from cmath and will work if FunctionTest.Log test
|
2017-04-26 22:29:57 +08:00
|
|
|
// passes. This test is used to show behavior of round since it differs from
|
|
|
|
// neo4j's round.
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Round) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ROUND"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ROUND", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", -2).ValueDouble(), -2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", -2.4).ValueDouble(), -2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", -2.5).ValueDouble(), -3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", -2.6).ValueDouble(), -3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", 2.4).ValueDouble(), 2);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", 2.5).ValueDouble(), 3);
|
|
|
|
ASSERT_EQ(EvaluateFunction("ROUND", 2.6).ValueDouble(), 3);
|
|
|
|
ASSERT_THROW(EvaluateFunction("ROUND", true), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
|
|
|
|
2017-04-26 22:29:57 +08:00
|
|
|
// Check if wrapped functions are callable (check if everything was spelled
|
2018-09-05 00:02:30 +08:00
|
|
|
// correctly...). Wrapper correctnes is checked in FunctionTest.Log function
|
|
|
|
// test.
|
|
|
|
TEST_F(FunctionTest, WrappedMathFunctions) {
|
2017-04-26 22:29:57 +08:00
|
|
|
for (auto function_name :
|
|
|
|
{"FLOOR", "CEIL", "ROUND", "EXP", "LOG", "LOG10", "SQRT", "ACOS", "ASIN",
|
|
|
|
"ATAN", "COS", "SIN", "TAN"}) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EvaluateFunction(function_name, 0.5);
|
2017-04-26 22:29:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Atan2) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ATAN2"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ATAN2", TypedValue(), 1).IsNull());
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ATAN2", 1, TypedValue()).IsNull());
|
|
|
|
ASSERT_DOUBLE_EQ(EvaluateFunction("ATAN2", 2, -1.0).ValueDouble(),
|
2017-04-26 22:29:57 +08:00
|
|
|
atan2(2, -1));
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ATAN2", 3.0, true), QueryRuntimeException);
|
2017-04-26 22:29:57 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Sign) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("SIGN"), QueryRuntimeException);
|
|
|
|
ASSERT_TRUE(EvaluateFunction("SIGN", TypedValue()).IsNull());
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIGN", -2).ValueInt(), -1);
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIGN", -0.2).ValueInt(), -1);
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIGN", 0.0).ValueInt(), 0);
|
|
|
|
ASSERT_EQ(EvaluateFunction("SIGN", 2.5).ValueInt(), 1);
|
|
|
|
ASSERT_THROW(EvaluateFunction("SIGN", true), QueryRuntimeException);
|
2017-04-24 22:01:00 +08:00
|
|
|
}
|
2017-04-26 22:29:57 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, E) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("E", 1), QueryRuntimeException);
|
|
|
|
ASSERT_DOUBLE_EQ(EvaluateFunction("E").ValueDouble(), M_E);
|
2017-04-26 22:29:57 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Pi) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("PI", 1), QueryRuntimeException);
|
|
|
|
ASSERT_DOUBLE_EQ(EvaluateFunction("PI").ValueDouble(), M_PI);
|
2017-04-26 22:29:57 +08:00
|
|
|
}
|
2017-05-20 01:25:54 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Rand) {
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("RAND", 1), QueryRuntimeException);
|
|
|
|
ASSERT_GE(EvaluateFunction("RAND").ValueDouble(), 0.0);
|
|
|
|
ASSERT_LT(EvaluateFunction("RAND").ValueDouble(), 1.0);
|
2017-08-22 21:18:29 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, StartsWith) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction(kStartsWith), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kStartsWith, "a", TypedValue()).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction(kStartsWith, TypedValue(), 1.3),
|
2017-05-20 01:25:54 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction(kStartsWith, "abc", "abc").ValueBool());
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kStartsWith, "abcdef", "abc").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kStartsWith, "abcdef", "aBc").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kStartsWith, "abc", "abcd").ValueBool());
|
2017-05-20 01:25:54 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, EndsWith) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction(kEndsWith), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kEndsWith, "a", TypedValue()).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction(kEndsWith, TypedValue(), 1.3),
|
2017-05-20 01:25:54 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction(kEndsWith, "abc", "abc").ValueBool());
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kEndsWith, "abcdef", "def").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kEndsWith, "abcdef", "dEf").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kEndsWith, "bcd", "abcd").ValueBool());
|
2017-05-20 01:25:54 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Contains) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction(kContains), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kContains, "a", TypedValue()).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction(kContains, TypedValue(), 1.3),
|
2017-05-20 01:25:54 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction(kContains, "abc", "abc").ValueBool());
|
|
|
|
EXPECT_TRUE(EvaluateFunction(kContains, "abcde", "bcd").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kContains, "cde", "abcdef").ValueBool());
|
|
|
|
EXPECT_FALSE(EvaluateFunction(kContains, "abcdef", "dEf").ValueBool());
|
2017-07-25 19:01:08 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Assert) {
|
2017-09-05 17:26:46 +08:00
|
|
|
// Invalid calls.
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT"), QueryRuntimeException);
|
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT", false, false), QueryRuntimeException);
|
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT", "string", false),
|
2017-09-13 23:09:04 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT", false, "reason", true),
|
2017-09-13 23:09:04 +08:00
|
|
|
QueryRuntimeException);
|
2017-09-05 17:26:46 +08:00
|
|
|
|
|
|
|
// Valid calls, assertion fails.
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT", false), QueryRuntimeException);
|
|
|
|
ASSERT_THROW(EvaluateFunction("ASSERT", false, "message"),
|
2017-09-13 23:09:04 +08:00
|
|
|
QueryRuntimeException);
|
2017-09-05 17:26:46 +08:00
|
|
|
try {
|
2019-06-05 21:50:29 +08:00
|
|
|
EvaluateFunction("ASSERT", false, "bbgba");
|
2017-09-05 17:26:46 +08:00
|
|
|
} catch (QueryRuntimeException &e) {
|
2018-08-29 17:05:34 +08:00
|
|
|
ASSERT_TRUE(std::string(e.what()).find("bbgba") != std::string::npos);
|
2017-09-05 17:26:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Valid calls, assertion passes.
|
2019-06-05 21:50:29 +08:00
|
|
|
ASSERT_TRUE(EvaluateFunction("ASSERT", true).ValueBool());
|
|
|
|
ASSERT_TRUE(EvaluateFunction("ASSERT", true, "message").ValueBool());
|
2017-09-05 17:26:46 +08:00
|
|
|
}
|
2017-09-13 16:27:12 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Counter) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("COUNTER"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("COUNTER", "a"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("COUNTER", "a", "b"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("COUNTER", "a", "b", "c"),
|
|
|
|
QueryRuntimeException);
|
2017-09-13 23:09:04 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c1", 0).ValueInt(), 0);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c1", 0).ValueInt(), 1);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c2", 0).ValueInt(), 0);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c1", 0).ValueInt(), 2);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c2", 0).ValueInt(), 1);
|
2019-05-14 23:23:52 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c3", -1).ValueInt(), -1);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c3", -1).ValueInt(), 0);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c3", -1).ValueInt(), 1);
|
2019-05-14 23:23:52 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c4", 0, 5).ValueInt(), 0);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c4", 0, 5).ValueInt(), 5);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c4", 0, 5).ValueInt(), 10);
|
2019-05-14 23:23:52 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c5", 0, -5).ValueInt(), 0);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c5", 0, -5).ValueInt(), -5);
|
|
|
|
EXPECT_EQ(EvaluateFunction("COUNTER", "c5", 0, -5).ValueInt(), -10);
|
2019-07-16 16:35:23 +08:00
|
|
|
|
|
|
|
EXPECT_THROW(EvaluateFunction("COUNTER", "c6", 0, 0), QueryRuntimeException);
|
2018-09-05 00:02:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FunctionTest, Id) {
|
2019-11-22 01:38:01 +08:00
|
|
|
auto va = dba.InsertVertex();
|
|
|
|
auto ea = dba.InsertEdge(&va, &va, dba.NameToEdgeType("edge"));
|
|
|
|
ASSERT_TRUE(ea.HasValue());
|
|
|
|
auto vb = dba.InsertVertex();
|
|
|
|
dba.AdvanceCommand();
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("ID", va).ValueInt(), 0);
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("ID", *ea).ValueInt(), 0);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("ID", vb).ValueInt(), 1);
|
|
|
|
EXPECT_THROW(EvaluateFunction("ID"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("ID", 0), QueryRuntimeException);
|
2019-11-22 01:38:01 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("ID", va, *ea), QueryRuntimeException);
|
2018-06-12 16:59:11 +08:00
|
|
|
}
|
2018-06-15 16:40:51 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringNull) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("TOSTRING", TypedValue()).IsNull());
|
2018-06-15 16:40:51 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringString) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", "").ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", "this is a string").ValueString(),
|
2018-06-27 17:08:21 +08:00
|
|
|
"this is a string");
|
2018-06-15 16:40:51 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringInteger) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", -23321312).ValueString(), "-23321312");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", 0).ValueString(), "0");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", 42).ValueString(), "42");
|
2018-06-15 16:40:51 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringDouble) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", -42.42).ValueString(), "-42.420000");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", 0.0).ValueString(), "0.000000");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", 238910.2313217).ValueString(),
|
2018-06-15 16:40:51 +08:00
|
|
|
"238910.231322");
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringBool) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", true).ValueString(), "true");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOSTRING", false).ValueString(), "false");
|
2018-06-15 16:40:51 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToStringExceptions) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("TOSTRING", 1, 2, 3), QueryRuntimeException);
|
2018-06-27 17:08:21 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Timestamp) {
|
|
|
|
ctx.timestamp = 42;
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("TIMESTAMP").ValueInt(), 42);
|
2018-06-27 17:08:21 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, TimestampExceptions) {
|
|
|
|
ctx.timestamp = 42;
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("TIMESTAMP", 1).ValueInt(),
|
2018-06-27 17:08:21 +08:00
|
|
|
QueryRuntimeException);
|
2018-06-15 16:40:51 +08:00
|
|
|
}
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Left) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("LEFT"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("LEFT", TypedValue(), TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("LEFT", TypedValue(), 10).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction("LEFT", TypedValue(), -10),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("LEFT", "memgraph", 0).ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("LEFT", "memgraph", 3).ValueString(), "mem");
|
|
|
|
EXPECT_EQ(EvaluateFunction("LEFT", "memgraph", 1000).ValueString(),
|
2018-06-29 20:58:10 +08:00
|
|
|
"memgraph");
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("LEFT", "memgraph", -10),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("LEFT", "memgraph", "graph"),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("LEFT", 132, 10), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Right) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RIGHT"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("RIGHT", TypedValue(), TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("RIGHT", TypedValue(), 10).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction("RIGHT", TypedValue(), -10),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("RIGHT", "memgraph", 0).ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("RIGHT", "memgraph", 3).ValueString(), "aph");
|
|
|
|
EXPECT_EQ(EvaluateFunction("RIGHT", "memgraph", 1000).ValueString(),
|
2018-06-29 20:58:10 +08:00
|
|
|
"memgraph");
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RIGHT", "memgraph", -10),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RIGHT", "memgraph", "graph"),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("RIGHT", 132, 10), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Trimming) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("LTRIM", TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("RTRIM", TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("TRIM", TypedValue()).IsNull());
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("LTRIM", " abc ").ValueString(), "abc ");
|
|
|
|
EXPECT_EQ(EvaluateFunction("RTRIM", " abc ").ValueString(), " abc");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TRIM", "abc").ValueString(), "abc");
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("LTRIM", "x", "y"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("RTRIM", "x", "y"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TRIM", "x", "y"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Reverse) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("REVERSE", TypedValue()).IsNull());
|
|
|
|
EXPECT_EQ(EvaluateFunction("REVERSE", "abc").ValueString(), "cba");
|
|
|
|
EXPECT_THROW(EvaluateFunction("REVERSE", "x", "y"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Replace) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("REPLACE"), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction("REPLACE", TypedValue(), "l", "w").IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("REPLACE", "hello", TypedValue(), "w").IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("REPLACE", "hello", "l", TypedValue()).IsNull());
|
|
|
|
EXPECT_EQ(EvaluateFunction("REPLACE", "hello", "l", "w").ValueString(),
|
2018-06-29 20:58:10 +08:00
|
|
|
"hewwo");
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("REPLACE", 1, "l", "w"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("REPLACE", "hello", 1, "w"),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("REPLACE", "hello", "l", 1),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Split) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("SPLIT"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("SPLIT", "one,two", 1), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("SPLIT", 1, "one,two"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("SPLIT", TypedValue(), TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("SPLIT", "one,two", TypedValue()).IsNull());
|
|
|
|
EXPECT_TRUE(EvaluateFunction("SPLIT", TypedValue(), ",").IsNull());
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
auto result = EvaluateFunction("SPLIT", "one,two", ",");
|
2018-06-29 20:58:10 +08:00
|
|
|
EXPECT_TRUE(result.IsList());
|
|
|
|
EXPECT_EQ(result.ValueList()[0].ValueString(), "one");
|
|
|
|
EXPECT_EQ(result.ValueList()[1].ValueString(), "two");
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, Substring) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("SUBSTRING"), QueryRuntimeException);
|
2018-06-29 20:58:10 +08:00
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_TRUE(EvaluateFunction("SUBSTRING", TypedValue(), 0, 10).IsNull());
|
|
|
|
EXPECT_THROW(EvaluateFunction("SUBSTRING", TypedValue(), TypedValue()),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("SUBSTRING", TypedValue(), -10),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("SUBSTRING", TypedValue(), 0, TypedValue()),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("SUBSTRING", TypedValue(), 0, -10),
|
2018-06-29 20:58:10 +08:00
|
|
|
QueryRuntimeException);
|
|
|
|
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 2).ValueString(), "llo");
|
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 10).ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 2, 0).ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 1, 3).ValueString(), "ell");
|
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 1, 4).ValueString(), "ello");
|
|
|
|
EXPECT_EQ(EvaluateFunction("SUBSTRING", "hello", 1, 10).ValueString(),
|
2018-06-29 20:58:10 +08:00
|
|
|
"ello");
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToLower) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("TOLOWER"), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction("TOLOWER", TypedValue()).IsNull());
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOLOWER", "Ab__C").ValueString(), "ab__c");
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2018-09-05 00:02:30 +08:00
|
|
|
TEST_F(FunctionTest, ToUpper) {
|
2019-06-05 21:50:29 +08:00
|
|
|
EXPECT_THROW(EvaluateFunction("TOUPPER"), QueryRuntimeException);
|
|
|
|
EXPECT_TRUE(EvaluateFunction("TOUPPER", TypedValue()).IsNull());
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOUPPER", "Ab__C").ValueString(), "AB__C");
|
2018-06-29 20:58:10 +08:00
|
|
|
}
|
|
|
|
|
2019-11-25 23:31:39 +08:00
|
|
|
TEST_F(FunctionTest, ToByteString) {
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", 42), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", TypedValue()),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", "", 42), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", "ff"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", "00"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("TOBYTESTRING", "0xG"), QueryRuntimeException);
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "").ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "0x").ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "0X").ValueString(), "");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "0x0123456789aAbBcCdDeEfF")
|
|
|
|
.ValueString(),
|
|
|
|
"\x01\x23\x45\x67\x89\xAA\xBB\xCC\xDD\xEE\xFF");
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "0x042").ValueString().size(), 2);
|
|
|
|
EXPECT_EQ(EvaluateFunction("TOBYTESTRING", "0x042").ValueString(),
|
|
|
|
utils::pmr::string("\x00\x42", 2, utils::NewDeleteResource()));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(FunctionTest, FromByteString) {
|
|
|
|
EXPECT_THROW(EvaluateFunction("FROMBYTESTRING"), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("FROMBYTESTRING", 42), QueryRuntimeException);
|
|
|
|
EXPECT_THROW(EvaluateFunction("FROMBYTESTRING", TypedValue()),
|
|
|
|
QueryRuntimeException);
|
|
|
|
EXPECT_EQ(EvaluateFunction("FROMBYTESTRING", "").ValueString(), "");
|
|
|
|
auto bytestring = EvaluateFunction("TOBYTESTRING", "0x123456789aAbBcCdDeEfF");
|
|
|
|
EXPECT_EQ(EvaluateFunction("FROMBYTESTRING", bytestring).ValueString(),
|
|
|
|
"0x0123456789aabbccddeeff");
|
|
|
|
EXPECT_EQ(EvaluateFunction("FROMBYTESTRING", std::string("\x00\x42", 2))
|
|
|
|
.ValueString(),
|
|
|
|
"0x0042");
|
|
|
|
}
|
|
|
|
|
2017-09-13 16:27:12 +08:00
|
|
|
} // namespace
|