Skip to content

Commit

Permalink
fix(interactive): Support multiple properties edge expand (alibaba#4115)
Browse files Browse the repository at this point in the history
Support multiple properties edge expand for adhoc queries
  • Loading branch information
liulx20 authored Aug 8, 2024
1 parent 33ce51d commit eb3f086
Show file tree
Hide file tree
Showing 13 changed files with 554 additions and 71 deletions.
15 changes: 15 additions & 0 deletions flex/engines/graph_db/runtime/adhoc/expr_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ RTAny LogicalExpr::eval_vertex(label_t label, vid_t v, size_t idx) const {
std::string rhs(rhs_->eval_vertex(label, v, idx).as_string());
return RTAny::from_bool(std::regex_match(ret, std::regex(rhs)));

} else if (logic_ == common::Logical::OR) {
bool ret = (rhs_->eval_vertex(label, v, idx).as_bool() ||
lhs_->eval_vertex(label, v, idx).as_bool());
return RTAny::from_bool(ret);
} else {
LOG(FATAL) << "not support..." << static_cast<int>(logic_);
}
Expand Down Expand Up @@ -155,6 +159,14 @@ RTAny LogicalExpr::eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() &&
lhs_->eval_edge(label, src, dst, data, idx).as_bool());
return RTAny::from_bool(ret);
} else if (logic_ == common::Logical::REGEX) {
std::string ret(lhs_->eval_edge(label, src, dst, data, idx).as_string());
std::string rhs(rhs_->eval_edge(label, src, dst, data, idx).as_string());
return RTAny::from_bool(std::regex_match(ret, std::regex(rhs)));
} else if (logic_ == common::Logical::OR) {
bool ret = (rhs_->eval_edge(label, src, dst, data, idx).as_bool() ||
lhs_->eval_edge(label, src, dst, data, idx).as_bool());
return RTAny::from_bool(ret);
} else {
LOG(FATAL) << "not support..." << static_cast<int>(logic_);
}
Expand Down Expand Up @@ -538,6 +550,9 @@ static std::unique_ptr<ExprBase> build_expr(
} else if (key->type() == RTAnyType::kI32Value) {
return std::make_unique<WithInExpr<int32_t>>(txn, ctx, std::move(key),
rhs.const_());
} else if (key->type() == RTAnyType::kStringValue) {
return std::make_unique<WithInExpr<std::string>>(
txn, ctx, std::move(key), rhs.const_());
} else {
LOG(FATAL) << "not support";
}
Expand Down
50 changes: 37 additions & 13 deletions flex/engines/graph_db/runtime/adhoc/expr_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,45 +97,69 @@ class WithInExpr : public ExprBase {
for (size_t idx = 0; idx < len; ++idx) {
container_.push_back(array.i32_array().item(idx));
}
} else if constexpr (std::is_same_v<T, std::string>) {
CHECK(array.item_case() == common::Value::kStrArray);
size_t len = array.str_array().item_size();
for (size_t idx = 0; idx < len; ++idx) {
container_.push_back(array.str_array().item(idx));
}
} else {
LOG(FATAL) << "not implemented";
}
}

RTAny eval_path(size_t idx) const override {
auto val = TypedConverter<T>::to_typed(key_->eval_path(idx));
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
if constexpr (std::is_same_v<T, std::string>) {
auto val = std::string(key_->eval_path(idx).as_string());
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
} else {
auto val = TypedConverter<T>::to_typed(key_->eval_path(idx));
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
}
}

RTAny eval_path(size_t idx, int) const override {
auto any_val = key_->eval_path(idx, 0);
if (any_val.is_null()) {
return RTAny::from_bool(false);
}
auto val = TypedConverter<T>::to_typed(any_val);
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
return eval_path(idx);
}
RTAny eval_vertex(label_t label, vid_t v, size_t idx) const override {
auto val = TypedConverter<T>::to_typed(key_->eval_vertex(label, v, idx));
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
if constexpr (std::is_same_v<T, std::string>) {
auto val = std::string(key_->eval_vertex(label, v, idx).as_string());
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
} else {
auto val = TypedConverter<T>::to_typed(key_->eval_vertex(label, v, idx));
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
}
}

RTAny eval_vertex(label_t label, vid_t v, size_t idx, int) const override {
auto any_val = key_->eval_vertex(label, v, idx, 0);
if (any_val.is_null()) {
return RTAny::from_bool(false);
}
auto val = TypedConverter<T>::to_typed(any_val);
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
return eval_vertex(label, v, idx);
}

RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
const Any& data, size_t idx) const override {
LOG(FATAL) << "not implemented";
if constexpr (std::is_same_v<T, std::string>) {
auto val =
std::string(key_->eval_edge(label, src, dst, data, idx).as_string());
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
} else {
auto val = TypedConverter<T>::to_typed(
key_->eval_edge(label, src, dst, data, idx));
return RTAny::from_bool(std::find(container_.begin(), container_.end(),
val) != container_.end());
}
return RTAny::from_bool(false);
}
RTAnyType type() const override { return RTAnyType::kBoolValue; }
Expand Down
7 changes: 5 additions & 2 deletions flex/engines/graph_db/runtime/adhoc/var.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ Var::Var(const ReadTransaction& txn, const Context& ctx,
if (pb.has_property()) {
auto& pt = pb.property();
if (pt.has_key()) {
getter_ = create_edge_property_path_accessor(ctx, tag, type_);
auto name = pt.key().name();
getter_ =
create_edge_property_path_accessor(txn, name, ctx, tag, type_);
} else if (pt.has_label()) {
getter_ = create_edge_label_path_accessor(ctx, tag);
} else {
Expand Down Expand Up @@ -125,7 +127,8 @@ Var::Var(const ReadTransaction& txn, const Context& ctx,
if (pb.has_property()) {
auto& pt = pb.property();
if (pt.has_key()) {
getter_ = create_edge_property_edge_accessor(type_);
auto name = pt.key().name();
getter_ = create_edge_property_edge_accessor(txn, name, type_);
} else {
LOG(FATAL) << "not support";
}
Expand Down
142 changes: 109 additions & 33 deletions flex/engines/graph_db/runtime/common/accessors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,68 @@ std::shared_ptr<IAccessor> create_vertex_property_vertex_accessor(
}

std::shared_ptr<IAccessor> create_edge_property_path_accessor(
const Context& ctx, int tag, RTAnyType type) {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<EdgePropertyPathAccessor<int64_t>>(ctx, tag);
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<EdgePropertyPathAccessor<int>>(ctx, tag);
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<EdgePropertyPathAccessor<uint64_t>>(ctx, tag);
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<EdgePropertyPathAccessor<std::string_view>>(ctx,
tag);
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<EdgePropertyPathAccessor<Date>>(ctx, tag);
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<EdgePropertyPathAccessor<double>>(ctx, tag);
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
const ReadTransaction& txn, const std::string& name, const Context& ctx,
int tag, RTAnyType type) {
auto col = std::dynamic_pointer_cast<IEdgeColumn>(ctx.get(tag));
const auto& labels = col->get_labels();
bool multip_properties = false;
if (txn.schema().has_multi_props_edge()) {
for (auto label : labels) {
auto& properties = txn.schema().get_edge_properties(
label.src_label, label.dst_label, label.edge_label);
if (properties.size() > 1) {
multip_properties = true;
break;
}
}
}
if (multip_properties) {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<MultiPropsEdgePropertyPathAccessor<int64_t>>(
txn, name, ctx, tag);
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<MultiPropsEdgePropertyPathAccessor<int>>(
txn, name, ctx, tag);
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<MultiPropsEdgePropertyPathAccessor<uint64_t>>(
txn, name, ctx, tag);
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<
MultiPropsEdgePropertyPathAccessor<std::string_view>>(txn, name, ctx,
tag);
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<MultiPropsEdgePropertyPathAccessor<Date>>(
txn, name, ctx, tag);
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<MultiPropsEdgePropertyPathAccessor<double>>(
txn, name, ctx, tag);
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
}
} else {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<EdgePropertyPathAccessor<int64_t>>(txn, name, ctx,
tag);
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<EdgePropertyPathAccessor<int>>(txn, name, ctx,
tag);
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<EdgePropertyPathAccessor<uint64_t>>(txn, name,
ctx, tag);
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<EdgePropertyPathAccessor<std::string_view>>(
txn, name, ctx, tag);
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<EdgePropertyPathAccessor<Date>>(txn, name, ctx,
tag);
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<EdgePropertyPathAccessor<double>>(txn, name, ctx,
tag);
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
}
}
return nullptr;
}
Expand All @@ -130,22 +175,53 @@ std::shared_ptr<IAccessor> create_edge_label_path_accessor(const Context& ctx,
return std::make_shared<EdgeLabelPathAccessor>(ctx, tag);
}

std::shared_ptr<IAccessor> create_edge_property_edge_accessor(RTAnyType type) {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<EdgePropertyEdgeAccessor<int64_t>>();
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<EdgePropertyEdgeAccessor<int>>();
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<EdgePropertyEdgeAccessor<uint64_t>>();
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<EdgePropertyEdgeAccessor<std::string_view>>();
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<EdgePropertyEdgeAccessor<Date>>();
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<EdgePropertyEdgeAccessor<double>>();
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
std::shared_ptr<IAccessor> create_edge_property_edge_accessor(
const ReadTransaction& txn, const std::string& prop_name, RTAnyType type) {
bool multip_properties = txn.schema().has_multi_props_edge();

if (multip_properties) {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<MultiPropsEdgePropertyEdgeAccessor<int64_t>>(
txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<MultiPropsEdgePropertyEdgeAccessor<int>>(
txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<MultiPropsEdgePropertyEdgeAccessor<uint64_t>>(
txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<
MultiPropsEdgePropertyEdgeAccessor<std::string_view>>(txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<MultiPropsEdgePropertyEdgeAccessor<Date>>(
txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<MultiPropsEdgePropertyEdgeAccessor<double>>(
txn, prop_name);
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
}
} else {
switch (type.type_enum_) {
case RTAnyType::RTAnyTypeImpl::kI64Value:
return std::make_shared<EdgePropertyEdgeAccessor<int64_t>>(txn,
prop_name);
case RTAnyType::RTAnyTypeImpl::kI32Value:
return std::make_shared<EdgePropertyEdgeAccessor<int>>(txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kU64Value:
return std::make_shared<EdgePropertyEdgeAccessor<uint64_t>>(txn,
prop_name);
case RTAnyType::RTAnyTypeImpl::kStringValue:
return std::make_shared<EdgePropertyEdgeAccessor<std::string_view>>(
txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kDate32:
return std::make_shared<EdgePropertyEdgeAccessor<Date>>(txn, prop_name);
case RTAnyType::RTAnyTypeImpl::kF64Value:
return std::make_shared<EdgePropertyEdgeAccessor<double>>(txn, prop_name);
default:
LOG(FATAL) << "not implemented - " << static_cast<int>(type.type_enum_);
}
}
return nullptr;
}
Expand Down
Loading

0 comments on commit eb3f086

Please sign in to comment.