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