Skip to content

Commit

Permalink
fix(interactive): Support more cases for var in expression (#4230)
Browse files Browse the repository at this point in the history
As titled.

Fix #4226
  • Loading branch information
zhanglei1949 authored Sep 18, 2024
1 parent 1130f91 commit a4dab02
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 8 deletions.
9 changes: 8 additions & 1 deletion flex/engines/graph_db/runtime/adhoc/var.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Var::Var(const ReadTransaction& txn, const Context& ctx,
tag = pb.tag().id();
CHECK(ctx.get(tag) != nullptr);
type_ = ctx.get(tag)->elem_type();
} else if (pb.has_property() && pb.property().has_label()) {
} else if (pb.has_property() &&
(pb.property().has_label() || pb.property().has_id())) {
type_ = RTAnyType::kI64Value;
} else {
LOG(FATAL) << "not support";
Expand Down Expand Up @@ -95,6 +96,8 @@ Var::Var(const ReadTransaction& txn, const Context& ctx,
create_edge_property_path_accessor(txn, name, ctx, tag, type_);
} else if (pt.has_label()) {
getter_ = create_edge_label_path_accessor(ctx, tag);
} else if (pt.has_id()) {
getter_ = create_edge_global_id_path_accessor(ctx, tag);
} else {
LOG(FATAL) << "not support...";
}
Expand Down Expand Up @@ -154,6 +157,10 @@ Var::Var(const ReadTransaction& txn, const Context& ctx,
if (pt.has_key()) {
auto name = pt.key().name();
getter_ = create_edge_property_edge_accessor(txn, name, type_);
} else if (pt.has_label()) {
getter_ = create_edge_label_edge_accessor();
} else if (pt.has_id()) {
getter_ = create_edge_global_id_edge_accessor();
} else {
LOG(FATAL) << "not support";
}
Expand Down
13 changes: 13 additions & 0 deletions flex/engines/graph_db/runtime/common/accessors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,19 @@ 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_label_edge_accessor() {
return std::make_shared<EdgeLabelEdgeAccessor>();
}

std::shared_ptr<IAccessor> create_edge_global_id_path_accessor(
const Context& ctx, int tag) {
return std::make_shared<EdgeGlobalIdPathAccessor>(ctx, tag);
}

std::shared_ptr<IAccessor> create_edge_global_id_edge_accessor() {
return std::make_shared<EdgeGlobalIdEdgeAccessor>();
}

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();
Expand Down
118 changes: 118 additions & 0 deletions flex/engines/graph_db/runtime/common/accessors.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,27 @@ class EdgeLabelPathAccessor : public IAccessor {
const IEdgeColumn& col_;
};

class EdgeLabelEdgeAccessor : public IAccessor {
public:
using elem_t = int32_t;
EdgeLabelEdgeAccessor() {}

elem_t typed_eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
const Any& data, size_t idx) const {
return static_cast<elem_t>(label.edge_label);
}

RTAny eval_path(size_t idx) const override {
LOG(FATAL) << "not supposed to reach here...";
return RTAny();
}

RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
const Any& data, size_t idx) const override {
return RTAny::from_int32(typed_eval_edge(label, src, dst, data, idx));
}
};

template <typename T>
class EdgePropertyEdgeAccessor : public IAccessor {
public:
Expand All @@ -573,6 +594,96 @@ class EdgePropertyEdgeAccessor : public IAccessor {
}
};

// Access the global edge id of an edge in a path
// Currently we have no unique id for a edge.
// We construct the id from the edge's src, dst and label.
class EdgeGlobalIdPathAccessor : public IAccessor {
public:
using elem_t = int64_t; // edge global id
EdgeGlobalIdPathAccessor(const Context& ctx, int tag)
: edge_col_(*std::dynamic_pointer_cast<IEdgeColumn>(ctx.get(tag))) {}

static uint32_t generate_edge_label_id(label_t src_label_id,
label_t dst_label_id,
label_t edge_label_id) {
uint32_t unique_edge_label_id = src_label_id;
static constexpr int num_bits = sizeof(label_t) * 8;
unique_edge_label_id = unique_edge_label_id << num_bits;
unique_edge_label_id = unique_edge_label_id | dst_label_id;
unique_edge_label_id = unique_edge_label_id << num_bits;
unique_edge_label_id = unique_edge_label_id | edge_label_id;
return unique_edge_label_id;
}

static int64_t encode_unique_edge_id(uint32_t label_id, vid_t src,
vid_t dst) {
// We assume label_id is only used by 24 bits.
int64_t unique_edge_id = label_id;
unique_edge_id = unique_edge_id << 40;
// bitmask for top 40 bits set to 1
int64_t bitmask = 0xFFFFFFFFFF000000;
// 24 bit | 20 bit | 20 bit
if (bitmask & (int64_t) src || bitmask & (int64_t) dst) {
LOG(ERROR) << "src or dst is too large to be encoded in 20 bits: " << src
<< " " << dst;
}
unique_edge_id = unique_edge_id | (src << 20);
unique_edge_id = unique_edge_id | dst;
return unique_edge_id;
}

elem_t typed_eval_path(size_t idx) const {
const auto& e = edge_col_.get_edge(idx);
auto label_id = generate_edge_label_id(std::get<0>(e).src_label,
std::get<0>(e).dst_label,
std::get<0>(e).edge_label);
return encode_unique_edge_id(label_id, std::get<1>(e), std::get<2>(e));
}

RTAny eval_path(size_t idx) const override {
return RTAny::from_int64(typed_eval_path(idx));
}

bool is_optional() const override { return edge_col_.is_optional(); }

RTAny eval_path(size_t idx, int) const override {
if (!edge_col_.has_value(idx)) {
return RTAny(RTAnyType::kNull);
}
return RTAny::from_int64(typed_eval_path(idx));
}

std::shared_ptr<IContextColumnBuilder> builder() const override {
return edge_col_.builder();
}

private:
const IEdgeColumn& edge_col_;
};

class EdgeGlobalIdEdgeAccessor : public IAccessor {
public:
using elem_t = int64_t; // edge global id
EdgeGlobalIdEdgeAccessor() {}

elem_t typed_eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
const Any& data, size_t idx) const {
auto label_id = EdgeGlobalIdPathAccessor::generate_edge_label_id(
label.src_label, label.dst_label, label.edge_label);
return EdgeGlobalIdPathAccessor::encode_unique_edge_id(label_id, src, dst);
}

RTAny eval_path(size_t idx) const override {
LOG(FATAL) << "not supposed to reach here...";
return RTAny();
}

RTAny eval_edge(const LabelTriplet& label, vid_t src, vid_t dst,
const Any& data, size_t idx) const override {
return RTAny::from_int64(typed_eval_edge(label, src, dst, data, idx));
}
};

template <typename T>
class MultiPropsEdgePropertyEdgeAccessor : public IAccessor {
public:
Expand Down Expand Up @@ -764,6 +875,13 @@ std::shared_ptr<IAccessor> create_edge_property_path_accessor(
std::shared_ptr<IAccessor> create_edge_label_path_accessor(const Context& ctx,
int tag);

std::shared_ptr<IAccessor> create_edge_label_edge_accessor();

std::shared_ptr<IAccessor> create_edge_global_id_path_accessor(
const Context& ctx, int tag);

std::shared_ptr<IAccessor> create_edge_global_id_edge_accessor();

std::shared_ptr<IAccessor> create_edge_property_edge_accessor(
const ReadTransaction& txn, const std::string& prop_name, RTAnyType type);

Expand Down
16 changes: 11 additions & 5 deletions flex/engines/graph_db/runtime/common/leaf_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@

namespace bl = boost::leaf;

#define RETURN_UNSUPPORTED_ERROR(msg) \
return ::boost::leaf::new_error( \
::gs::Status(::gs::StatusCode::UNSUPPORTED_OPERATION, msg))
// Concatenate the current function name and line number to form the error
// message
#define PREPEND_LINE_INFO(msg) \
std::string(__FILE__) + ":" + std::to_string(__LINE__) + \
" func: " + std::string(__FUNCTION__) + ", " + msg

#define RETURN_UNSUPPORTED_ERROR(msg) \
return ::boost::leaf::new_error(::gs::Status( \
::gs::StatusCode::UNSUPPORTED_OPERATION, PREPEND_LINE_INFO(msg)))

#define RETURN_BAD_REQUEST_ERROR(msg) \
return ::boost::leaf::new_error( \
::gs::Status(::gs::StatusCode::BAD_REQUEST, msg))
::gs::Status(::gs::StatusCode::BAD_REQUEST, PREPEND_LINE_INFO(msg)))

#define RETURN_NOT_IMPLEMENTED_ERROR(msg) \
return ::boost::leaf::new_error( \
::gs::Status(::gs::StatusCode::UNIMPLEMENTED, msg))
::gs::Status(::gs::StatusCode::UNIMPLEMENTED, PREPEND_LINE_INFO(msg)))

#endif // RUNTIME_COMMON_LEAF_UTILS_H_
6 changes: 4 additions & 2 deletions flex/engines/graph_db/runtime/common/operators/scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@

#include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h"
#include "flex/engines/graph_db/runtime/common/context.h"

#include "boost/leaf.hpp"
#include "flex/engines/graph_db/runtime/common/leaf_utils.h"

namespace bl = boost::leaf;
namespace gs {
Expand Down Expand Up @@ -58,6 +57,9 @@ class Scan {
}
}
ctx.set(params.alias, builder.finish());
} else {
LOG(ERROR) << "No vertex labels in scan_vertex";
RETURN_BAD_REQUEST_ERROR("No valid vertex labels in scan_vertex");
}
return ctx;
}
Expand Down

0 comments on commit a4dab02

Please sign in to comment.