Make TypedValue constructor explicit for non-primitive types

Reviewers: mtomic, mferencevic, msantl

Reviewed By: mtomic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2128
This commit is contained in:
Teon Banek 2019-06-06 13:16:37 +02:00
parent b3bc4d6809
commit 57d967786c
27 changed files with 244 additions and 206 deletions

View File

@ -1149,7 +1149,7 @@ class DistributedExpandBfsCursor : public query::plan::Cursor {
subcursor_ids_, *current_edge_addr, &db_)
: bfs_subcursor_clients_->ReconstructPath(
subcursor_ids_, *current_vertex_addr, &db_);
edges.insert(edges.end(), ret.edges.begin(), ret.edges.end());
for (const auto &edge : ret.edges) edges.emplace_back(edge);
current_vertex_addr = ret.next_vertex;
current_edge_addr = ret.next_edge;
if (!current_vertex_addr && !current_edge_addr) break;

View File

@ -88,19 +88,19 @@ void Load(query::TypedValue *value, slk::Reader *reader,
case static_cast<uint8_t>(1): {
bool v;
slk::Load(&v, reader);
*value = query::TypedValue(v);
*value = v;
return;
}
case static_cast<uint8_t>(2): {
int64_t v;
slk::Load(&v, reader);
*value = query::TypedValue(v);
*value = v;
return;
}
case static_cast<uint8_t>(3): {
double v;
slk::Load(&v, reader);
*value = query::TypedValue(v);
*value = v;
return;
}
case static_cast<uint8_t>(4): {

View File

@ -43,7 +43,7 @@ TypedValue EndNode(TypedValue *args, int64_t nargs, const EvaluationContext &,
case TypedValue::Type::Null:
return TypedValue();
case TypedValue::Type::Edge:
return args[0].Value<EdgeAccessor>().to();
return TypedValue(args[0].Value<EdgeAccessor>().to());
default:
throw QueryRuntimeException("'endNode' argument must be an edge.");
}
@ -94,9 +94,10 @@ TypedValue Properties(TypedValue *args, int64_t nargs,
auto get_properties = [&](const auto &record_accessor) {
std::map<std::string, TypedValue> properties;
for (const auto &property : record_accessor.Properties()) {
properties[dba->PropertyName(property.first)] = property.second;
properties[dba->PropertyName(property.first)] =
TypedValue(property.second);
}
return properties;
return TypedValue(properties);
};
switch (args[0].type()) {
case TypedValue::Type::Null:
@ -145,7 +146,7 @@ TypedValue StartNode(TypedValue *args, int64_t nargs, const EvaluationContext &,
case TypedValue::Type::Null:
return TypedValue();
case TypedValue::Type::Edge:
return args[0].Value<EdgeAccessor>().from();
return TypedValue(args[0].Value<EdgeAccessor>().from());
default:
throw QueryRuntimeException("'startNode' argument must be an edge.");
}
@ -294,7 +295,8 @@ TypedValue Type(TypedValue *args, int64_t nargs, const EvaluationContext &,
case TypedValue::Type::Null:
return TypedValue();
case TypedValue::Type::Edge:
return dba->EdgeTypeName(args[0].Value<EdgeAccessor>().EdgeType());
return TypedValue(
dba->EdgeTypeName(args[0].Value<EdgeAccessor>().EdgeType()));
default:
throw QueryRuntimeException("'type' argument must be an edge.");
}
@ -308,9 +310,9 @@ TypedValue Keys(TypedValue *args, int64_t nargs, const EvaluationContext &,
auto get_keys = [&](const auto &record_accessor) {
std::vector<TypedValue> keys;
for (const auto &property : record_accessor.Properties()) {
keys.push_back(dba->PropertyName(property.first));
keys.emplace_back(dba->PropertyName(property.first));
}
return keys;
return TypedValue(keys);
};
switch (args[0].type()) {
case TypedValue::Type::Null:
@ -335,9 +337,9 @@ TypedValue Labels(TypedValue *args, int64_t nargs, const EvaluationContext &,
case TypedValue::Type::Vertex: {
std::vector<TypedValue> labels;
for (const auto &label : args[0].Value<VertexAccessor>().labels()) {
labels.push_back(dba->LabelName(label));
labels.emplace_back(dba->LabelName(label));
}
return labels;
return TypedValue(labels);
}
default:
throw QueryRuntimeException("'labels' argument must be a node.");
@ -354,7 +356,7 @@ TypedValue Nodes(TypedValue *args, int64_t nargs, const EvaluationContext &,
throw QueryRuntimeException("'nodes' argument should be a path.");
}
auto &vertices = args[0].ValuePath().vertices();
return std::vector<TypedValue>(vertices.begin(), vertices.end());
return TypedValue(std::vector<TypedValue>(vertices.begin(), vertices.end()));
}
TypedValue Relationships(TypedValue *args, int64_t nargs,
@ -369,7 +371,7 @@ TypedValue Relationships(TypedValue *args, int64_t nargs,
throw QueryRuntimeException("'relationships' argument must be a path.");
}
auto &edges = args[0].ValuePath().edges();
return std::vector<TypedValue>(edges.begin(), edges.end());
return TypedValue(std::vector<TypedValue>(edges.begin(), edges.end()));
}
TypedValue Range(TypedValue *args, int64_t nargs, const EvaluationContext &,
@ -403,7 +405,7 @@ TypedValue Range(TypedValue *args, int64_t nargs, const EvaluationContext &,
list.emplace_back(i);
}
}
return list;
return TypedValue(list);
}
TypedValue Tail(TypedValue *args, int64_t nargs, const EvaluationContext &,
@ -416,9 +418,9 @@ TypedValue Tail(TypedValue *args, int64_t nargs, const EvaluationContext &,
return TypedValue();
case TypedValue::Type::List: {
auto list = args[0].ValueList();
if (list.empty()) return list;
if (list.empty()) return TypedValue(list);
list.erase(list.begin());
return list;
return TypedValue(list);
}
default:
throw QueryRuntimeException("'tail' argument must be a list.");
@ -453,7 +455,7 @@ TypedValue UniformSample(TypedValue *args, int64_t nargs,
for (int i = 0; i < desired_length; ++i) {
sampled.push_back(population[rand_dist(pseudo_rand_gen_)]);
}
return sampled;
return TypedValue(sampled);
}
throw QueryRuntimeException(
"Second argument of 'uniformSample' must be a non-negative integer.");
@ -735,9 +737,9 @@ TypedValue ToString(TypedValue *args, int64_t nargs, const EvaluationContext &,
case TypedValue::Type::String:
return arg;
case TypedValue::Type::Int:
return std::to_string(arg.ValueInt());
return TypedValue(std::to_string(arg.ValueInt()));
case TypedValue::Type::Double:
return std::to_string(arg.ValueDouble());
return TypedValue(std::to_string(arg.ValueDouble()));
case TypedValue::Type::Bool:
return TypedValue(arg.ValueBool() ? "true" : "false");
default:
@ -822,7 +824,7 @@ TypedValue CallStringFunction(
case TypedValue::Type::Null:
return TypedValue(args[0].GetMemoryResource());
case TypedValue::Type::String:
return fun(args[0].ValueString());
return TypedValue(fun(args[0].ValueString()));
default:
throw QueryRuntimeException("'" + name +
"' argument should be a string.");
@ -895,8 +897,8 @@ TypedValue Replace(TypedValue *args, int64_t nargs, const EvaluationContext &,
if (args[0].IsNull() || args[1].IsNull() || args[2].IsNull()) {
return TypedValue();
}
return utils::Replace(args[0].ValueString(), args[1].ValueString(),
args[2].ValueString());
return TypedValue(utils::Replace(args[0].ValueString(), args[1].ValueString(),
args[2].ValueString()));
}
TypedValue Split(TypedValue *args, int64_t nargs, const EvaluationContext &,
@ -920,7 +922,7 @@ TypedValue Split(TypedValue *args, int64_t nargs, const EvaluationContext &,
utils::Split(args[0].ValueString(), args[1].ValueString())) {
result.emplace_back(str);
}
return result;
return TypedValue(result);
}
TypedValue Substring(TypedValue *args, int64_t nargs, const EvaluationContext &,

View File

@ -193,16 +193,16 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
if (!index.IsString())
throw QueryRuntimeException(
"Expected a string as a property name, got {}.", index.type());
return lhs.Value<VertexAccessor>().PropsAt(
dba_->Property(std::string(index.ValueString())));
return TypedValue(lhs.Value<VertexAccessor>().PropsAt(
dba_->Property(std::string(index.ValueString()))));
}
if (lhs.IsEdge()) {
if (!index.IsString())
throw QueryRuntimeException(
"Expected a string as a property name, got {}.", index.type());
return lhs.Value<EdgeAccessor>().PropsAt(
dba_->Property(std::string(index.ValueString())));
return TypedValue(lhs.Value<EdgeAccessor>().PropsAt(
dba_->Property(std::string(index.ValueString()))));
}
// lhs is Null
@ -253,10 +253,10 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
auto lower_bound = normalise_bound(_lower_bound.Value<int64_t>());
auto upper_bound = normalise_bound(_upper_bound.Value<int64_t>());
if (upper_bound <= lower_bound) {
return std::vector<TypedValue>();
return TypedValue(std::vector<TypedValue>());
}
return std::vector<TypedValue>(list.begin() + lower_bound,
list.begin() + upper_bound);
return TypedValue(std::vector<TypedValue>(list.begin() + lower_bound,
list.begin() + upper_bound));
}
TypedValue Visit(IsNullOperator &is_null) override {
@ -270,11 +270,11 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
case TypedValue::Type::Null:
return TypedValue();
case TypedValue::Type::Vertex:
return expression_result.Value<VertexAccessor>().PropsAt(
GetProperty(property_lookup.property_));
return TypedValue(expression_result.Value<VertexAccessor>().PropsAt(
GetProperty(property_lookup.property_)));
case TypedValue::Type::Edge:
return expression_result.Value<EdgeAccessor>().PropsAt(
GetProperty(property_lookup.property_));
return TypedValue(expression_result.Value<EdgeAccessor>().PropsAt(
GetProperty(property_lookup.property_)));
case TypedValue::Type::Map: {
const auto &map = expression_result.ValueMap();
auto found = map.find(property_lookup.property_.name.c_str());
@ -309,7 +309,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
TypedValue Visit(PrimitiveLiteral &literal) override {
// TODO: no need to evaluate constants, we can write it to frame in one
// of the previous phases.
return literal.value_;
return TypedValue(literal.value_);
}
TypedValue Visit(ListLiteral &literal) override {
@ -317,14 +317,14 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
result.reserve(literal.elements_.size());
for (const auto &expression : literal.elements_)
result.emplace_back(expression->Accept(*this));
return result;
return TypedValue(result);
}
TypedValue Visit(MapLiteral &literal) override {
std::map<std::string, TypedValue> result;
for (const auto &pair : literal.elements_)
result.emplace(pair.first.name, pair.second->Accept(*this));
return result;
return TypedValue(result);
}
TypedValue Visit(Aggregation &aggregation) override {
@ -414,7 +414,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
result.emplace_back(extract.expression_->Accept(*this));
}
}
return result;
return TypedValue(result);
}
TypedValue Visit(All &all) override {
@ -477,7 +477,8 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
}
TypedValue Visit(ParameterLookup &param_lookup) override {
return ctx_->parameters.AtTokenPosition(param_lookup.token_position_);
return TypedValue(
ctx_->parameters.AtTokenPosition(param_lookup.token_position_));
}
TypedValue Visit(RegexMatch &regex_match) override {

View File

@ -59,7 +59,7 @@ class DumpClosure final {
ExecutionContext *context) {
std::ostringstream oss;
if (dump_generator_.NextQuery(&oss)) {
return std::make_optional(std::vector<TypedValue>{oss.str()});
return std::make_optional(std::vector<TypedValue>{TypedValue(oss.str())});
}
return std::nullopt;
}
@ -222,7 +222,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
std::lock_guard<std::mutex> lock(auth->WithLock());
std::vector<std::vector<TypedValue>> users;
for (const auto &user : auth->AllUsers()) {
users.push_back({user.username()});
users.push_back({TypedValue(user.username())});
}
return users;
};
@ -233,7 +233,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
std::lock_guard<std::mutex> lock(auth->WithLock());
std::vector<std::vector<TypedValue>> roles;
for (const auto &role : auth->AllRoles()) {
roles.push_back({role.rolename()});
roles.push_back({TypedValue(role.rolename())});
}
return roles;
};
@ -351,9 +351,10 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
description.push_back("DENIED TO ROLE");
}
}
grants.push_back({auth::PermissionToString(permission),
auth::PermissionLevelToString(effective),
utils::Join(description, ", ")});
grants.push_back(
{TypedValue(auth::PermissionToString(permission)),
TypedValue(auth::PermissionLevelToString(effective)),
TypedValue(utils::Join(description, ", "))});
}
}
} else {
@ -368,9 +369,10 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
} else if (effective == auth::PermissionLevel::DENY) {
description = "DENIED TO ROLE";
}
grants.push_back({auth::PermissionToString(permission),
auth::PermissionLevelToString(effective),
description});
grants.push_back(
{TypedValue(auth::PermissionToString(permission)),
TypedValue(auth::PermissionLevelToString(effective)),
TypedValue(description)});
}
}
}
@ -386,7 +388,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
throw QueryRuntimeException("User '{}' doesn't exist .", username);
}
return std::vector<std::vector<TypedValue>>{std::vector<TypedValue>{
user->role() ? user->role()->rolename() : "null"}};
TypedValue(user->role() ? user->role()->rolename() : "null")}};
};
return callback;
case AuthQuery::Action::SHOW_USERS_FOR_ROLE:
@ -399,7 +401,8 @@ Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
}
std::vector<std::vector<TypedValue>> users;
for (const auto &user : auth->AllUsersForRole(rolename)) {
users.emplace_back(std::vector<TypedValue>{user.username()});
users.emplace_back(
std::vector<TypedValue>{TypedValue(user.username())});
}
return users;
};
@ -490,8 +493,9 @@ Callback HandleStreamQuery(StreamQuery *stream_query,
std::vector<std::vector<TypedValue>> status;
for (const auto &stream : streams->Show()) {
status.push_back(std::vector<TypedValue>{
stream.stream_name, stream.stream_uri, stream.stream_topic,
stream.transform_uri, stream.stream_status});
TypedValue(stream.stream_name), TypedValue(stream.stream_uri),
TypedValue(stream.stream_topic), TypedValue(stream.transform_uri),
TypedValue(stream.stream_status)});
}
return status;
};
@ -558,7 +562,8 @@ Callback HandleStreamQuery(StreamQuery *stream_query,
params.emplace(param.first, glue::ToTypedValue(param.second));
}
rows.emplace_back(std::vector<TypedValue>{result.first, params});
rows.emplace_back(std::vector<TypedValue>{TypedValue(result.first),
TypedValue(params)});
}
} catch (integrations::kafka::KafkaStreamException &e) {
throw QueryRuntimeException(e.what());
@ -629,7 +634,7 @@ Callback HandleInfoQuery(InfoQuery *info_query,
std::vector<std::vector<TypedValue>> results;
results.reserve(info.size());
for (const auto &pair : info) {
results.push_back({pair.first, pair.second});
results.push_back({TypedValue(pair.first), TypedValue(pair.second)});
}
return results;
};
@ -641,7 +646,9 @@ Callback HandleInfoQuery(InfoQuery *info_query,
results.reserve(info.size());
for (const auto &peer_info : info) {
for (const auto &pair : peer_info.second) {
results.push_back({peer_info.first, pair.first, pair.second});
results.push_back({TypedValue(peer_info.first),
TypedValue(pair.first),
TypedValue(pair.second)});
}
}
return results;
@ -657,7 +664,7 @@ Callback HandleInfoQuery(InfoQuery *info_query,
std::vector<std::vector<TypedValue>> results;
results.reserve(info.size());
for (const auto &index : info) {
results.push_back({index});
results.push_back({TypedValue(index)});
}
return results;
};
@ -674,9 +681,9 @@ Callback HandleInfoQuery(InfoQuery *info_query,
return db_accessor->PropertyName(p);
});
std::vector<TypedValue> constraint{TypedValue("unique"),
db_accessor->LabelName(e.label),
utils::Join(property_names, ",")};
std::vector<TypedValue> constraint{
TypedValue("unique"), TypedValue(db_accessor->LabelName(e.label)),
TypedValue(utils::Join(property_names, ","))};
results.emplace_back(constraint);
}
@ -878,7 +885,7 @@ Interpreter::Results Interpreter::operator()(
std::vector<std::vector<TypedValue>> printed_plan_rows;
for (const auto &row :
utils::Split(utils::RTrim(printed_plan.str()), "\n")) {
printed_plan_rows.push_back(std::vector<TypedValue>{row});
printed_plan_rows.push_back(std::vector<TypedValue>{TypedValue(row)});
}
summary["explain"] = PlanToJson(db_accessor, &cypher_query_plan->plan());

View File

@ -836,7 +836,7 @@ class ExpandVariableCursor : public Cursor {
if (diff > 0U)
edges_on_frame->erase(edges_on_frame->begin(),
edges_on_frame->begin() + diff);
edges_on_frame->insert(edges_on_frame->begin(), new_edge);
edges_on_frame->emplace(edges_on_frame->begin(), new_edge);
} else {
edges_on_frame->resize(
std::min(edges_on_frame->size(), edges_.size() - 1U));
@ -1291,7 +1291,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
to_visit_current_.pop_back();
// create the frame value for the edges
std::vector<TypedValue> edge_list{expansion.first};
std::vector<TypedValue> edge_list{TypedValue(expansion.first)};
auto last_vertex = expansion.second;
while (true) {
const EdgeAccessor &last_edge = edge_list.back().Value<EdgeAccessor>();
@ -1301,7 +1301,7 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
const auto &previous_edge = processed_.find(last_vertex)->second;
if (!previous_edge) break;
edge_list.push_back(previous_edge.value());
edge_list.emplace_back(previous_edge.value());
}
// expand only if what we've just expanded is less then max depth
@ -1509,13 +1509,13 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
? previous_edge->to()
: previous_edge->from();
last_depth--;
edge_list.push_back(previous_edge.value());
edge_list.emplace_back(previous_edge.value());
}
// Place destination node on the frame, handle existence flag.
if (self_.common_.existing_node) {
TypedValue &node = frame[self_.common_.node_symbol];
if ((node != current_vertex).Value<bool>())
if ((node != TypedValue(current_vertex)).Value<bool>())
continue;
else
// Prevent expanding other paths, because we found the

View File

@ -52,9 +52,10 @@ class ProfilingStatsToTableHelper {
auto cycles = IndividualCycles(cumulative_stats);
rows_.emplace_back(std::vector<TypedValue>{
FormatOperator(cumulative_stats.name),
TypedValue(cumulative_stats.actual_hits), FormatRelativeTime(cycles),
FormatAbsoluteTime(cycles)});
TypedValue(FormatOperator(cumulative_stats.name)),
TypedValue(cumulative_stats.actual_hits),
TypedValue(FormatRelativeTime(cycles)),
TypedValue(FormatAbsoluteTime(cycles))});
for (size_t i = 1; i < cumulative_stats.children.size(); ++i) {
Branch(cumulative_stats.children[i]);

View File

@ -45,9 +45,11 @@ class VertexCountCache {
const PropertyValue &value) {
auto label_prop = std::make_pair(label, property);
auto &value_vertex_count = property_value_vertex_count_[label_prop];
if (value_vertex_count.find(value) == value_vertex_count.end())
value_vertex_count[value] = db_->VerticesCount(label, property, value);
return value_vertex_count.at(value);
// TODO: Why do we even need TypedValue in this whole file?
TypedValue tv_value(value);
if (value_vertex_count.find(tv_value) == value_vertex_count.end())
value_vertex_count[tv_value] = db_->VerticesCount(label, property, value);
return value_vertex_count.at(tv_value);
}
int64_t VerticesCount(
@ -88,8 +90,8 @@ class VertexCountCache {
const auto &maybe_upper = key.second;
query::TypedValue lower;
query::TypedValue upper;
if (maybe_lower) lower = maybe_lower->value();
if (maybe_upper) upper = maybe_upper->value();
if (maybe_lower) lower = TypedValue(maybe_lower->value());
if (maybe_upper) upper = TypedValue(maybe_upper->value());
query::TypedValue::Hash hash;
return utils::HashCombine<size_t, size_t>{}(hash(lower), hash(upper));
}
@ -104,8 +106,8 @@ class VertexCountCache {
return false;
query::TypedValue bound_a;
query::TypedValue bound_b;
if (maybe_bound_a) bound_a = maybe_bound_a->value();
if (maybe_bound_b) bound_b = maybe_bound_b->value();
if (maybe_bound_a) bound_a = TypedValue(maybe_bound_a->value());
if (maybe_bound_b) bound_b = TypedValue(maybe_bound_b->value());
return query::TypedValue::BoolEqual{}(bound_a, bound_b);
};
return bound_equal(a.first, b.first) && bound_equal(a.second, b.second);

View File

@ -47,7 +47,7 @@ TypedValue::TypedValue(const PropertyValue &value,
const auto &vec = value.Value<std::vector<PropertyValue>>();
new (&list_v) TVector(memory_);
list_v.reserve(vec.size());
list_v.assign(vec.begin(), vec.end());
for (const auto &v : vec) list_v.emplace_back(v);
return;
}
case PropertyValue::Type::Map: {
@ -92,8 +92,7 @@ TypedValue::TypedValue(PropertyValue &&other, utils::MemoryResource *memory)
auto &vec = other.Value<std::vector<PropertyValue>>();
new (&list_v) TVector(memory_);
list_v.reserve(vec.size());
list_v.assign(std::make_move_iterator(vec.begin()),
std::make_move_iterator(vec.end()));
for (auto &v : vec) list_v.emplace_back(std::move(v));
break;
}
case PropertyValue::Type::Map: {
@ -349,9 +348,6 @@ DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(int, Int, int_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(bool, Bool, bool_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(int64_t, Int, int_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(double, Double, double_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const TypedValue::TString &, String,
string_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const std::string &, String, string_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const std::string_view &, String, string_v)
DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const TypedValue::TVector &, List, list_v)
@ -369,7 +365,12 @@ DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const TypedValue::TMap &, Map, map_v)
TypedValue &TypedValue::operator=(
const std::map<std::string, TypedValue> &other) {
*this = TypedValue(other, memory_);
if (type_ == Type::Map) {
map_v.clear();
for (const auto &kv : other) map_v.emplace(kv.first, kv.second);
} else {
*this = TypedValue(other, memory_);
}
return *this;
}
@ -387,7 +388,6 @@ DEFINE_TYPED_VALUE_COPY_ASSIGNMENT(const Path &, Path, path_v)
} else { \
*this = TypedValue(std::move(other), memory_); \
} \
\
return *this; \
}
@ -396,6 +396,7 @@ DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(TypedValue::TVector, List, list_v)
TypedValue &TypedValue::operator=(std::vector<TypedValue> &&other) {
if (type_ == Type::List) {
list_v.reserve(other.size());
list_v.assign(std::make_move_iterator(other.begin()),
std::make_move_iterator(other.end()));
} else {
@ -404,15 +405,18 @@ TypedValue &TypedValue::operator=(std::vector<TypedValue> &&other) {
return *this;
}
DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(TypedValue::TMap, Map, map_v)
DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(TMap, Map, map_v)
TypedValue &TypedValue::operator=(std::map<std::string, TypedValue> &&other) {
*this = TypedValue(std::move(other), memory_);
if (type_ == Type::Map) {
map_v.clear();
for (auto &kv : other) map_v.emplace(kv.first, std::move(kv.second));
} else {
*this = TypedValue(std::move(other), memory_);
}
return *this;
}
DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(VertexAccessor, Vertex, vertex_v)
DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(EdgeAccessor, Edge, edge_v)
DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT(Path, Path, path_v)
#undef DEFINE_TYPED_VALUE_MOVE_ASSIGNMENT

View File

@ -149,8 +149,8 @@ class TypedValue {
explicit operator PropertyValue() const;
// copy constructors for non-primitive types
TypedValue(const std::string &value,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(const std::string &value, utils::MemoryResource *memory =
utils::NewDeleteResource())
: memory_(memory), type_(Type::String) {
new (&string_v) TString(value, memory_);
}
@ -176,7 +176,7 @@ class TypedValue {
* Since we use utils::Allocator, which does not propagate, this means that
* memory_ will be the default utils::NewDeleteResource().
*/
TypedValue(const TString &other)
explicit TypedValue(const TString &other)
: TypedValue(other, std::allocator_traits<utils::Allocator<TypedValue>>::
select_on_container_copy_construction(
other.get_allocator())
@ -189,8 +189,9 @@ class TypedValue {
}
/** Construct a copy using the given utils::MemoryResource */
TypedValue(const std::vector<TypedValue> &value,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(
const std::vector<TypedValue> &value,
utils::MemoryResource *memory = utils::NewDeleteResource())
: memory_(memory), type_(Type::List) {
new (&list_v) TVector(memory_);
list_v.reserve(value.size());
@ -205,7 +206,7 @@ class TypedValue {
* Since we use utils::Allocator, which does not propagate, this means that
* memory_ will be the default utils::NewDeleteResource().
*/
TypedValue(const TVector &other)
explicit TypedValue(const TVector &other)
: TypedValue(other, std::allocator_traits<utils::Allocator<TypedValue>>::
select_on_container_copy_construction(
other.get_allocator())
@ -218,8 +219,9 @@ class TypedValue {
}
/** Construct a copy using the given utils::MemoryResource */
TypedValue(const std::map<std::string, TypedValue> &value,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(
const std::map<std::string, TypedValue> &value,
utils::MemoryResource *memory = utils::NewDeleteResource())
: memory_(memory), type_(Type::Map) {
new (&map_v) TMap(memory_);
for (const auto &kv : value) map_v.emplace(kv.first, kv.second);
@ -233,7 +235,7 @@ class TypedValue {
* Since we use utils::Allocator, which does not propagate, this means that
* memory_ will be the default utils::NewDeleteResource().
*/
TypedValue(const TMap &other)
explicit TypedValue(const TMap &other)
: TypedValue(other, std::allocator_traits<utils::Allocator<TypedValue>>::
select_on_container_copy_construction(
other.get_allocator())
@ -245,26 +247,27 @@ class TypedValue {
new (&map_v) TMap(value, memory_);
}
TypedValue(const VertexAccessor &vertex,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(
const VertexAccessor &vertex,
utils::MemoryResource *memory = utils::NewDeleteResource())
: memory_(memory), type_(Type::Vertex) {
new (&vertex_v) VertexAccessor(vertex);
}
TypedValue(const EdgeAccessor &edge,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(const EdgeAccessor &edge, utils::MemoryResource *memory =
utils::NewDeleteResource())
: memory_(memory), type_(Type::Edge) {
new (&edge_v) EdgeAccessor(edge);
}
TypedValue(const Path &path,
utils::MemoryResource *memory = utils::NewDeleteResource())
explicit TypedValue(const Path &path, utils::MemoryResource *memory =
utils::NewDeleteResource())
: memory_(memory), type_(Type::Path) {
new (&path_v) Path(path, memory_);
}
/** Construct a copy using default utils::NewDeleteResource() */
TypedValue(const PropertyValue &value);
explicit TypedValue(const PropertyValue &value);
/** Construct a copy using the given utils::MemoryResource */
TypedValue(const PropertyValue &value, utils::MemoryResource *memory);
@ -276,7 +279,7 @@ class TypedValue {
* utils::MemoryResource is obtained from other. After the move, other will be
* left in unspecified state.
*/
TypedValue(TString &&other) noexcept
explicit TypedValue(TString &&other) noexcept
: TypedValue(std::move(other),
other.get_allocator().GetMemoryResource()) {}
@ -293,7 +296,7 @@ class TypedValue {
* Perform an element-wise move using default utils::NewDeleteResource().
* Other will be not be empty, though elements may be Null.
*/
TypedValue(std::vector<TypedValue> &&other)
explicit TypedValue(std::vector<TypedValue> &&other)
: TypedValue(std::move(other), utils::NewDeleteResource()) {}
/**
@ -319,7 +322,7 @@ class TypedValue {
* utils::MemoryResource is obtained from other. After the move, other will be
* left empty.
*/
TypedValue(TVector &&other) noexcept
explicit TypedValue(TVector &&other) noexcept
: TypedValue(std::move(other),
other.get_allocator().GetMemoryResource()) {}
@ -338,7 +341,7 @@ class TypedValue {
* Other will not be left empty, i.e. keys will exist but their values may
* be Null.
*/
TypedValue(std::map<std::string, TypedValue> &&other)
explicit TypedValue(std::map<std::string, TypedValue> &&other)
: TypedValue(std::move(other), utils::NewDeleteResource()) {}
/**
@ -358,7 +361,7 @@ class TypedValue {
* utils::MemoryResource is obtained from other. After the move, other will be
* left empty.
*/
TypedValue(TMap &&other) noexcept
explicit TypedValue(TMap &&other) noexcept
: TypedValue(std::move(other),
other.get_allocator().GetMemoryResource()) {}
@ -373,20 +376,16 @@ class TypedValue {
new (&map_v) TMap(std::move(other), memory_);
}
TypedValue(VertexAccessor &&vertex) noexcept : type_(Type::Vertex) {
new (&vertex_v) VertexAccessor(std::move(vertex));
}
TypedValue(VertexAccessor &&vertex, utils::MemoryResource *memory) noexcept
explicit TypedValue(
VertexAccessor &&vertex,
utils::MemoryResource *memory = utils::NewDeleteResource()) noexcept
: memory_(memory), type_(Type::Vertex) {
new (&vertex_v) VertexAccessor(std::move(vertex));
}
TypedValue(EdgeAccessor &&edge) noexcept : type_(Type::Edge) {
new (&edge_v) EdgeAccessor(std::move(edge));
}
TypedValue(EdgeAccessor &&edge, utils::MemoryResource *memory) noexcept
explicit TypedValue(
EdgeAccessor &&edge,
utils::MemoryResource *memory = utils::NewDeleteResource()) noexcept
: memory_(memory), type_(Type::Edge) {
new (&edge_v) EdgeAccessor(std::move(edge));
}
@ -396,7 +395,7 @@ class TypedValue {
* utils::MemoryResource is obtained from path. After the move, path will be
* left empty.
*/
TypedValue(Path &&path) noexcept
explicit TypedValue(Path &&path) noexcept
: TypedValue(std::move(path), path.GetMemoryResource()) {}
/**
@ -414,8 +413,7 @@ class TypedValue {
* Default utils::NewDeleteResource() is used for allocations. After the move,
* other will be set to Null.
*/
// NOLINTNEXTLINE(hicpp-explicit-conversions)
TypedValue(PropertyValue &&other);
explicit TypedValue(PropertyValue &&other);
/**
* Construct with the value of other, but use the given utils::MemoryResource.
@ -429,8 +427,6 @@ class TypedValue {
TypedValue &operator=(bool);
TypedValue &operator=(int64_t);
TypedValue &operator=(double);
TypedValue &operator=(const TString &);
TypedValue &operator=(const std::string &);
TypedValue &operator=(const std::string_view &);
TypedValue &operator=(const TVector &);
TypedValue &operator=(const std::vector<TypedValue> &);
@ -443,19 +439,17 @@ class TypedValue {
/** Copy assign other, utils::MemoryResource of `this` is used */
TypedValue &operator=(const TypedValue &other);
/** Move assign other, utils::MemoryResource of `this` is used. */
TypedValue &operator=(TypedValue &&other) noexcept(false);
// move assignment operators
TypedValue &operator=(TString &&);
TypedValue &operator=(TVector &&);
TypedValue &operator=(std::vector<TypedValue> &&);
TypedValue &operator=(TMap &&);
TypedValue &operator=(std::map<std::string, TypedValue> &&);
TypedValue &operator=(VertexAccessor &&);
TypedValue &operator=(EdgeAccessor &&);
TypedValue &operator=(Path &&);
/** Move assign other, utils::MemoryResource of `this` is used. */
TypedValue &operator=(TypedValue &&other) noexcept(false);
~TypedValue();
Type type() const { return type_; }

View File

@ -158,7 +158,7 @@ static void ExpandVariable(benchmark::State &state) {
TMemory memory;
auto cursor = expand_variable.MakeCursor(&dba, memory.get());
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
frame[expand_variable.input_symbol_] = v;
frame[expand_variable.input_symbol_] = query::TypedValue(v);
while (cursor->Pull(frame, execution_context))
;
}
@ -194,7 +194,7 @@ static void ExpandBfs(benchmark::State &state) {
TMemory memory;
auto cursor = expand_variable.MakeCursor(&dba, memory.get());
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
frame[expand_variable.input_symbol_] = v;
frame[expand_variable.input_symbol_] = query::TypedValue(v);
while (cursor->Pull(frame, execution_context))
;
}
@ -232,9 +232,9 @@ static void ExpandShortest(benchmark::State &state) {
TMemory memory;
auto cursor = expand_variable.MakeCursor(&dba, memory.get());
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
frame[expand_variable.input_symbol_] = v;
frame[expand_variable.input_symbol_] = query::TypedValue(v);
for (const auto &dest : dba.Vertices(false)) {
frame[dest_symbol] = dest;
frame[dest_symbol] = query::TypedValue(dest);
while (cursor->Pull(frame, execution_context))
;
}
@ -403,7 +403,8 @@ static void Unwind(benchmark::State &state) {
query::plan::Unwind unwind(scan_all, list_expr, out_sym);
auto dba = db.Access();
query::Frame frame(symbol_table.max_position());
frame[list_sym] = std::vector<query::TypedValue>(state.range(1));
frame[list_sym] =
query::TypedValue(std::vector<query::TypedValue>(state.range(1)));
// Nothing should be used from the EvaluationContext, so leave it empty.
query::EvaluationContext evaluation_context;
while (state.KeepRunning()) {

View File

@ -169,14 +169,15 @@ class InteractiveDbAccessor {
return 0;
}
auto &value_vertex_count = property_value_vertex_count_[label_prop];
if (value_vertex_count.find(value) == value_vertex_count.end()) {
query::TypedValue tv_value(value);
if (value_vertex_count.find(tv_value) == value_vertex_count.end()) {
std::stringstream ss;
ss << value;
ss << tv_value;
int64_t count = ReadVertexCount("label '" + label + "' and property '" +
property + "' value '" + ss.str() + "'");
value_vertex_count[value] = count;
value_vertex_count[tv_value] = count;
}
return value_vertex_count.at(value);
return value_vertex_count.at(tv_value);
}
int64_t VerticesCount(

View File

@ -47,10 +47,11 @@ class Base {
TypedValue LiteralValue(Expression *expression) {
if (context_.is_query_cached) {
auto *param_lookup = dynamic_cast<ParameterLookup *>(expression);
return parameters_.AtTokenPosition(param_lookup->token_position_);
return TypedValue(
parameters_.AtTokenPosition(param_lookup->token_position_));
} else {
auto *literal = dynamic_cast<PrimitiveLiteral *>(expression);
return literal->value_;
return TypedValue(literal->value_);
}
}
@ -65,12 +66,13 @@ class Base {
ASSERT_TRUE(param_lookup);
if (token_position)
EXPECT_EQ(param_lookup->token_position_, *token_position);
value = parameters_.AtTokenPosition(param_lookup->token_position_);
value = TypedValue(
parameters_.AtTokenPosition(param_lookup->token_position_));
} else {
auto *literal = dynamic_cast<PrimitiveLiteral *>(expression);
ASSERT_TRUE(literal);
if (token_position) ASSERT_EQ(literal->token_position_, *token_position);
value = literal->value_;
value = TypedValue(literal->value_);
}
EXPECT_TRUE(TypedValue::BoolEqual{}(value, expected_tv));
}

View File

@ -234,8 +234,8 @@ std::unique_ptr<query::plan::LogicalOperator> YieldVertices(
std::vector<std::vector<query::TypedValue>> frames;
frames.push_back(std::vector<query::TypedValue>{query::TypedValue()});
for (const auto &vertex : vertices) {
frames.push_back(
std::vector<query::TypedValue>{VertexAccessor(vertex, *dba)});
frames.emplace_back(std::vector<query::TypedValue>{
query::TypedValue(VertexAccessor(vertex, *dba))});
}
return std::make_unique<Yield>(input_op, std::vector<query::Symbol>{symbol},
frames);
@ -248,11 +248,12 @@ std::unique_ptr<query::plan::LogicalOperator> YieldEntities(
std::shared_ptr<query::plan::LogicalOperator> input_op) {
std::vector<std::vector<query::TypedValue>> frames;
for (const auto &vertex : vertices) {
frames.push_back(
std::vector<query::TypedValue>{VertexAccessor(vertex, *dba)});
frames.emplace_back(std::vector<query::TypedValue>{
query::TypedValue(VertexAccessor(vertex, *dba))});
}
for (const auto &edge : edges) {
frames.push_back(std::vector<query::TypedValue>{EdgeAccessor(edge, *dba)});
frames.emplace_back(std::vector<query::TypedValue>{
query::TypedValue(EdgeAccessor(edge, *dba))});
}
return std::make_unique<Yield>(input_op, std::vector<query::Symbol>{symbol},
frames);
@ -370,7 +371,7 @@ void BfsTest(Database *db, int lower_bound, int upper_bound,
input_op = std::make_shared<Yield>(
nullptr, std::vector<query::Symbol>{blocked_sym},
std::vector<std::vector<query::TypedValue>>{
{VertexAccessor(vertices[5], *dba_ptr)}});
{query::TypedValue(VertexAccessor(vertices[5], *dba_ptr))}});
filter_expr = NEQ(PROPERTY_LOOKUP(inner_node, PROPERTY_PAIR("id")),
PARAMETER_LOOKUP(0));
context.evaluation_context.parameters.Add(0, 5);

View File

@ -189,9 +189,9 @@ TEST(BoltEncoder, VertexAndEdge) {
// check everything
std::vector<Value> vals;
vals.push_back(glue::ToBoltValue(va1));
vals.push_back(glue::ToBoltValue(va2));
vals.push_back(glue::ToBoltValue(ea));
vals.push_back(glue::ToBoltValue(query::TypedValue(va1)));
vals.push_back(glue::ToBoltValue(query::TypedValue(va2)));
vals.push_back(glue::ToBoltValue(query::TypedValue(ea)));
bolt_encoder.MessageRecord(vals);
// The vertexedge_encoded testdata has hardcoded zeros for IDs,

View File

@ -43,10 +43,11 @@ class Base {
TypedValue LiteralValue(Expression *expression) {
if (context_.is_query_cached) {
auto *param_lookup = dynamic_cast<ParameterLookup *>(expression);
return parameters_.AtTokenPosition(param_lookup->token_position_);
return TypedValue(
parameters_.AtTokenPosition(param_lookup->token_position_));
} else {
auto *literal = dynamic_cast<PrimitiveLiteral *>(expression);
return literal->value_;
return TypedValue(literal->value_);
}
}
@ -61,12 +62,13 @@ class Base {
ASSERT_TRUE(param_lookup);
if (token_position)
EXPECT_EQ(param_lookup->token_position_, *token_position);
value = parameters_.AtTokenPosition(param_lookup->token_position_);
value = TypedValue(
parameters_.AtTokenPosition(param_lookup->token_position_));
} else {
auto *literal = dynamic_cast<PrimitiveLiteral *>(expression);
ASSERT_TRUE(literal);
if (token_position) ASSERT_EQ(literal->token_position_, *token_position);
value = literal->value_;
value = TypedValue(literal->value_);
}
EXPECT_TRUE(TypedValue::BoolEqual{}(value, expected_tv));
}

View File

@ -417,8 +417,9 @@ class DistributedEdgeCreateTest : public DistributedGraphDbTest {
EXPECT_EQ(edge.Properties().size(), props.size());
for (auto &kv : props) {
auto equality = edge.PropsAt(dba->Property(kv.first)) ==
query::TypedValue(kv.second);
auto equality =
query::TypedValue(edge.PropsAt(dba->Property(kv.first))) ==
query::TypedValue(kv.second);
EXPECT_TRUE(equality.IsBool() && equality.ValueBool());
}
}

View File

@ -208,8 +208,8 @@ void CompareDbs(database::GraphDb &a, database::GraphDb &b) {
std::vector<std::pair<std::string, query::TypedValue>> p1;
std::vector<std::pair<std::string, query::TypedValue>> p2;
for (auto x : p1_id) p1.push_back({dba_a.PropertyName(x.first), x.second});
for (auto x : p2_id) p2.push_back({dba_b.PropertyName(x.first), x.second});
for (auto x : p1_id) p1.emplace_back(dba_a.PropertyName(x.first), x.second);
for (auto x : p2_id) p2.emplace_back(dba_b.PropertyName(x.first), x.second);
// Don't use a binary predicate which depends on different value getters
// semantics for two containers because is_permutation might call the

View File

@ -115,12 +115,12 @@ TEST_F(InterpreterTest, Parameters) {
}
{
// Non-primitive literal.
auto stream = Interpret("RETURN $2",
{{"2", std::vector<PropertyValue>{5, 2, 3}}});
auto stream =
Interpret("RETURN $2", {{"2", std::vector<PropertyValue>{5, 2, 3}}});
ASSERT_EQ(stream.GetResults().size(), 1U);
ASSERT_EQ(stream.GetResults()[0].size(), 1U);
auto result = query::test_common::ToList<int64_t>(
stream.GetResults()[0][0].ValueList());
auto result =
query::test_common::ToList<int64_t>(stream.GetResults()[0][0]);
ASSERT_THAT(result, testing::ElementsAre(5, 2, 3));
}
{
@ -218,8 +218,7 @@ TEST_F(InterpreterTest, Bfs) {
std::unordered_set<int64_t> matched_ids;
for (const auto &result : stream.GetResults()) {
const auto &edges =
query::test_common::ToList<EdgeAccessor>(result[0].ValueList());
const auto &edges = query::test_common::ToList<EdgeAccessor>(result[0]);
// Check that path is of expected length. Returned paths should be from
// shorter to longer ones.
EXPECT_EQ(edges.size(), expected_level);
@ -284,8 +283,7 @@ TEST_F(InterpreterTest, ShortestPath) {
{"r1"}, {"r2"}, {"r1", "r2"}};
for (const auto &result : stream.GetResults()) {
const auto &edges =
query::test_common::ToList<EdgeAccessor>(result[0].ValueList());
const auto &edges = query::test_common::ToList<EdgeAccessor>(result[0]);
std::vector<std::string> datum;
for (const auto &edge : edges) {

View File

@ -417,8 +417,8 @@ TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) {
v1.PropsSet(prop, 42);
e11.PropsSet(prop, 43);
auto *vertex_id = CreateIdentifierWithValue("v1", v1);
auto *edge_id = CreateIdentifierWithValue("e11", e11);
auto *vertex_id = CreateIdentifierWithValue("v1", TypedValue(v1));
auto *edge_id = CreateIdentifierWithValue("e11", TypedValue(e11));
{
// Legal indexing.
auto *op1 = storage.Create<SubscriptOperator>(
@ -631,7 +631,7 @@ TEST_F(ExpressionEvaluatorTest, LabelsTest) {
auto *identifier = storage.Create<Identifier>("n");
auto node_symbol = symbol_table.CreateSymbol("n", true);
identifier->MapTo(node_symbol);
frame[node_symbol] = v1;
frame[node_symbol] = TypedValue(v1);
{
auto *op = storage.Create<LabelsTest>(
identifier, std::vector<LabelIx>{storage.GetLabelIx("DOG"),
@ -911,7 +911,7 @@ class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
auto v1 = dba.InsertVertex();
v1.PropsSet(prop_age.second, 10);
frame[symbol] = v1;
frame[symbol] = TypedValue(v1);
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
EXPECT_TRUE(Value(prop_height).IsNull());
}
@ -921,7 +921,7 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {
auto v2 = dba.InsertVertex();
auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("edge_type"));
e12.PropsSet(prop_age.second, 10);
frame[symbol] = e12;
frame[symbol] = TypedValue(e12);
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
EXPECT_TRUE(Value(prop_height).IsNull());
}
@ -932,8 +932,8 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Null) {
}
TEST_F(ExpressionEvaluatorPropertyLookup, MapLiteral) {
frame[symbol] =
std::map<std::string, TypedValue>{{prop_age.first, TypedValue(10)}};
frame[symbol] = TypedValue(
std::map<std::string, TypedValue>{{prop_age.first, TypedValue(10)}});
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
EXPECT_TRUE(Value(prop_height).IsNull());
}

View File

@ -334,8 +334,11 @@ TEST(QueryPlan, AggregateGroupByValues) {
result_group_bys.insert(row[1]);
}
ASSERT_EQ(result_group_bys.size(), group_by_vals.size() - 2);
std::vector<TypedValue> group_by_tvals;
group_by_tvals.reserve(group_by_vals.size());
for (const auto &v : group_by_vals) group_by_tvals.emplace_back(v);
EXPECT_TRUE(
std::is_permutation(group_by_vals.begin(), group_by_vals.end() - 2,
std::is_permutation(group_by_tvals.begin(), group_by_tvals.end() - 2,
result_group_bys.begin(), TypedValue::BoolEqual{}));
}

View File

@ -125,7 +125,9 @@ TEST(QueryPlan, OrderBy) {
{Ordering::DESC, {Null, "zorro", "borro"}}};
for (const auto &order_value_pair : orderable) {
const auto &values = order_value_pair.second;
std::vector<TypedValue> values;
values.reserve(order_value_pair.second.size());
for (const auto &v : order_value_pair.second) values.emplace_back(v);
// empty database
for (auto &vertex : dba.Vertices(false)) dba.DetachRemoveVertex(vertex);
dba.AdvanceCommand();
@ -134,7 +136,7 @@ TEST(QueryPlan, OrderBy) {
// take some effort to shuffle the values
// because we are testing that something not ordered gets ordered
// and need to take care it does not happen by accident
std::vector<PropertyValue> shuffled(values.begin(), values.end());
auto shuffled = values;
auto order_equal = [&values, &shuffled]() {
return std::equal(values.begin(), values.end(), shuffled.begin(),
TypedValue::BoolEqual{});
@ -145,7 +147,8 @@ TEST(QueryPlan, OrderBy) {
ASSERT_FALSE(order_equal());
// create the vertices
for (const auto &value : shuffled) dba.InsertVertex().PropsSet(prop, value);
for (const auto &value : shuffled)
dba.InsertVertex().PropsSet(prop, PropertyValue(value));
dba.AdvanceCommand();
// order by and collect results

View File

@ -43,7 +43,8 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
EXPECT_EQ(vertex.labels().size(), 1);
EXPECT_EQ(*vertex.labels().begin(), label);
EXPECT_EQ(vertex.Properties().size(), 1);
auto prop_eq = vertex.PropsAt(property.second) == TypedValue(42);
auto prop_eq =
TypedValue(vertex.PropsAt(property.second)) == TypedValue(42);
ASSERT_EQ(prop_eq.type(), TypedValue::Type::Bool);
EXPECT_TRUE(prop_eq.Value<bool>());
}
@ -717,7 +718,7 @@ TEST(QueryPlan, NodeFilterSet) {
EXPECT_EQ(2, PullAll(*set, &context));
dba.AdvanceCommand();
v1.Reconstruct();
auto prop_eq = v1.PropsAt(prop.second) == TypedValue(42 + 2);
auto prop_eq = TypedValue(v1.PropsAt(prop.second)) == TypedValue(42 + 2);
ASSERT_EQ(prop_eq.type(), TypedValue::Type::Bool);
EXPECT_TRUE(prop_eq.Value<bool>());
}

View File

@ -775,8 +775,7 @@ TEST_F(QueryPlanExpandVariable, NamedPath) {
auto results = GetResults<query::Path>(create_path, path_symbol);
ASSERT_EQ(results.size(), 8);
EXPECT_TRUE(std::is_permutation(results.begin(), results.end(),
expected_paths.begin(),
TypedValue::BoolEqual{}));
expected_paths.begin()));
}
namespace std {
@ -1627,7 +1626,8 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
ASSERT_EQ(results.size(), expected.size());
for (size_t i = 0; i < expected.size(); i++) {
TypedValue equal =
results[i][0].Value<VertexAccessor>().PropsAt(prop) == expected[i];
TypedValue(results[i][0].Value<VertexAccessor>().PropsAt(prop)) ==
expected[i];
ASSERT_EQ(equal.type(), TypedValue::Type::Bool);
EXPECT_TRUE(equal.Value<bool>());
}
@ -1645,8 +1645,10 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
{TypedValue(0.5), TypedValue(1), TypedValue(1.5), TypedValue(2)});
check(TypedValue(1.5), Bound::Type::EXCLUSIVE, TypedValue(2.5),
Bound::Type::INCLUSIVE, {TypedValue(2), TypedValue(2.5)});
check(std::vector<TypedValue>{TypedValue(0.5)}, Bound::Type::EXCLUSIVE,
std::vector<TypedValue>{TypedValue(1.5)}, Bound::Type::INCLUSIVE,
check(TypedValue(std::vector<TypedValue>{TypedValue(0.5)}),
Bound::Type::EXCLUSIVE,
TypedValue(std::vector<TypedValue>{TypedValue(1.5)}),
Bound::Type::INCLUSIVE,
{TypedValue(std::vector<TypedValue>{TypedValue(1)})});
// when a range contains different types, nothing should get returned
@ -1656,8 +1658,8 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
static_cast<PropertyValue>(value_a).type(),
static_cast<PropertyValue>(value_b).type()))
continue;
check(value_a, Bound::Type::INCLUSIVE, value_b, Bound::Type::INCLUSIVE,
{});
check(TypedValue(value_a), Bound::Type::INCLUSIVE, TypedValue(value_b),
Bound::Type::INCLUSIVE, {});
}
}
@ -1695,7 +1697,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
const auto &row = results[0];
ASSERT_EQ(row.size(), 1);
auto vertex = row[0].Value<VertexAccessor>();
auto value = vertex.PropsAt(prop);
TypedValue value(vertex.PropsAt(prop));
TypedValue::BoolEqual eq;
EXPECT_TRUE(eq(value, TypedValue(42)));
}

View File

@ -94,7 +94,7 @@ TEST(TestVariableStartPlanner, MatchReturn) {
// We have 2 nodes `n` and `m` from which we could start, so expect 2 plans.
CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
// We expect to produce only a single (v1) node.
AssertRows(results, {{v1}});
AssertRows(results, {{TypedValue(v1)}});
});
}
@ -118,7 +118,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
// We have 3 nodes: `n`, `m` and `l` from which we could start.
CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
// We expect to produce only a single (v1) node.
AssertRows(results, {{v1}});
AssertRows(results, {{TypedValue(v1)}});
});
}
{
@ -129,7 +129,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
PATTERN(NODE("m"), EDGE("e", Direction::OUT), NODE("l"))),
RETURN("n")));
CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{v1}});
AssertRows(results, {{TypedValue(v1)}});
});
}
}
@ -156,7 +156,8 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
// We expect to produce 2 rows:
// * (v1), (v3)
// * (v2), null
AssertRows(results, {{v1, v3}, {v2, TypedValue()}});
AssertRows(results, {{TypedValue(v1), TypedValue(v3)},
{TypedValue(v2), TypedValue()}});
});
}
@ -183,7 +184,8 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
// start, we generate 2 * 2 * 2 plans.
CheckPlansProduce(8, query, storage, &dba, [&](const auto &results) {
// We expect to produce a single row: (v1), (v2), null, (v1), (v2)
AssertRows(results, {{v1, v2, TypedValue(), v1, v2}});
AssertRows(results, {{TypedValue(v1), TypedValue(v2), TypedValue(),
TypedValue(v1), TypedValue(v2)}});
});
}
@ -206,7 +208,7 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
// we expect to get 2 plans for each, which totals 2 * 2.
CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
// We expect to produce a single row: (v1), (v1), (v2)
AssertRows(results, {{v1, v1, v2}});
AssertRows(results, {{TypedValue(v1), TypedValue(v1), TypedValue(v2)}});
});
}
@ -226,9 +228,11 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("r")));
// We expect to get a single column with the following rows:
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
TypedValue r2_list(std::vector<TypedValue>{r2}); // [r2]
TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2]
TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)}); // [r1]
TypedValue r2_list(std::vector<TypedValue>{TypedValue(r2)}); // [r2]
// [r1, r2]
TypedValue r1_r2_list(
std::vector<TypedValue>{TypedValue(r1), TypedValue(r2)});
CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}, {r2_list}, {r1_r2_list}});
});
@ -255,8 +259,10 @@ TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), edge, NODE("m"))), RETURN("r")));
// We expect to get a single column with the following rows:
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1] (v1 -[*..1]-> v2)
TypedValue r2_list(std::vector<TypedValue>{r2}); // [r2] (v2 -[*..2]-> v3)
// [r1] (v1 -[*..1]-> v2)
TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)});
// [r2] (v2 -[*..2]-> v3)
TypedValue r2_list(std::vector<TypedValue>{TypedValue(r2)});
CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}, {r2_list}});
});
@ -282,8 +288,10 @@ TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
auto *query =
QUERY(SINGLE_QUERY(MATCH(PATTERN(node_n, edge, NODE("m"))), RETURN("r")));
// We expect to get a single column with the following rows:
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2]
TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)}); // [r1]
// [r1, r2]
TypedValue r1_r2_list(
std::vector<TypedValue>{TypedValue(r1), TypedValue(r2)});
CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}, {r1_r2_list}});
});
@ -315,7 +323,7 @@ TEST(TestVariableStartPlanner, MatchBfs) {
auto *query = QUERY(
SINGLE_QUERY(MATCH(PATTERN(NODE("n"), bfs, NODE("m"))), RETURN("r")));
// We expect to get a single column with the following rows:
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
TypedValue r1_list(std::vector<TypedValue>{TypedValue(r1)}); // [r1]
CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}});
});

View File

@ -24,6 +24,10 @@ void EXPECT_PROP_EQ(const TypedValue &a, const TypedValue &b) {
EXPECT_PROP_TRUE(a == b);
}
void EXPECT_PROP_EQ(const PropertyValue &a, const TypedValue &b) {
EXPECT_PROP_EQ(TypedValue(a), b);
}
TEST(QueryStripper, NoLiterals) {
StrippedQuery stripped("CREATE (n)");
EXPECT_EQ(stripped.literals().size(), 0);

View File

@ -329,9 +329,9 @@ TEST_F(TypedValueArithmeticTest, Sum) {
std::vector<TypedValue> out3{
TypedValue(1), TypedValue(2), TypedValue(true), TypedValue("a"),
TypedValue(1), TypedValue(2), TypedValue(true), TypedValue("a")};
EXPECT_PROP_EQ((TypedValue(2) + TypedValue(in)).ValueList(), out1);
EXPECT_PROP_EQ((TypedValue(in) + TypedValue(2)).ValueList(), out2);
EXPECT_PROP_EQ((TypedValue(in) + TypedValue(in)).ValueList(), out3);
EXPECT_PROP_EQ(TypedValue(2) + TypedValue(in), TypedValue(out1));
EXPECT_PROP_EQ(TypedValue(in) + TypedValue(2), TypedValue(out2));
EXPECT_PROP_EQ(TypedValue(in) + TypedValue(in), TypedValue(out3));
}
TEST_F(TypedValueArithmeticTest, Difference) {