Fix clang-tidy warnings, remove commented out code and add HasLabel
functions in ShardRequestManager to avoid throwing bad optional on expression evaluator
This commit is contained in:
parent
213583f916
commit
9e81fe791c
@ -417,7 +417,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
|
||||
TReturnType HasLabelImpl(const VertexAccessor &vertex, const LabelIx &label_ix, QueryEngineTag /*tag*/) {
|
||||
auto label = typename VertexAccessor::Label{LabelId::FromUint(label_ix.ix)};
|
||||
auto has_label = vertex.HasLabel(label);
|
||||
return !has_label;
|
||||
return has_label;
|
||||
}
|
||||
|
||||
TypedValue Visit(LabelsTest &labels_test) override {
|
||||
|
@ -61,12 +61,10 @@ template <typename TypedValueT, typename FunctionContextT, typename Tag, typenam
|
||||
std::function<TypedValueT(const TypedValueT *arguments, int64_t num_arguments, const FunctionContextT &context)>
|
||||
NameToFunction(const std::string &function_name);
|
||||
|
||||
namespace {
|
||||
const char kStartsWith[] = "STARTSWITH";
|
||||
const char kEndsWith[] = "ENDSWITH";
|
||||
const char kContains[] = "CONTAINS";
|
||||
const char kId[] = "ID";
|
||||
} // namespace
|
||||
inline const char kStartsWith[] = "STARTSWITH";
|
||||
inline const char kEndsWith[] = "ENDSWITH";
|
||||
inline const char kContains[] = "CONTAINS";
|
||||
inline const char kId[] = "ID";
|
||||
|
||||
} // namespace memgraph::functions
|
||||
|
||||
@ -484,11 +482,11 @@ TypedValueT Properties(const TypedValueT *args, int64_t nargs, const FunctionCon
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsVertex()) {
|
||||
return get_properties(value.ValueVertex());
|
||||
} else {
|
||||
return get_properties(value.ValueEdge());
|
||||
}
|
||||
if (value.IsVertex()) {
|
||||
return get_properties(value.ValueVertex());
|
||||
}
|
||||
return get_properties(value.ValueEdge());
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
@ -497,17 +495,19 @@ TypedValueT Size(const TypedValueT *args, int64_t nargs, const FunctionContextT
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsList()) {
|
||||
}
|
||||
if (value.IsList()) {
|
||||
return TypedValueT(static_cast<int64_t>(value.ValueList().size()), ctx.memory);
|
||||
} else if (value.IsString()) {
|
||||
}
|
||||
if (value.IsString()) {
|
||||
return TypedValueT(static_cast<int64_t>(value.ValueString().size()), ctx.memory);
|
||||
} else if (value.IsMap()) {
|
||||
}
|
||||
if (value.IsMap()) {
|
||||
// neo4j doesn't implement size for map, but I don't see a good reason not
|
||||
// to do it.
|
||||
return TypedValueT(static_cast<int64_t>(value.ValueMap().size()), ctx.memory);
|
||||
} else {
|
||||
return TypedValueT(static_cast<int64_t>(value.ValuePath().edges().size()), ctx.memory);
|
||||
}
|
||||
return TypedValueT(static_cast<int64_t>(value.ValuePath().edges().size()), ctx.memory);
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT, typename Tag, typename Conv>
|
||||
@ -527,9 +527,9 @@ TypedValueT StartNode(const TypedValueT *args, int64_t nargs, const FunctionCont
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
size_t UnwrapDegreeResult(storage::v3::Result<size_t> maybe_degree) {
|
||||
// This is needed because clang-tidy fails to identify the use of this function in the if-constexpr branch
|
||||
// NOLINTNEXTLINE(clang-diagnostic-unused-function)
|
||||
inline size_t UnwrapDegreeResult(storage::v3::Result<size_t> maybe_degree) {
|
||||
if (maybe_degree.HasError()) {
|
||||
switch (maybe_degree.GetError()) {
|
||||
case storage::v3::Error::DELETED_OBJECT:
|
||||
@ -546,8 +546,6 @@ size_t UnwrapDegreeResult(storage::v3::Result<size_t> maybe_degree) {
|
||||
return *maybe_degree;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT, typename Tag>
|
||||
TypedValueT Degree(const TypedValueT *args, int64_t nargs, const FunctionContextT &ctx) {
|
||||
FType<TypedValueT, Or<Null, Vertex>>("degree", args, nargs);
|
||||
@ -599,18 +597,19 @@ TypedValueT ToBoolean(const TypedValueT *args, int64_t nargs, const FunctionCont
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsBool()) {
|
||||
return TypedValueT(value.ValueBool(), ctx.memory);
|
||||
} else if (value.IsInt()) {
|
||||
return TypedValueT(value.ValueInt() != 0L, ctx.memory);
|
||||
} else {
|
||||
auto s = utils::ToUpperCase(utils::Trim(value.ValueString()));
|
||||
if (s == "TRUE") return TypedValueT(true, ctx.memory);
|
||||
if (s == "FALSE") return TypedValueT(false, ctx.memory);
|
||||
// I think this is just stupid and that exception should be thrown, but
|
||||
// neo4j does it this way...
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
if (value.IsBool()) {
|
||||
return TypedValueT(value.ValueBool(), ctx.memory);
|
||||
}
|
||||
if (value.IsInt()) {
|
||||
return TypedValueT(value.ValueInt() != 0L, ctx.memory);
|
||||
}
|
||||
auto s = utils::ToUpperCase(utils::Trim(value.ValueString()));
|
||||
if (s == "TRUE") return TypedValueT(true, ctx.memory);
|
||||
if (s == "FALSE") return TypedValueT(false, ctx.memory);
|
||||
// I think this is just stupid and that exception should be thrown, but
|
||||
// neo4j does it this way...
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
@ -619,16 +618,17 @@ TypedValueT ToFloat(const TypedValueT *args, int64_t nargs, const FunctionContex
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsInt()) {
|
||||
}
|
||||
if (value.IsInt()) {
|
||||
return TypedValueT(static_cast<double>(value.ValueInt()), ctx.memory);
|
||||
} else if (value.IsDouble()) {
|
||||
}
|
||||
if (value.IsDouble()) {
|
||||
return TypedValueT(value, ctx.memory);
|
||||
} else {
|
||||
try {
|
||||
return TypedValueT(utils::ParseDouble(utils::Trim(value.ValueString())), ctx.memory);
|
||||
} catch (const utils::BasicException &) {
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return TypedValueT(utils::ParseDouble(utils::Trim(value.ValueString())), ctx.memory);
|
||||
} catch (const utils::BasicException &) {
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,20 +638,22 @@ TypedValueT ToInteger(const TypedValueT *args, int64_t nargs, const FunctionCont
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsBool()) {
|
||||
}
|
||||
if (value.IsBool()) {
|
||||
return TypedValueT(value.ValueBool() ? 1L : 0L, ctx.memory);
|
||||
} else if (value.IsInt()) {
|
||||
}
|
||||
if (value.IsInt()) {
|
||||
return TypedValueT(value, ctx.memory);
|
||||
} else if (value.IsDouble()) {
|
||||
}
|
||||
if (value.IsDouble()) {
|
||||
return TypedValueT(static_cast<int64_t>(value.ValueDouble()), ctx.memory);
|
||||
} else {
|
||||
try {
|
||||
// Yup, this is correct. String is valid if it has floating point
|
||||
// number, then it is parsed and converted to int.
|
||||
return TypedValueT(static_cast<int64_t>(utils::ParseDouble(utils::Trim(value.ValueString()))), ctx.memory);
|
||||
} catch (const utils::BasicException &) {
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Yup, this is correct. String is valid if it has floating point
|
||||
// number, then it is parsed and converted to int.
|
||||
return TypedValueT(static_cast<int64_t>(utils::ParseDouble(utils::Trim(value.ValueString()))), ctx.memory);
|
||||
} catch (const utils::BasicException &) {
|
||||
return TypedValueT(ctx.memory);
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,11 +738,11 @@ TypedValueT Keys(const TypedValueT *args, int64_t nargs, const FunctionContextT
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsVertex()) {
|
||||
return get_keys(value.ValueVertex());
|
||||
} else {
|
||||
return get_keys(value.ValueEdge());
|
||||
}
|
||||
if (value.IsVertex()) {
|
||||
return get_keys(value.ValueVertex());
|
||||
}
|
||||
return get_keys(value.ValueEdge());
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT, typename Tag>
|
||||
@ -853,13 +855,14 @@ TypedValueT Abs(const TypedValueT *args, int64_t nargs, const FunctionContextT &
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsInt()) {
|
||||
return TypedValueT(std::abs(value.ValueInt()), ctx.memory);
|
||||
} else {
|
||||
return TypedValueT(std::abs(value.ValueDouble()), ctx.memory);
|
||||
}
|
||||
if (value.IsInt()) {
|
||||
return TypedValueT(std::abs(value.ValueInt()), ctx.memory);
|
||||
}
|
||||
return TypedValueT(std::abs(value.ValueDouble()), ctx.memory);
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define WRAP_CMATH_FLOAT_FUNCTION(name, lowercased_name) \
|
||||
template <typename TypedValueT, typename FunctionContextT> \
|
||||
TypedValueT name(const TypedValueT *args, int64_t nargs, const FunctionContextT &ctx) { \
|
||||
@ -867,11 +870,11 @@ TypedValueT Abs(const TypedValueT *args, int64_t nargs, const FunctionContextT &
|
||||
const auto &value = args[0]; \
|
||||
if (value.IsNull()) { \
|
||||
return TypedValueT(ctx.memory); \
|
||||
} else if (value.IsInt()) { \
|
||||
return TypedValueT(lowercased_name(value.ValueInt()), ctx.memory); \
|
||||
} else { \
|
||||
return TypedValueT(lowercased_name(value.ValueDouble()), ctx.memory); \
|
||||
} \
|
||||
if (value.IsInt()) { \
|
||||
return TypedValueT(lowercased_name(value.ValueInt()), ctx.memory); \
|
||||
} \
|
||||
return TypedValueT(lowercased_name(value.ValueDouble()), ctx.memory); \
|
||||
}
|
||||
|
||||
WRAP_CMATH_FLOAT_FUNCTION(Ceil, ceil)
|
||||
@ -899,9 +902,8 @@ TypedValueT Atan2(const TypedValueT *args, int64_t nargs, const FunctionContextT
|
||||
auto to_double = [](const TypedValueT &t) -> double {
|
||||
if (t.IsInt()) {
|
||||
return t.ValueInt();
|
||||
} else {
|
||||
return t.ValueDouble();
|
||||
}
|
||||
return t.ValueDouble();
|
||||
};
|
||||
double y = to_double(args[0]);
|
||||
double x = to_double(args[1]);
|
||||
@ -915,11 +917,11 @@ TypedValueT Sign(const TypedValueT *args, int64_t nargs, const FunctionContextT
|
||||
const auto &value = args[0];
|
||||
if (value.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (value.IsInt()) {
|
||||
return sign(value.ValueInt());
|
||||
} else {
|
||||
return sign(value.ValueDouble());
|
||||
}
|
||||
if (value.IsInt()) {
|
||||
return sign(value.ValueInt());
|
||||
}
|
||||
return sign(value.ValueDouble());
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
@ -962,7 +964,7 @@ struct StartsWithPredicate {
|
||||
};
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
inline auto StartsWith = StringMatchOperator<StartsWithPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
inline const auto StartsWith = StringMatchOperator<StartsWithPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
|
||||
// Check if s1 ends with s2.
|
||||
template <typename TypedValueT>
|
||||
@ -975,7 +977,7 @@ struct EndsWithPredicate {
|
||||
};
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
inline auto EndsWith = StringMatchOperator<EndsWithPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
inline const auto EndsWith = StringMatchOperator<EndsWithPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
|
||||
// Check if s1 contains s2.
|
||||
template <typename TypedValueT>
|
||||
@ -988,7 +990,7 @@ struct ContainsPredicate {
|
||||
};
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
inline auto Contains = StringMatchOperator<ContainsPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
inline const auto Contains = StringMatchOperator<ContainsPredicate<TypedValueT>, TypedValueT, FunctionContextT>;
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
TypedValueT Assert(const TypedValueT *args, int64_t nargs, const FunctionContextT &ctx) {
|
||||
@ -1026,11 +1028,11 @@ TypedValueT Id(const TypedValueT *args, int64_t nargs, const FunctionContextT &c
|
||||
const auto &arg = args[0];
|
||||
if (arg.IsNull()) {
|
||||
return TypedValueT(ctx.memory);
|
||||
} else if (arg.IsVertex()) {
|
||||
return TypedValueT(static_cast<int64_t>(arg.ValueVertex().CypherId()), ctx.memory);
|
||||
} else {
|
||||
return TypedValueT(static_cast<int64_t>(arg.ValueEdge().CypherId()), ctx.memory);
|
||||
}
|
||||
if (arg.IsVertex()) {
|
||||
return TypedValueT(static_cast<int64_t>(arg.ValueVertex().CypherId()), ctx.memory);
|
||||
}
|
||||
return TypedValueT(static_cast<int64_t>(arg.ValueEdge().CypherId()), ctx.memory);
|
||||
}
|
||||
|
||||
template <typename TypedValueT, typename FunctionContextT>
|
||||
|
@ -23,11 +23,11 @@ EdgeTypeId EdgeAccessor::EdgeType() const { return edge.type.id; }
|
||||
const std::vector<std::pair<PropertyId, Value>> &EdgeAccessor::Properties() const { return edge.properties; }
|
||||
|
||||
Value EdgeAccessor::GetProperty(const std::string &prop_name) const {
|
||||
auto prop_id = manager_->NameToProperty(prop_name);
|
||||
auto it = std::find_if(edge.properties.begin(), edge.properties.end(), [&](auto &pr) { return prop_id == pr.first; });
|
||||
if (it == edge.properties.end()) {
|
||||
if (!manager_->HasProperty(prop_name)) {
|
||||
return {};
|
||||
}
|
||||
auto prop_id = manager_->NameToProperty(prop_name);
|
||||
auto it = std::find_if(edge.properties.begin(), edge.properties.end(), [&](auto &pr) { return prop_id == pr.first; });
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@ -88,6 +88,9 @@ Value VertexAccessor::GetProperty(PropertyId prop_id) const {
|
||||
|
||||
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
||||
Value VertexAccessor::GetProperty(const std::string &prop_name) const {
|
||||
if (!manager_->HasProperty(prop_name)) {
|
||||
return {};
|
||||
}
|
||||
return GetProperty(manager_->NameToProperty(prop_name));
|
||||
}
|
||||
|
||||
|
@ -129,6 +129,9 @@ class ShardRequestManagerInterface {
|
||||
virtual const std::string &PropertyToName(memgraph::storage::v3::PropertyId prop) const = 0;
|
||||
virtual const std::string &LabelToName(memgraph::storage::v3::LabelId label) const = 0;
|
||||
virtual const std::string &EdgeTypeToName(memgraph::storage::v3::EdgeTypeId type) const = 0;
|
||||
virtual bool HasProperty(const std::string &name) const = 0;
|
||||
virtual bool HasEdgeType(const std::string &name) const = 0;
|
||||
virtual bool HasLabel(const std::string &name) const = 0;
|
||||
virtual bool IsPrimaryLabel(LabelId label) const = 0;
|
||||
virtual bool IsPrimaryKey(LabelId primary_label, PropertyId property) const = 0;
|
||||
};
|
||||
@ -353,6 +356,12 @@ class ShardRequestManager : public ShardRequestManagerInterface {
|
||||
return result_rows;
|
||||
}
|
||||
|
||||
bool HasProperty(const std::string &name) const override { return shards_map_.GetPropertyId(name).has_value(); }
|
||||
|
||||
bool HasEdgeType(const std::string &name) const override { return shards_map_.GetEdgeTypeId(name).has_value(); }
|
||||
|
||||
bool HasLabel(const std::string &name) const override { return shards_map_.GetLabelId(name).has_value(); }
|
||||
|
||||
private:
|
||||
enum class PaginatedResponseState { Pending, PartiallyFinished };
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "query/v2/frontend/ast/ast.hpp"
|
||||
#include "query/v2/requests.hpp"
|
||||
#include "query/v2/shard_request_manager.hpp"
|
||||
#include "storage/v3/property_value.hpp"
|
||||
#include "storage/v3/storage.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/string.hpp"
|
||||
@ -117,6 +118,12 @@ class MockedShardRequestManager : public memgraph::msgs::ShardRequestManagerInte
|
||||
return edge_types_.IdToName(id.AsUint());
|
||||
}
|
||||
|
||||
bool HasProperty(const std::string &name) const override { return shards_map_.GetPropertyId(name).has_value(); }
|
||||
|
||||
bool HasEdgeType(const std::string &name) const override { return shards_map_.GetEdgeTypeId(name).has_value(); }
|
||||
|
||||
bool HasLabel(const std::string &name) const override { return shards_map_.GetLabelId(name).has_value(); }
|
||||
|
||||
bool IsPrimaryLabel(LabelId label) const override { return true; }
|
||||
|
||||
bool IsPrimaryKey(LabelId primary_label, PropertyId property) const override { return true; }
|
||||
@ -202,10 +209,6 @@ class ExpressionEvaluatorTest : public ::testing::Test {
|
||||
ExpressionEvaluatorTest() {}
|
||||
|
||||
protected:
|
||||
// memgraph::storage::Storage db;
|
||||
// memgraph::storage::Storage::Accessor storage_dba{db.Access()};
|
||||
// memgraph::query::DbAccessor dba{&storage_dba};
|
||||
//
|
||||
AstStorage storage;
|
||||
memgraph::utils::MonotonicBufferResource mem{1024};
|
||||
EvaluationContext ctx{.memory = &mem, .timestamp = memgraph::query::v2::QueryTimestamp()};
|
||||
@ -575,36 +578,33 @@ TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) {
|
||||
// TODO(kostasrim) Investigate
|
||||
// Shall we return null on missing properties? Or shall we throw bad optional access as we do now?
|
||||
|
||||
// {
|
||||
// // Legal indexing, non-existing key.
|
||||
// auto *op1 = storage.Create<SubscriptOperator>(vertex_id, storage.Create<PrimitiveLiteral>("blah"));
|
||||
// auto value1 = Eval(op1);
|
||||
// EXPECT_TRUE(value1.IsNull());
|
||||
//
|
||||
// auto *op2 = storage.Create<SubscriptOperator>(edge_id, storage.Create<PrimitiveLiteral>("blah"));
|
||||
// auto value2 = Eval(op2);
|
||||
// EXPECT_TRUE(value2.IsNull());
|
||||
// }
|
||||
// {
|
||||
// // Wrong key type.
|
||||
// auto *op1 = storage.Create<SubscriptOperator>(vertex_id, storage.Create<PrimitiveLiteral>(1));
|
||||
// EXPECT_THROW(Eval(op1), ExpressionRuntimeException);
|
||||
//
|
||||
// auto *op2 = storage.Create<SubscriptOperator>(edge_id, storage.Create<PrimitiveLiteral>(1));
|
||||
// EXPECT_THROW(Eval(op2), ExpressionRuntimeException);
|
||||
// }
|
||||
// {
|
||||
// // Indexing with Null.
|
||||
// auto *op1 = storage.Create<SubscriptOperator>(vertex_id,
|
||||
// storage.Create<PrimitiveLiteral>(memgraph::storage::PropertyValue()));
|
||||
// auto value1 = Eval(op1);
|
||||
// EXPECT_TRUE(value1.IsNull());
|
||||
//
|
||||
// auto *op2 = storage.Create<SubscriptOperator>(edge_id,
|
||||
// storage.Create<PrimitiveLiteral>(memgraph::storage::PropertyValue()));
|
||||
// auto value2 = Eval(op2);
|
||||
// EXPECT_TRUE(value2.IsNull());
|
||||
// }
|
||||
{
|
||||
// Legal indexing, non-existing key.
|
||||
auto *op1 = storage.Create<SubscriptOperator>(vertex_id, storage.Create<PrimitiveLiteral>("blah"));
|
||||
auto value1 = Eval(op1);
|
||||
EXPECT_TRUE(value1.IsNull());
|
||||
auto *op2 = storage.Create<SubscriptOperator>(edge_id, storage.Create<PrimitiveLiteral>("blah"));
|
||||
auto value2 = Eval(op2);
|
||||
EXPECT_TRUE(value2.IsNull());
|
||||
}
|
||||
{
|
||||
// Wrong key type.
|
||||
auto *op1 = storage.Create<SubscriptOperator>(vertex_id, storage.Create<PrimitiveLiteral>(1));
|
||||
EXPECT_THROW(Eval(op1), ExpressionRuntimeException);
|
||||
|
||||
auto *op2 = storage.Create<SubscriptOperator>(edge_id, storage.Create<PrimitiveLiteral>(1));
|
||||
EXPECT_THROW(Eval(op2), ExpressionRuntimeException);
|
||||
}
|
||||
{
|
||||
// Indexing with Null.
|
||||
auto *op1 = storage.Create<SubscriptOperator>(vertex_id, storage.Create<PrimitiveLiteral>(TypedValue{}));
|
||||
auto value1 = Eval(op1);
|
||||
EXPECT_TRUE(value1.IsNull());
|
||||
|
||||
auto *op2 = storage.Create<SubscriptOperator>(edge_id, storage.Create<PrimitiveLiteral>(TypedValue{}));
|
||||
auto value2 = Eval(op2);
|
||||
EXPECT_TRUE(value2.IsNull());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorTest, ListSlicingOperator) {
|
||||
@ -741,41 +741,31 @@ TEST_F(ExpressionEvaluatorTest, IsNullOperator) {
|
||||
ASSERT_EQ(val2.ValueBool(), true);
|
||||
}
|
||||
|
||||
// TEST_F(ExpressionEvaluatorTest, LabelsTest) {
|
||||
// auto v1 = dba.InsertVertex();
|
||||
// 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();
|
||||
// auto *identifier = storage.Create<Identifier>("n");
|
||||
// auto node_symbol = symbol_table.CreateSymbol("n", true);
|
||||
// identifier->MapTo(node_symbol);
|
||||
// frame[node_symbol] = TypedValue(v1);
|
||||
// {
|
||||
// auto *op = storage.Create<LabelsTest>(
|
||||
// identifier, std::vector<LabelIx>{storage.GetLabelIx("DOG"), storage.GetLabelIx("ANIMAL")});
|
||||
// auto value = Eval(op);
|
||||
// EXPECT_EQ(value.ValueBool(), true);
|
||||
// }
|
||||
// {
|
||||
// auto *op = storage.Create<LabelsTest>(
|
||||
// identifier,
|
||||
// std::vector<LabelIx>{storage.GetLabelIx("DOG"), storage.GetLabelIx("BAD_DOG"),
|
||||
// storage.GetLabelIx("ANIMAL")});
|
||||
// auto value = Eval(op);
|
||||
// EXPECT_EQ(value.ValueBool(), false);
|
||||
// }
|
||||
// {
|
||||
// frame[node_symbol] = TypedValue();
|
||||
// auto *op = storage.Create<LabelsTest>(
|
||||
// identifier,
|
||||
// std::vector<LabelIx>{storage.GetLabelIx("DOG"), storage.GetLabelIx("BAD_DOG"),
|
||||
// storage.GetLabelIx("ANIMAL")});
|
||||
// auto value = Eval(op);
|
||||
// EXPECT_TRUE(value.IsNull());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
TEST_F(ExpressionEvaluatorTest, LabelsTest) {
|
||||
Label label{shard_manager->NameToLabel("label1")};
|
||||
auto v1 = CreateVertex({}, shard_manager.get(), label);
|
||||
auto *identifier = storage.Create<Identifier>("n");
|
||||
auto node_symbol = symbol_table.CreateSymbol("n", true);
|
||||
identifier->MapTo(node_symbol);
|
||||
frame[node_symbol] = TypedValue(v1);
|
||||
{
|
||||
auto *op = storage.Create<LabelsTest>(identifier, std::vector<LabelIx>{LabelIx{"label1", label.id.AsInt()}});
|
||||
auto value = Eval(op);
|
||||
EXPECT_EQ(value.ValueBool(), true);
|
||||
}
|
||||
{
|
||||
auto *op = storage.Create<LabelsTest>(identifier, std::vector<LabelIx>{LabelIx{"label2", 10}});
|
||||
auto value = Eval(op);
|
||||
EXPECT_EQ(value.ValueBool(), false);
|
||||
}
|
||||
{
|
||||
auto *op = storage.Create<LabelsTest>(identifier, std::vector<LabelIx>{LabelIx{"label2", 10}});
|
||||
frame[node_symbol] = TypedValue();
|
||||
auto value = Eval(op);
|
||||
EXPECT_TRUE(value.IsNull());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorTest, Aggregation) {
|
||||
auto aggr = storage.Create<Aggregation>(storage.Create<PrimitiveLiteral>(42), nullptr, Aggregation::Op::COUNT);
|
||||
auto aggr_sym = symbol_table.CreateSymbol("aggr", true);
|
||||
@ -794,11 +784,8 @@ TEST_F(ExpressionEvaluatorTest, ListLiteral) {
|
||||
auto &result_elems = result.ValueList();
|
||||
ASSERT_EQ(3, result_elems.size());
|
||||
EXPECT_TRUE(result_elems[0].IsInt());
|
||||
;
|
||||
EXPECT_TRUE(result_elems[1].IsString());
|
||||
;
|
||||
EXPECT_TRUE(result_elems[2].IsBool());
|
||||
;
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorTest, ParameterLookup) {
|
||||
@ -1148,167 +1135,16 @@ class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(kostasrim) These will fail because of memory resource not propagating correctly. This should be done as part of
|
||||
// polishing the allocators.
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
|
||||
// auto v1 = dba.InsertVertex();
|
||||
// ASSERT_TRUE(v1.SetProperty(prop_age.second, memgraph::storage::PropertyValue(10)).HasValue());
|
||||
// dba.AdvanceCommand();
|
||||
// auto v1 = CreateVertex({{prop_age.second, memgraph::msgs::Value(static_cast<int64_t>(32))}}, shard_manager.get());
|
||||
// frame[symbol] = TypedValue(v1);
|
||||
// EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
||||
// EXPECT_TRUE(Value(prop_height).IsNull());
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, Duration) {
|
||||
// const memgraph::utils::Duration dur({10, 1, 30, 2, 22, 45});
|
||||
// frame[symbol] = TypedValue(dur);
|
||||
//
|
||||
// const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
// const auto total_days = Value(day);
|
||||
// EXPECT_TRUE(total_days.IsInt());
|
||||
// EXPECT_EQ(total_days.ValueInt(), 10);
|
||||
//
|
||||
// const std::pair hour = std::make_pair("hour", dba.NameToProperty("hour"));
|
||||
// const auto total_hours = Value(hour);
|
||||
// EXPECT_TRUE(total_hours.IsInt());
|
||||
// EXPECT_EQ(total_hours.ValueInt(), 1);
|
||||
//
|
||||
// const std::pair minute = std::make_pair("minute", dba.NameToProperty("minute"));
|
||||
// const auto total_mins = Value(minute);
|
||||
// EXPECT_TRUE(total_mins.IsInt());
|
||||
//
|
||||
// EXPECT_EQ(total_mins.ValueInt(), 1 * 60 + 30);
|
||||
//
|
||||
// const std::pair sec = std::make_pair("second", dba.NameToProperty("second"));
|
||||
// const auto total_secs = Value(sec);
|
||||
// EXPECT_TRUE(total_secs.IsInt());
|
||||
// const auto expected_secs = total_mins.ValueInt() * 60 + 2;
|
||||
// EXPECT_EQ(total_secs.ValueInt(), expected_secs);
|
||||
//
|
||||
// const std::pair milli = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
// const auto total_milli = Value(milli);
|
||||
// EXPECT_TRUE(total_milli.IsInt());
|
||||
// const auto expected_milli = total_secs.ValueInt() * 1000 + 22;
|
||||
// EXPECT_EQ(total_milli.ValueInt(), expected_milli);
|
||||
//
|
||||
// const std::pair micro = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
// const auto total_micros = Value(micro);
|
||||
// EXPECT_TRUE(total_micros.IsInt());
|
||||
// const auto expected_micros = expected_milli * 1000 + 45;
|
||||
// EXPECT_EQ(total_micros.ValueInt(), expected_micros);
|
||||
//
|
||||
// const std::pair nano = std::make_pair("nanosecond", dba.NameToProperty("nanosecond"));
|
||||
// const auto total_nano = Value(nano);
|
||||
// EXPECT_TRUE(total_nano.IsInt());
|
||||
// const auto expected_nano = expected_micros * 1000;
|
||||
// EXPECT_EQ(total_nano.ValueInt(), expected_nano);
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, Date) {
|
||||
// const memgraph::utils::Date date({1996, 11, 22});
|
||||
// frame[symbol] = TypedValue(date);
|
||||
//
|
||||
// const std::pair year = std::make_pair("year", dba.NameToProperty("year"));
|
||||
// const auto y = Value(year);
|
||||
// EXPECT_TRUE(y.IsInt());
|
||||
// EXPECT_EQ(y.ValueInt(), 1996);
|
||||
//
|
||||
// const std::pair month = std::make_pair("month", dba.NameToProperty("month"));
|
||||
// const auto m = Value(month);
|
||||
// EXPECT_TRUE(m.IsInt());
|
||||
// EXPECT_EQ(m.ValueInt(), 11);
|
||||
//
|
||||
// const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
// const auto d = Value(day);
|
||||
// EXPECT_TRUE(d.IsInt());
|
||||
// EXPECT_EQ(d.ValueInt(), 22);
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, LocalTime) {
|
||||
// const memgraph::utils::LocalTime lt({1, 2, 3, 11, 22});
|
||||
// frame[symbol] = TypedValue(lt);
|
||||
//
|
||||
// const std::pair hour = std::make_pair("hour", dba.NameToProperty("hour"));
|
||||
// const auto h = Value(hour);
|
||||
// EXPECT_TRUE(h.IsInt());
|
||||
// EXPECT_EQ(h.ValueInt(), 1);
|
||||
//
|
||||
// const std::pair minute = std::make_pair("minute", dba.NameToProperty("minute"));
|
||||
// const auto min = Value(minute);
|
||||
// EXPECT_TRUE(min.IsInt());
|
||||
// EXPECT_EQ(min.ValueInt(), 2);
|
||||
//
|
||||
// const std::pair second = std::make_pair("second", dba.NameToProperty("second"));
|
||||
// const auto sec = Value(second);
|
||||
// EXPECT_TRUE(sec.IsInt());
|
||||
// EXPECT_EQ(sec.ValueInt(), 3);
|
||||
//
|
||||
// const std::pair millis = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
// const auto mil = Value(millis);
|
||||
// EXPECT_TRUE(mil.IsInt());
|
||||
// EXPECT_EQ(mil.ValueInt(), 11);
|
||||
//
|
||||
// const std::pair micros = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
// const auto mic = Value(micros);
|
||||
// EXPECT_TRUE(mic.IsInt());
|
||||
// EXPECT_EQ(mic.ValueInt(), 22);
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, LocalDateTime) {
|
||||
// const memgraph::utils::LocalDateTime ldt({1993, 8, 6}, {2, 3, 4, 55, 40});
|
||||
// frame[symbol] = TypedValue(ldt);
|
||||
//
|
||||
// const std::pair year = std::make_pair("year", dba.NameToProperty("year"));
|
||||
// const auto y = Value(year);
|
||||
// EXPECT_TRUE(y.IsInt());
|
||||
// EXPECT_EQ(y.ValueInt(), 1993);
|
||||
//
|
||||
// const std::pair month = std::make_pair("month", dba.NameToProperty("month"));
|
||||
// const auto m = Value(month);
|
||||
// EXPECT_TRUE(m.IsInt());
|
||||
// EXPECT_EQ(m.ValueInt(), 8);
|
||||
//
|
||||
// const std::pair day = std::make_pair("day", dba.NameToProperty("day"));
|
||||
// const auto d = Value(day);
|
||||
// EXPECT_TRUE(d.IsInt());
|
||||
// EXPECT_EQ(d.ValueInt(), 6);
|
||||
//
|
||||
// const std::pair hour = std::make_pair("hour", dba.NameToProperty("hour"));
|
||||
// const auto h = Value(hour);
|
||||
// EXPECT_TRUE(h.IsInt());
|
||||
// EXPECT_EQ(h.ValueInt(), 2);
|
||||
//
|
||||
// const std::pair minute = std::make_pair("minute", dba.NameToProperty("minute"));
|
||||
// const auto min = Value(minute);
|
||||
// EXPECT_TRUE(min.IsInt());
|
||||
// EXPECT_EQ(min.ValueInt(), 3);
|
||||
//
|
||||
// const std::pair second = std::make_pair("second", dba.NameToProperty("second"));
|
||||
// const auto sec = Value(second);
|
||||
// EXPECT_TRUE(sec.IsInt());
|
||||
// EXPECT_EQ(sec.ValueInt(), 4);
|
||||
//
|
||||
// const std::pair millis = std::make_pair("millisecond", dba.NameToProperty("millisecond"));
|
||||
// const auto mil = Value(millis);
|
||||
// EXPECT_TRUE(mil.IsInt());
|
||||
// EXPECT_EQ(mil.ValueInt(), 55);
|
||||
//
|
||||
// const std::pair micros = std::make_pair("microsecond", dba.NameToProperty("microsecond"));
|
||||
// const auto mic = Value(micros);
|
||||
// EXPECT_TRUE(mic.IsInt());
|
||||
// EXPECT_EQ(mic.ValueInt(), 40);
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {
|
||||
// auto v1 = dba.InsertVertex();
|
||||
// auto v2 = dba.InsertVertex();
|
||||
// auto e12 = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("edge_type"));
|
||||
// ASSERT_TRUE(e12.HasValue());
|
||||
// ASSERT_TRUE(e12->SetProperty(prop_age.second, memgraph::storage::PropertyValue(10)).HasValue());
|
||||
// dba.AdvanceCommand();
|
||||
// frame[symbol] = TypedValue(*e12);
|
||||
// EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
||||
// EXPECT_TRUE(Value(prop_height).IsNull());
|
||||
// }
|
||||
//
|
||||
// TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {}
|
||||
|
||||
TEST_F(ExpressionEvaluatorPropertyLookup, Null) {
|
||||
frame[symbol] = TypedValue();
|
||||
EXPECT_TRUE(Value(prop_age).IsNull());
|
||||
@ -1455,59 +1291,10 @@ TEST_F(FunctionTest, StartNode) {
|
||||
}
|
||||
|
||||
// TODO(kostasrim) Enable this test once we add degree to the accessors
|
||||
// TEST_F(FunctionTest, Degree) {
|
||||
// ASSERT_THROW(EvaluateFunction("DEGREE"), ExpressionRuntimeException);
|
||||
// ASSERT_TRUE(EvaluateFunction("DEGREE", TypedValue()).IsNull());
|
||||
// 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();
|
||||
// ASSERT_EQ(EvaluateFunction("DEGREE", v1).ValueInt(), 1);
|
||||
// ASSERT_EQ(EvaluateFunction("DEGREE", v2).ValueInt(), 2);
|
||||
// ASSERT_EQ(EvaluateFunction("DEGREE", v3).ValueInt(), 1);
|
||||
// ASSERT_THROW(EvaluateFunction("DEGREE", 2), ExpressionRuntimeException);
|
||||
// ASSERT_THROW(EvaluateFunction("DEGREE", *e12), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TODO(kostasrim) Enable this test once we add InDegree to the accessors
|
||||
// TEST_F(FunctionTest, InDegree) {
|
||||
// ASSERT_THROW(EvaluateFunction("INDEGREE"), ExpressionRuntimeException);
|
||||
// ASSERT_TRUE(EvaluateFunction("INDEGREE", TypedValue()).IsNull());
|
||||
// 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();
|
||||
// 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), ExpressionRuntimeException);
|
||||
// ASSERT_THROW(EvaluateFunction("INDEGREE", *e12), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TODO(kostasrim) Enable this test once we add OutDegree to the accessors
|
||||
// TEST_F(FunctionTest, OutDegree) {
|
||||
// ASSERT_THROW(EvaluateFunction("OUTDEGREE"), ExpressionRuntimeException);
|
||||
// ASSERT_TRUE(EvaluateFunction("OUTDEGREE", TypedValue()).IsNull());
|
||||
// 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();
|
||||
// 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), ExpressionRuntimeException);
|
||||
// ASSERT_THROW(EvaluateFunction("OUTDEGREE", *e12), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, Degree) {}
|
||||
// TEST_F(FunctionTest, InDegree) {}
|
||||
// TEST_F(FunctionTest, OutDegree) {}
|
||||
|
||||
TEST_F(FunctionTest, ToBoolean) {
|
||||
ASSERT_THROW(EvaluateFunction("TOBOOLEAN"), FunctionRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("TOBOOLEAN", TypedValue()).IsNull());
|
||||
@ -1591,42 +1378,8 @@ TEST_F(FunctionTest, Labels) {
|
||||
}
|
||||
|
||||
// TODO(kostasrim) Enable this once we fix accessors Path
|
||||
// TEST_F(FunctionTest, NodesRelationships) {
|
||||
// EXPECT_THROW(EvaluateFunction("NODES"), ExpressionRuntimeException);
|
||||
// EXPECT_THROW(EvaluateFunction("RELATIONSHIPS"), ExpressionRuntimeException);
|
||||
// EXPECT_TRUE(EvaluateFunction("NODES", TypedValue()).IsNull());
|
||||
// EXPECT_TRUE(EvaluateFunction("RELATIONSHIPS", TypedValue()).IsNull());
|
||||
//
|
||||
// {
|
||||
// auto v1 = dba.InsertVertex();
|
||||
// auto v2 = dba.InsertVertex();
|
||||
// auto v3 = dba.InsertVertex();
|
||||
// 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());
|
||||
// memgraph::query::Path path{v1, *e1, v2, *e2, v3};
|
||||
// dba.AdvanceCommand();
|
||||
//
|
||||
// auto _nodes = EvaluateFunction("NODES", path).ValueList();
|
||||
// std::vector<memgraph::query::VertexAccessor> nodes;
|
||||
// for (const auto &node : _nodes) {
|
||||
// nodes.push_back(node.ValueVertex());
|
||||
// }
|
||||
// EXPECT_THAT(nodes, ElementsAre(v1, v2, v3));
|
||||
//
|
||||
// auto _edges = EvaluateFunction("RELATIONSHIPS", path).ValueList();
|
||||
// std::vector<memgraph::query::EdgeAccessor> edges;
|
||||
// for (const auto &edge : _edges) {
|
||||
// edges.push_back(edge.ValueEdge());
|
||||
// }
|
||||
// EXPECT_THAT(edges, ElementsAre(*e1, *e2));
|
||||
// }
|
||||
//
|
||||
// EXPECT_THROW(EvaluateFunction("NODES", 2), ExpressionRuntimeException);
|
||||
// EXPECT_THROW(EvaluateFunction("RELATIONSHIPS", 2), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, NodesRelationships) {}
|
||||
|
||||
TEST_F(FunctionTest, Range) {
|
||||
EXPECT_THROW(EvaluateFunction("RANGE"), FunctionRuntimeException);
|
||||
EXPECT_TRUE(EvaluateFunction("RANGE", 1, 2, TypedValue()).IsNull());
|
||||
@ -1889,64 +1642,10 @@ TEST_F(FunctionTest, ToStringBool) {
|
||||
EXPECT_EQ(EvaluateFunction("TOSTRING", false).ValueString(), "false");
|
||||
}
|
||||
|
||||
// TEST_F(FunctionTest, ToStringDate) {
|
||||
// const auto date = memgraph::utils::Date({1970, 1, 2});
|
||||
// EXPECT_EQ(EvaluateFunction("TOSTRING", date).ValueString(), "1970-01-02");
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, ToStringLocalTime) {
|
||||
// const auto lt = memgraph::utils::LocalTime({13, 2, 40, 100, 50});
|
||||
// EXPECT_EQ(EvaluateFunction("TOSTRING", lt).ValueString(), "13:02:40.100050");
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, ToStringLocalDateTime) {
|
||||
// const auto ldt = memgraph::utils::LocalDateTime({1970, 1, 2}, {23, 02, 59});
|
||||
// EXPECT_EQ(EvaluateFunction("TOSTRING", ldt).ValueString(), "1970-01-02T23:02:59.000000");
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, ToStringDuration) {
|
||||
// memgraph::utils::Duration duration{{.minute = 2, .second = 2, .microsecond = 33}};
|
||||
// EXPECT_EQ(EvaluateFunction("TOSTRING", duration).ValueString(), "P0DT0H2M2.000033S");
|
||||
// }
|
||||
//
|
||||
TEST_F(FunctionTest, ToStringExceptions) {
|
||||
EXPECT_THROW(EvaluateFunction("TOSTRING", 1, 2, 3), FunctionRuntimeException);
|
||||
}
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampVoid) {
|
||||
// ctx.timestamp = 42;
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP").ValueInt(), 42);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampDate) {
|
||||
// ctx.timestamp = 42;
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP", memgraph::utils::Date({1970, 1, 1})).ValueInt(), 0);
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP", memgraph::utils::Date({1971, 1, 1})).ValueInt(), 31536000000000);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampLocalTime) {
|
||||
// ctx.timestamp = 42;
|
||||
// const memgraph::utils::LocalTime time(10000);
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP", time).ValueInt(), 10000);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampLocalDateTime) {
|
||||
// ctx.timestamp = 42;
|
||||
// const memgraph::utils::LocalDateTime time(20000);
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP", time).ValueInt(), 20000);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampDuration) {
|
||||
// ctx.timestamp = 42;
|
||||
// const memgraph::utils::Duration time(20000);
|
||||
// EXPECT_EQ(EvaluateFunction("TIMESTAMP", time).ValueInt(), 20000);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, TimestampExceptions) {
|
||||
// ctx.timestamp = 42;
|
||||
// EXPECT_THROW(EvaluateFunction("TIMESTAMP", 1).ValueInt(), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
|
||||
TEST_F(FunctionTest, Left) {
|
||||
EXPECT_THROW(EvaluateFunction("LEFT"), FunctionRuntimeException);
|
||||
|
||||
@ -2083,110 +1782,5 @@ TEST_F(FunctionTest, FromByteString) {
|
||||
EXPECT_EQ(EvaluateFunction("FROMBYTESTRING", std::string("\x00\x42", 2)).ValueString(), "0x0042");
|
||||
}
|
||||
|
||||
// TEST_F(FunctionTest, Date) {
|
||||
// const auto unix_epoch = memgraph::utils::Date({1970, 1, 1});
|
||||
// EXPECT_EQ(EvaluateFunction("DATE", "1970-01-01").ValueDate(), unix_epoch);
|
||||
// const auto map_param = TypedValue(
|
||||
// std::map<std::string, TypedValue>{{"year", TypedValue(1970)}, {"month", TypedValue(1)}, {"day",
|
||||
// TypedValue(1)}});
|
||||
// EXPECT_EQ(EvaluateFunction("DATE", map_param).ValueDate(), unix_epoch);
|
||||
// const auto today = memgraph::utils::CurrentDate();
|
||||
// EXPECT_EQ(EvaluateFunction("DATE").ValueDate(), today);
|
||||
//
|
||||
// EXPECT_THROW(EvaluateFunction("DATE", "{}"), memgraph::utils::BasicException);
|
||||
// EXPECT_THROW(EvaluateFunction("DATE", std::map<std::string, TypedValue>{{"years", TypedValue(1970)}}),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(EvaluateFunction("DATE", std::map<std::string, TypedValue>{{"mnths", TypedValue(1970)}}),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(EvaluateFunction("DATE", std::map<std::string, TypedValue>{{"dayz", TypedValue(1970)}}),
|
||||
// ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, LocalTime) {
|
||||
// const auto local_time = memgraph::utils::LocalTime({13, 3, 2, 0, 0});
|
||||
// EXPECT_EQ(EvaluateFunction("LOCALTIME", "130302").ValueLocalTime(), local_time);
|
||||
// const auto one_sec_in_microseconds = 1000000;
|
||||
// const auto map_param = TypedValue(std::map<std::string, TypedValue>{{"hour", TypedValue(1)},
|
||||
// {"minute", TypedValue(2)},
|
||||
// {"second", TypedValue(3)},
|
||||
// {"millisecond", TypedValue(4)},
|
||||
// {"microsecond", TypedValue(5)}});
|
||||
// EXPECT_EQ(EvaluateFunction("LOCALTIME", map_param).ValueLocalTime(), memgraph::utils::LocalTime({1, 2, 3, 4, 5}));
|
||||
// const auto today = memgraph::utils::CurrentLocalTime();
|
||||
// EXPECT_NEAR(EvaluateFunction("LOCALTIME").ValueLocalTime().MicrosecondsSinceEpoch(),
|
||||
// today.MicrosecondsSinceEpoch(),
|
||||
// one_sec_in_microseconds);
|
||||
//
|
||||
// EXPECT_THROW(EvaluateFunction("LOCALTIME", "{}"), memgraph::utils::BasicException);
|
||||
// EXPECT_THROW(EvaluateFunction("LOCALTIME", TypedValue(std::map<std::string, TypedValue>{{"hous",
|
||||
// TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(
|
||||
// EvaluateFunction("LOCALTIME", TypedValue(std::map<std::string, TypedValue>{{"minut", TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(
|
||||
// EvaluateFunction("LOCALTIME", TypedValue(std::map<std::string, TypedValue>{{"seconds", TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, LocalDateTime) {
|
||||
// const auto local_date_time = memgraph::utils::LocalDateTime({1970, 1, 1}, {13, 3, 2, 0, 0});
|
||||
// EXPECT_EQ(EvaluateFunction("LOCALDATETIME", "1970-01-01T13:03:02").ValueLocalDateTime(), local_date_time);
|
||||
// const auto today = memgraph::utils::CurrentLocalDateTime();
|
||||
// const auto one_sec_in_microseconds = 1000000;
|
||||
// const auto map_param = TypedValue(std::map<std::string, TypedValue>{{"year", TypedValue(1972)},
|
||||
// {"month", TypedValue(2)},
|
||||
// {"day", TypedValue(3)},
|
||||
// {"hour", TypedValue(4)},
|
||||
// {"minute", TypedValue(5)},
|
||||
// {"second", TypedValue(6)},
|
||||
// {"millisecond", TypedValue(7)},
|
||||
// {"microsecond", TypedValue(8)}});
|
||||
//
|
||||
// EXPECT_EQ(EvaluateFunction("LOCALDATETIME", map_param).ValueLocalDateTime(),
|
||||
// memgraph::utils::LocalDateTime({1972, 2, 3}, {4, 5, 6, 7, 8}));
|
||||
// EXPECT_NEAR(EvaluateFunction("LOCALDATETIME").ValueLocalDateTime().MicrosecondsSinceEpoch(),
|
||||
// today.MicrosecondsSinceEpoch(), one_sec_in_microseconds);
|
||||
// EXPECT_THROW(EvaluateFunction("LOCALDATETIME", "{}"), memgraph::utils::BasicException);
|
||||
// EXPECT_THROW(
|
||||
// EvaluateFunction("LOCALDATETIME", TypedValue(std::map<std::string, TypedValue>{{"hours", TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(
|
||||
// EvaluateFunction("LOCALDATETIME", TypedValue(std::map<std::string, TypedValue>{{"seconds",
|
||||
// TypedValue(1970)}})), ExpressionRuntimeException);
|
||||
// }
|
||||
//
|
||||
// TEST_F(FunctionTest, Duration) {
|
||||
// const auto map_param = TypedValue(std::map<std::string, TypedValue>{{"day", TypedValue(3)},
|
||||
// {"hour", TypedValue(4)},
|
||||
// {"minute", TypedValue(5)},
|
||||
// {"second", TypedValue(6)},
|
||||
// {"millisecond", TypedValue(7)},
|
||||
// {"microsecond", TypedValue(8)}});
|
||||
//
|
||||
// EXPECT_EQ(EvaluateFunction("DURATION", map_param).ValueDuration(), memgraph::utils::Duration({3, 4, 5, 6, 7, 8}));
|
||||
// EXPECT_THROW(EvaluateFunction("DURATION", "{}"), memgraph::utils::BasicException);
|
||||
// EXPECT_THROW(EvaluateFunction("DURATION", TypedValue(std::map<std::string, TypedValue>{{"hours",
|
||||
// TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
// EXPECT_THROW(
|
||||
// EvaluateFunction("DURATION", TypedValue(std::map<std::string, TypedValue>{{"seconds", TypedValue(1970)}})),
|
||||
// ExpressionRuntimeException);
|
||||
//
|
||||
// const auto map_param_negative = TypedValue(std::map<std::string, TypedValue>{{"day", TypedValue(-3)},
|
||||
// {"hour", TypedValue(-4)},
|
||||
// {"minute", TypedValue(-5)},
|
||||
// {"second", TypedValue(-6)},
|
||||
// {"millisecond", TypedValue(-7)},
|
||||
// {"microsecond", TypedValue(-8)}});
|
||||
// EXPECT_EQ(EvaluateFunction("DURATION", map_param_negative).ValueDuration(),
|
||||
// memgraph::utils::Duration({-3, -4, -5, -6, -7, -8}));
|
||||
//
|
||||
// EXPECT_EQ(EvaluateFunction("DURATION", "P4DT4H5M6.2S").ValueDuration(),
|
||||
// memgraph::utils::Duration({4, 4, 5, 6, 0, 200000}));
|
||||
// EXPECT_EQ(EvaluateFunction("DURATION", "P3DT4H5M6.100S").ValueDuration(),
|
||||
// memgraph::utils::Duration({3, 4, 5, 6, 0, 100000}));
|
||||
// EXPECT_EQ(EvaluateFunction("DURATION", "P3DT4H5M6.100110S").ValueDuration(),
|
||||
// memgraph::utils::Duration({3, 4, 5, 6, 100, 110}));
|
||||
// }
|
||||
// TODO(kostasrim) Add temporal type tests.
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user