bool ServerApp::Query()

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;
}