in flex/engines/graph_db/app/server_app.cc [87:308]
bool ServerApp::Query(GraphDBSession& graph, Decoder& input, Encoder& output) {
std::string op = std::string(input.get_string());
for (auto& c : op) {
c = toupper(c);
}
if (op == "SHOW_STORED_PROCEDURES") {
CHECK(input.empty());
graph.GetAppInfo(output);
return true;
} else if (op == "QUERY_VERTEX") {
std::string vertex_label = std::string(input.get_string());
int64_t vertex_id = input.get_long();
CHECK(input.empty());
auto txn = graph.GetReadTransaction();
uint8_t vertex_label_id = txn.schema().get_vertex_label_id(vertex_label);
auto vit = txn.GetVertexIterator(vertex_label_id);
for (; vit.IsValid(); vit.Next()) {
if (vit.GetId().AsInt64() == vertex_id) {
output.put_int(1);
int field_num = vit.FieldNum();
for (int i = 0; i < field_num; ++i) {
output.put_string(vit.GetField(i).to_string());
}
return true;
}
}
output.put_int(0);
return false;
} else if (op == "QUERY_EDGE") {
std::string src_label = std::string(input.get_string());
int64_t src_id = input.get_long();
std::string dst_label = std::string(input.get_string());
int64_t dst_id = input.get_long();
std::string edge_label = std::string(input.get_string());
CHECK(input.empty());
if (src_label != "_ANY_LABEL" && dst_label != "_ANY_LABEL" &&
edge_label != "_ANY_LABEL" &&
src_id != std::numeric_limits<int64_t>::max() &&
dst_id != std::numeric_limits<int64_t>::max()) {
auto txn = graph.GetReadTransaction();
uint8_t src_label_id, dst_label_id, edge_label_id;
if (!txn.schema().contains_vertex_label(src_label)) {
output.put_int(0);
return false;
}
src_label_id = txn.schema().get_vertex_label_id(src_label);
if (!txn.schema().contains_vertex_label(dst_label)) {
output.put_int(0);
return false;
}
dst_label_id = txn.schema().get_vertex_label_id(dst_label);
if (!txn.schema().contains_edge_label(edge_label)) {
output.put_int(0);
return false;
}
edge_label_id = txn.schema().get_edge_label_id(edge_label);
uint32_t src_vid = get_vertex_vid(txn, src_label_id, src_id);
if (src_vid == std::numeric_limits<uint32_t>::max()) {
output.put_int(0);
return false;
}
uint32_t dst_vid = get_vertex_vid(txn, dst_label_id, dst_id);
if (dst_vid == std::numeric_limits<uint32_t>::max()) {
output.put_int(0);
return false;
}
auto ieit = txn.GetInEdgeIterator(dst_label_id, dst_vid, src_label_id,
edge_label_id);
while (ieit.IsValid()) {
if (ieit.GetNeighbor() == src_vid) {
output.put_int(1);
output.put_string(src_label);
output.put_string(dst_label);
output.put_string(edge_label);
output.put_int(1);
output.put_long(src_id);
output.put_long(dst_id);
output.put_string(ieit.GetData().to_string());
return true;
}
ieit.Next();
}
auto oeit = txn.GetOutEdgeIterator(src_label_id, src_vid, dst_label_id,
edge_label_id);
while (oeit.IsValid()) {
if (oeit.GetNeighbor() == dst_vid) {
output.put_int(1);
output.put_string(src_label);
output.put_string(dst_label);
output.put_string(edge_label);
output.put_int(1);
output.put_long(src_id);
output.put_long(dst_id);
output.put_string(oeit.GetData().to_string());
return true;
}
oeit.Next();
}
output.put_int(0);
return true;
} else {
auto txn = graph.GetReadTransaction();
std::vector<std::tuple<uint8_t, uint8_t, uint8_t>> label_tuples;
generate_label_tuples(src_label, dst_label, edge_label, txn.schema(),
label_tuples);
if (label_tuples.empty()) {
output.put_int(0);
return true;
}
output.put_int(1);
size_t total_matched_edges = 0;
for (auto& tup : label_tuples) {
uint8_t src_label_id = std::get<0>(tup);
uint8_t dst_label_id = std::get<1>(tup);
uint8_t edge_label_id = std::get<2>(tup);
vertex_range src_range(0, 0), dst_range(0, 0);
if (src_id == std::numeric_limits<int64_t>::max()) {
src_range.from = 0;
src_range.to = txn.GetVertexNum(src_label_id);
} else {
uint32_t src_vid = get_vertex_vid(txn, src_label_id, src_id);
if (src_vid != std::numeric_limits<uint32_t>::max()) {
src_range.from = src_vid;
src_range.to = src_vid + 1;
}
}
if (dst_id == std::numeric_limits<int64_t>::max()) {
dst_range.from = 0;
dst_range.to = txn.GetVertexNum(dst_label_id);
} else {
uint32_t dst_vid = get_vertex_vid(txn, dst_label_id, dst_id);
if (dst_vid != std::numeric_limits<uint32_t>::max()) {
dst_range.from = dst_vid;
dst_range.to = dst_vid + 1;
}
}
if (src_range.empty() || dst_range.empty()) {
continue;
}
std::vector<std::tuple<int64_t, int64_t, std::string>> match_edges;
for (uint32_t v = dst_range.from; v != dst_range.to; ++v) {
int64_t v_oid = txn.GetVertexId(dst_label_id, v).AsInt64();
auto ieit = txn.GetInEdgeIterator(dst_label_id, v, src_label_id,
edge_label_id);
while (ieit.IsValid()) {
uint32_t u = ieit.GetNeighbor();
if (src_range.contains(u)) {
int64_t u_oid = txn.GetVertexId(src_label_id, u).AsInt64();
match_edges.emplace_back(u_oid, v_oid,
ieit.GetData().to_string());
}
ieit.Next();
}
}
if (match_edges.empty()) {
for (uint32_t u = src_range.from; u != src_range.to; ++u) {
int64_t u_oid = txn.GetVertexId(src_label_id, u).AsInt64();
auto oeit = txn.GetOutEdgeIterator(src_label_id, u, dst_label_id,
edge_label_id);
while (oeit.IsValid()) {
uint32_t v = oeit.GetNeighbor();
if (dst_range.contains(v)) {
int64_t v_oid = txn.GetVertexId(dst_label_id, v).AsInt64();
match_edges.emplace_back(u_oid, v_oid,
oeit.GetData().to_string());
}
oeit.Next();
}
}
}
if (!match_edges.empty()) {
total_matched_edges += match_edges.size();
if (total_matched_edges > 1000) {
output.clear();
output.put_int(2);
return true;
}
std::string src_label_name =
txn.schema().get_vertex_label_name(src_label_id);
std::string dst_label_name =
txn.schema().get_vertex_label_name(dst_label_id);
std::string edge_label_name =
txn.schema().get_edge_label_name(edge_label_id);
output.put_string(src_label_name);
output.put_string(dst_label_name);
output.put_string(edge_label_name);
output.put_int(match_edges.size());
for (auto& e : match_edges) {
output.put_long(std::get<0>(e));
output.put_long(std::get<1>(e));
output.put_string(std::get<2>(e));
}
}
}
if (total_matched_edges == 0) {
output.clear();
output.put_int(0);
}
return true;
}
} else if (op == "COMPACTION") {
bool ret = graph.Compact();
if (ret) {
output.put_string("SUCCESS");
} else {
output.put_string("ABORTED");
}
return true;
}
return false;
}