diff --git a/src/query/backend/cpp/typed_value.cpp b/src/query/backend/cpp/typed_value.cpp index 2574e43eb..084f728f3 100644 --- a/src/query/backend/cpp/typed_value.cpp +++ b/src/query/backend/cpp/typed_value.cpp @@ -12,32 +12,26 @@ TypedValue::TypedValue(const PropertyValue& value) { case PropertyValue::Type::Null: type_ = Type::Null; return; - case PropertyValue::Type::Bool: type_ = Type::Bool; bool_v = value.Value<bool>(); return; - case PropertyValue::Type::Int: type_ = Type::Int; int_v = value.Value<int>(); return; - case PropertyValue::Type::Double: type_ = Type::Double; double_v = value.Value<double>(); - case PropertyValue::Type::String: type_ = Type::String; new (&string_v) std::string(value.Value<std::string>()); - case PropertyValue::Type::List: type_ = Type::List; auto vec = value.Value<std::vector<PropertyValue>>(); new (&list_v) std::vector<TypedValue>(vec.begin(), vec.end()); return; } - permanent_fail("Unsupported PropertyValue::Type"); } @@ -56,6 +50,8 @@ TypedValue::operator PropertyValue() const { case TypedValue::Type::List: return PropertyValue( std::vector<PropertyValue>(list_v.begin(), list_v.end())); + default: + permanent_fail("Unsupported PropertyValue::Type"); } permanent_fail("Unsupported PropertyValue::Type"); } @@ -68,13 +64,6 @@ bool TypedValue::Value<bool>() const { return bool_v; } -template <> -std::string TypedValue::Value<std::string>() const { - debug_assert(type_ == TypedValue::Type::String, - "Incompatible template param and type"); - return string_v; -} - template <> int TypedValue::Value<int>() const { debug_assert(type_ == TypedValue::Type::Int, @@ -89,6 +78,13 @@ double TypedValue::Value<double>() const { return double_v; } +template <> +std::string TypedValue::Value<std::string>() const { + debug_assert(type_ == TypedValue::Type::String, + "Incompatible template param and type"); + return string_v; +} + template <> std::vector<TypedValue> TypedValue::Value<std::vector<TypedValue>>() const { debug_assert(type_ == TypedValue::Type::List, @@ -96,32 +92,66 @@ std::vector<TypedValue> TypedValue::Value<std::vector<TypedValue>>() const { return list_v; } +template <> +std::map<std::string, TypedValue> +TypedValue::Value<std::map<std::string, TypedValue>>() const { + debug_assert(type_ == TypedValue::Type::Map, + "Incompatible template param and type"); + return map_v; +} + +template <> +VertexAccessor TypedValue::Value<VertexAccessor>() const { + debug_assert(type_ == TypedValue::Type::Vertex, + "Incompatible template param and type"); + return vertex_v; +} + +template <> +EdgeAccessor TypedValue::Value<EdgeAccessor>() const { + debug_assert(type_ == TypedValue::Type::Edge, + "Incompatible template param and type"); + return edge_v; +} + +template <> +Path TypedValue::Value<Path>() const { + debug_assert(type_ == TypedValue::Type::Path, + "Incompatible template param and type"); + return path_v; +} + TypedValue::TypedValue(const TypedValue& other) : type_(other.type_) { switch (other.type_) { case TypedValue::Type::Null: return; - case TypedValue::Type::Bool: this->bool_v = other.bool_v; return; - - case TypedValue::Type::String: - new (&string_v) std::string(other.string_v); - return; - case Type::Int: this->int_v = other.int_v; return; - case Type::Double: this->double_v = other.double_v; return; - + case TypedValue::Type::String: + new (&string_v) std::string(other.string_v); + return; case Type::List: new (&list_v) std::vector<TypedValue>(other.list_v); return; + case Type::Map: + new (&map_v) std::map<std::string, TypedValue>(other.map_v); + return; + case Type::Vertex: + new (&vertex_v) VertexAccessor(other.vertex_v); + return; + case Type::Edge: + new (&edge_v) EdgeAccessor(other.edge_v); + return; + case Type::Path: + new (&path_v) Path(other.path_v); } - permanent_fail("Unsupported TypedValue::Type"); } @@ -131,14 +161,22 @@ std::ostream& operator<<(std::ostream& os, const TypedValue::Type type) { return os << "null"; case TypedValue::Type::Bool: return os << "bool"; - case TypedValue::Type::String: - return os << "string"; case TypedValue::Type::Int: return os << "int"; case TypedValue::Type::Double: return os << "double"; + case TypedValue::Type::String: + return os << "string"; case TypedValue::Type::List: return os << "list"; + case TypedValue::Type::Map: + return os << "map"; + case TypedValue::Type::Vertex: + return os << "vertex"; + case TypedValue::Type::Edge: + return os << "edge"; + case TypedValue::Type::Path: + return os << "path"; } permanent_fail("Unsupported TypedValue::Type"); } @@ -149,18 +187,30 @@ std::ostream& operator<<(std::ostream& os, const TypedValue& value) { return os << "Null"; case TypedValue::Type::Bool: return os << (value.Value<bool>() ? "true" : "false"); - case TypedValue::Type::String: - return os << value.Value<std::string>(); case TypedValue::Type::Int: return os << value.Value<int>(); case TypedValue::Type::Double: return os << value.Value<double>(); + case TypedValue::Type::String: + return os << value.Value<std::string>(); case TypedValue::Type::List: os << "["; for (const auto& x : value.Value<std::vector<TypedValue>>()) { os << x << ","; } return os << "]"; + case TypedValue::Type::Map: + os << "{"; + for (const auto& x : value.Value<std::map<std::string, TypedValue>>()) { + os << x.first << ": " << x.second << ","; + } + return os << "}"; + case TypedValue::Type::Vertex: + return os << value.Value<VertexAccessor>(); + case TypedValue::Type::Edge: + return os << value.Value<EdgeAccessor>(); + case TypedValue::Type::Path: + return os << value.Value<Path>(); } permanent_fail("Unsupported PropertyValue::Type"); } @@ -176,18 +226,30 @@ TypedValue& TypedValue::operator=(const TypedValue& other) { case TypedValue::Type::Bool: this->bool_v = other.bool_v; return *this; - case TypedValue::Type::String: - new (&string_v) std::string(other.string_v); - return *this; case TypedValue::Type::Int: this->int_v = other.int_v; return *this; case TypedValue::Type::Double: this->double_v = other.double_v; return *this; + case TypedValue::Type::String: + new (&string_v) std::string(other.string_v); + return *this; case TypedValue::Type::List: new (&list_v) std::vector<TypedValue>(other.list_v); return *this; + case TypedValue::Type::Map: + new (&map_v) std::map<std::string, TypedValue>(other.map_v); + return *this; + case TypedValue::Type::Vertex: + new (&vertex_v) VertexAccessor(other.vertex_v); + return *this; + case TypedValue::Type::Edge: + new (&edge_v) EdgeAccessor(other.edge_v); + return *this; + case TypedValue::Type::Path: + new (&path_v) Path(other.path_v); + return *this; } } permanent_fail("Unsupported TypedValue::Type"); @@ -216,6 +278,19 @@ TypedValue::~TypedValue() { using namespace std; list_v.~vector<TypedValue>(); return; + case Type::Map: + using namespace std; + map_v.~map<std::string, TypedValue>(); + return; + case Type::Vertex: + vertex_v.~VertexAccessor(); + return; + case Type::Edge: + edge_v.~EdgeAccessor(); + return; + case Type::Path: + path_v.~Path(); + return; } permanent_fail("Unsupported TypedValue::Type"); } diff --git a/src/query/backend/cpp/typed_value.hpp b/src/query/backend/cpp/typed_value.hpp index 77c0dc6f1..84de55e30 100644 --- a/src/query/backend/cpp/typed_value.hpp +++ b/src/query/backend/cpp/typed_value.hpp @@ -4,11 +4,17 @@ #include <memory> #include <string> #include <vector> +#include <map> #include "utils/exceptions/stacktrace_exception.hpp" #include "utils/total_ordering.hpp" #include "utils/underlying_cast.hpp" #include "storage/property_value.hpp" +#include "storage/edge_accessor.hpp" +#include "storage/vertex_accessor.hpp" +#include "traversal/path.hpp" + +typedef traversal_template::Path<VertexAccessor, EdgeAccessor> Path; /** * Encapsulation of a value and it's type encapsulated in a class that has no @@ -24,7 +30,18 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> { public: /** A value type. Each type corresponds to exactly one C++ type */ - enum class Type : unsigned { Null, String, Bool, Int, Double, List }; + enum class Type : unsigned { + Null, + Bool, + Int, + Double, + String, + List, + Map, + Vertex, + Edge, + Path + }; // single static reference to Null, used whenever Null should be returned static const TypedValue Null; @@ -37,7 +54,7 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> { // conversion function to PropertyValue operator PropertyValue() const; - /// constructors for non-primitive types (shared pointers) + /// constructors for non-primitive types TypedValue(const std::string& value) : type_(Type::String) { new (&string_v) std::string(value); } @@ -47,6 +64,17 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> { TypedValue(const std::vector<TypedValue>& value) : type_(Type::List) { new (&list_v) std::vector<TypedValue>(value); } + TypedValue(const std::map<std::string, TypedValue>& value) + : type_(Type::Map) { + new (&map_v) std::map<std::string, TypedValue>(value); + } + TypedValue(const VertexAccessor& vertex) : type_(Type::Vertex) { + new (&vertex_v) VertexAccessor(vertex); + } + TypedValue(const EdgeAccessor& edge) : type_(Type::Edge) { + new (&edge_v) EdgeAccessor(edge); + } + TypedValue(const Path& path) : type_(Type::Path) { new (&path_v) Path(path); } TypedValue(const PropertyValue& value); // assignment ops @@ -82,7 +110,12 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> { // because of data locality. std::string string_v; std::vector<TypedValue> list_v; - // Node, Edge, Path, Map missing. + // clang doesn't allow unordered_map to have incomplete type as value so we + // we use map. + std::map<std::string, TypedValue> map_v; + VertexAccessor vertex_v; + EdgeAccessor edge_v; + Path path_v; }; /**