static Status parse_edge_schema()

in flex/storages/rt_mutable_graph/schema.cc [856:1074]


static Status parse_edge_schema(YAML::Node node, Schema& schema) {
  std::string edge_label_name;
  if (!node["type_name"]) {
    LOG(ERROR) << "edge type_name is not set properly";
    return Status(StatusCode::INVALID_SCHEMA,
                  "edge type_name is not set properly");
  }
  edge_label_name = node["type_name"].as<std::string>();

  std::vector<PropertyType> property_types;
  std::vector<std::string> prop_names;
  std::string description;  // default is empty string
  RETURN_IF_NOT_OK(parse_edge_properties(node["properties"], edge_label_name,
                                         property_types, prop_names,
                                         schema.GetVersion()));

  if (node["description"]) {
    description = node["description"].as<std::string>();
  }
  if (node["nullable"]) {
    LOG(ERROR) << "nullable is not supported yet";
    return Status(StatusCode::UNIMPLEMENTED, "nullable is not supported yet");
  }

  if (node["default_value"]) {
    LOG(ERROR) << "default_value is not supported yet";
    return Status(StatusCode::UNIMPLEMENTED,
                  "default_value is not supported yet");
  }

  EdgeStrategy default_ie = EdgeStrategy::kMultiple;
  EdgeStrategy default_oe = EdgeStrategy::kMultiple;
  bool default_sort_on_compaction = false;

  // get vertex type pair relation
  auto vertex_type_pair_node = node["vertex_type_pair_relations"];
  // vertex_type_pair_node can be a list or a map
  if (!vertex_type_pair_node) {
    LOG(ERROR) << "edge [vertex_type_pair_relations] is not set";
    return Status(StatusCode::INVALID_SCHEMA,
                  "edge [vertex_type_pair_relations] is not set");
  }
  if (!vertex_type_pair_node.IsSequence()) {
    LOG(ERROR) << "edge [vertex_type_pair_relations] should be a sequence";
    return Status(StatusCode::INVALID_SCHEMA,
                  "edge [vertex_type_pair_relations] should be a sequence");
  }
  for (size_t i = 0; i < vertex_type_pair_node.size(); ++i) {
    std::string src_label_name, dst_label_name;
    auto cur_node = vertex_type_pair_node[i];
    EdgeStrategy cur_ie = default_ie;
    EdgeStrategy cur_oe = default_oe;
    bool cur_sort_on_compaction = default_sort_on_compaction;
    if (!get_scalar(cur_node, "source_vertex", src_label_name)) {
      LOG(ERROR) << "Expect field source_vertex for edge [" << edge_label_name
                 << "] in vertex_type_pair_relations";
      return Status(StatusCode::INVALID_SCHEMA,
                    "Expect field source_vertex for edge [" + edge_label_name +
                        "] in vertex_type_pair_relations");
    }
    if (!get_scalar(cur_node, "destination_vertex", dst_label_name)) {
      LOG(ERROR) << "Expect field destination_vertex for edge ["
                 << edge_label_name << "] in vertex_type_pair_relations";
      return Status(StatusCode::INVALID_SCHEMA,
                    "Expect field destination_vertex for edge [" +
                        edge_label_name + "] in vertex_type_pair_relations");
    }
    // check whether edge triplet exists in current schema
    if (schema.has_edge_label(src_label_name, dst_label_name,
                              edge_label_name)) {
      LOG(ERROR) << "Edge [" << edge_label_name << "] from [" << src_label_name
                 << "] to [" << dst_label_name << "] already exists";
      return Status(StatusCode::INVALID_SCHEMA,
                    "Edge [" + edge_label_name + "] from [" + src_label_name +
                        "] to [" + dst_label_name + "] already exists");
    }

    std::string relation_str;
    if (get_scalar(cur_node, "relation", relation_str)) {
      RelationToEdgeStrategy(relation_str, cur_ie, cur_oe);
    } else {
      LOG(WARNING) << "relation not defined, using default ie strategy: "
                   << cur_ie << ", oe strategy: " << cur_oe;
    }
    // check if x_csr_params presents
    bool oe_mutable = true, ie_mutable = true;
    if (cur_node["x_csr_params"]) {
      auto csr_node = cur_node["x_csr_params"];
      if (csr_node["edge_storage_strategy"]) {
        std::string edge_storage_strategy_str;
        if (get_scalar(csr_node, "edge_storage_strategy",
                       edge_storage_strategy_str)) {
          if (edge_storage_strategy_str == "ONLY_IN") {
            cur_oe = EdgeStrategy::kNone;
            VLOG(10) << "Store only in edges for edge: " << src_label_name
                     << "-[" << edge_label_name << "]->" << dst_label_name;
          } else if (edge_storage_strategy_str == "ONLY_OUT") {
            cur_ie = EdgeStrategy::kNone;
            VLOG(10) << "Store only out edges for edge: " << src_label_name
                     << "-[" << edge_label_name << "]->" << dst_label_name;
          } else if (edge_storage_strategy_str == "BOTH_OUT_IN" ||
                     edge_storage_strategy_str == "BOTH_IN_OUT") {
            VLOG(10) << "Store both in and out edges for edge: "
                     << src_label_name << "-[" << edge_label_name << "]->"
                     << dst_label_name;
          } else {
            LOG(ERROR) << "edge_storage_strategy is not set properly for edge: "
                       << src_label_name << "-[" << edge_label_name << "]->"
                       << dst_label_name;
            return Status(
                StatusCode::INVALID_SCHEMA,
                "edge_storage_strategy is not set properly for edge: " +
                    src_label_name + "-[" + edge_label_name + "]->" +
                    dst_label_name);
          }
        }
      }
      // try to parse sort on compaction
      if (csr_node["sort_on_compaction"]) {
        std::string sort_on_compaction_str;
        if (get_scalar(csr_node, "sort_on_compaction",
                       sort_on_compaction_str)) {
          if (sort_on_compaction_str == "true" ||
              sort_on_compaction_str == "TRUE") {
            VLOG(10) << "Sort on compaction for edge: " << src_label_name
                     << "-[" << edge_label_name << "]->" << dst_label_name;
            cur_sort_on_compaction = true;
          } else if (sort_on_compaction_str == "false" ||
                     sort_on_compaction_str == "FALSE") {
            VLOG(10) << "Do not sort on compaction for edge: " << src_label_name
                     << "-[" << edge_label_name << "]->" << dst_label_name;
            cur_sort_on_compaction = false;
          } else {
            LOG(ERROR) << "sort_on_compaction is not set properly for edge: "
                       << src_label_name << "-[" << edge_label_name << "]->"
                       << dst_label_name << "expect TRUE/FALSE";
            return Status(StatusCode::INVALID_SCHEMA,
                          "sort_on_compaction is not set properly for edge: " +
                              src_label_name + "-[" + edge_label_name + "]->" +
                              dst_label_name + "expect TRUE/FALSE");
          }
        }
      } else {
        VLOG(10) << "Do not sort on compaction for edge: " << src_label_name
                 << "-[" << edge_label_name << "]->" << dst_label_name;
      }

      if (csr_node["oe_mutability"]) {
        std::string mutability_str;
        if (get_scalar(csr_node, "oe_mutability", mutability_str)) {
          // mutability_str to upper_case
          std::transform(mutability_str.begin(), mutability_str.end(),
                         mutability_str.begin(), ::toupper);
          if (mutability_str == "IMMUTABLE") {
            oe_mutable = false;
          } else if (mutability_str == "MUTABLE") {
            oe_mutable = true;
          } else {
            LOG(ERROR) << "oe_mutability is not set properly for edge: "
                       << src_label_name << "-[" << edge_label_name << "]->"
                       << dst_label_name
                       << ", expect IMMUTABLE/MUTABLE, got:" << mutability_str;
            return Status(StatusCode::INVALID_SCHEMA,
                          "oe_mutability is not set properly for edge: " +
                              src_label_name + "-[" + edge_label_name + "]->" +
                              dst_label_name + ", expect IMMUTABLE/MUTABLE");
          }
        }
      }
      if (csr_node["ie_mutability"]) {
        std::string mutability_str;
        if (get_scalar(csr_node, "ie_mutability", mutability_str)) {
          // mutability_str to upper_case
          std::transform(mutability_str.begin(), mutability_str.end(),
                         mutability_str.begin(), ::toupper);
          if (mutability_str == "IMMUTABLE") {
            ie_mutable = false;
          } else if (mutability_str == "MUTABLE") {
            ie_mutable = true;
          } else {
            LOG(ERROR) << "ie_mutability is not set properly for edge: "
                       << src_label_name << "-[" << edge_label_name << "]->"
                       << dst_label_name
                       << ", expect IMMUTABLE/MUTABLE, got:" << mutability_str;
            return Status(StatusCode::INVALID_SCHEMA,
                          "ie_mutability is not set properly for edge: " +
                              src_label_name + "-[" + edge_label_name + "]->" +
                              dst_label_name + ", expect IMMUTABLE/MUTABLE");
          }
        }
      }
    }

    VLOG(10) << "edge " << edge_label_name << " from " << src_label_name
             << " to " << dst_label_name << " with " << property_types.size()
             << " properties";
    schema.add_edge_label(src_label_name, dst_label_name, edge_label_name,
                          property_types, prop_names, cur_oe, cur_ie,
                          oe_mutable, ie_mutable, cur_sort_on_compaction,
                          description);
  }

  // check the type_id equals to storage's label_id
  int32_t type_id;
  if (!get_scalar(node, "type_id", type_id)) {
    LOG(WARNING) << "type_id is not set properly for type: " << edge_label_name
                 << ", try to use incremental id";
    type_id = schema.edge_label_num() - 1;
  }
  auto label_id = schema.get_edge_label_id(edge_label_name);
  if (label_id != type_id) {
    LOG(ERROR) << "type_id is not equal to label_id for type: "
               << edge_label_name;
    return Status(
        StatusCode::INVALID_SCHEMA,
        "type_id is not equal to label_id for type: " + edge_label_name);
  }
  return Status::OK();
}