diff --git a/interactive_engine/executor/ir/core/src/plan/ffi.rs b/interactive_engine/executor/ir/core/src/plan/ffi.rs index c0d1019e8ffc..0421500e3a0b 100644 --- a/interactive_engine/executor/ir/core/src/plan/ffi.rs +++ b/interactive_engine/executor/ir/core/src/plan/ffi.rs @@ -64,7 +64,7 @@ use prost::Message; use crate::error::IrError; use crate::plan::logical::{LogicalPlan, NodeId}; -use crate::plan::meta::{set_schema_from_json, KeyType}; +use crate::plan::meta::set_schema_from_json; use crate::plan::physical::AsPhysical; #[repr(i32)] @@ -519,16 +519,6 @@ pub enum FfiKeyType { Column = 2, } -impl From for KeyType { - fn from(t: FfiKeyType) -> Self { - match t { - FfiKeyType::Entity => KeyType::Entity, - FfiKeyType::Relation => KeyType::Relation, - FfiKeyType::Column => KeyType::Column, - } - } -} - /// Query entity/relation/property name by given id #[no_mangle] pub extern "C" fn get_key_name(key_id: i32, key_type: FfiKeyType) -> FfiResult { diff --git a/interactive_engine/executor/ir/core/src/plan/logical.rs b/interactive_engine/executor/ir/core/src/plan/logical.rs index b5f81406bc60..43639db20789 100644 --- a/interactive_engine/executor/ir/core/src/plan/logical.rs +++ b/interactive_engine/executor/ir/core/src/plan/logical.rs @@ -968,7 +968,7 @@ fn build_and_predicate( fn get_table_id_from_pb(schema: &Schema, name: &common_pb::NameOrId) -> Option { name.item.as_ref().and_then(|item| match item { - common_pb::name_or_id::Item::Name(name) => schema.get_table_id(name), + common_pb::name_or_id::Item::Name(name) => schema.get_entity_or_relation_id(name), common_pb::name_or_id::Item::Id(id) => Some(*id), }) } @@ -1027,7 +1027,7 @@ fn preprocess_label( common_pb::value::Item::Str(name) => { let new_item = common_pb::value::Item::I32( schema - .get_table_id(name) + .get_entity_or_relation_id(name) .ok_or_else(|| IrError::TableNotExist(NameOrId::Str(name.to_string())))?, ); debug!("table: {:?} -> {:?}", item, new_item); @@ -1039,9 +1039,11 @@ fn preprocess_label( .item .iter() .map(|name| { - schema.get_table_id(name).ok_or_else(|| { - IrError::TableNotExist(NameOrId::Str(name.to_string())) - }) + schema + .get_entity_or_relation_id(name) + .ok_or_else(|| { + IrError::TableNotExist(NameOrId::Str(name.to_string())) + }) }) .collect::>>()?, }); @@ -1502,7 +1504,7 @@ fn is_params_all_labels(params: &pb::QueryParams) -> bool { .as_ref() .and_then(|store_meta| store_meta.schema.as_ref()) { - let params_label_ids: BTreeSet = params + let mut params_label_ids: Vec = params .tables .iter() .filter_map(|name_or_id| { @@ -1515,11 +1517,11 @@ fn is_params_all_labels(params: &pb::QueryParams) -> bool { } }) .collect(); - let meta_label_ids: BTreeSet = schema - .entity_labels_iter() - .map(|(_, label_id)| label_id) - .collect(); - params_label_ids.eq(&meta_label_ids) + + params_label_ids.sort(); + params_label_ids.dedup(); + + schema.check_all_entity_labels(¶ms_label_ids) } else { false } diff --git a/interactive_engine/executor/ir/core/src/plan/meta.rs b/interactive_engine/executor/ir/core/src/plan/meta.rs index 85f858626cb0..296e33d51330 100644 --- a/interactive_engine/executor/ir/core/src/plan/meta.rs +++ b/interactive_engine/executor/ir/core/src/plan/meta.rs @@ -103,31 +103,22 @@ impl From for schema_pb::LabelMeta { } } -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub enum KeyType { - Entity = 0, - Relation = 1, - Column = 2, -} - -impl Default for KeyType { - fn default() -> Self { - Self::Entity - } -} - #[derive(Clone, Debug, Default)] pub struct Schema { - /// A map from table (Entity or Relation) name to its internally encoded id - /// In the concept of graph database, this is also known as label - table_name_to_id: BTreeMap, + /// A map from entity name to its internally encoded id + /// In the concept of graph database, this is also known as vertex label + entity_name_to_id: BTreeMap, + /// A map from relation name to its internally encoded id + /// In the concept of graph database, this is also known as vertex label + relation_name_to_id: BTreeMap, /// A map from column name to its store-encoded id /// In the concept of graph database, this is also known as property column_name_to_id: BTreeMap, /// Record the primary keys of each table primary_keys: BTreeMap>, - /// A reversed map of `id` to `name` mapping - id_to_name: BTreeMap<(KeyType, KeyId), String>, + /// A reversed map of `id` to `name` mapping. + /// 0, entity; 1, relation; 2, column + id_to_name: BTreeMap<(u8, KeyId), String>, /// The entities' labels that are bound a certain type of relations relation_bound_labels: BTreeMap>, /// Is the table name mapped as id @@ -151,19 +142,15 @@ impl Schema { if schema.is_table_id { for (name, id) in entities.into_iter() { schema - .table_name_to_id - .insert(name.clone(), (KeyType::Entity, id)); - schema - .id_to_name - .insert((KeyType::Entity, id), name); + .entity_name_to_id + .insert(name.clone(), id); + schema.id_to_name.insert((0, id), name); } for (name, id) in relations.into_iter() { schema - .table_name_to_id - .insert(name.clone(), (KeyType::Relation, id)); - schema - .id_to_name - .insert((KeyType::Relation, id), name); + .relation_name_to_id + .insert(name.clone(), id); + schema.id_to_name.insert((1, id), name); } } if schema.is_column_id { @@ -171,19 +158,26 @@ impl Schema { schema .column_name_to_id .insert(name.clone(), id); - schema - .id_to_name - .insert((KeyType::Column, id), name); + schema.id_to_name.insert((2, id), name); } } schema } - pub fn get_table_id(&self, name: &str) -> Option { - self.table_name_to_id + pub fn get_entity_id(&self, name: &str) -> Option { + self.entity_name_to_id.get(name).map(|id| *id) + } + + pub fn get_relation_id(&self, name: &str) -> Option { + self.relation_name_to_id.get(name).map(|id| *id) + } + + pub fn get_entity_or_relation_id(&self, name: &str) -> Option { + self.entity_name_to_id .get(name) - .map(|(_, id)| *id) + .map(|id| *id) + .or_else(|| self.relation_name_to_id.get(name).map(|id| *id)) } pub fn get_column_id(&self, name: &str) -> Option { @@ -191,15 +185,15 @@ impl Schema { } pub fn get_entity_name(&self, id: KeyId) -> Option<&String> { - self.id_to_name.get(&(KeyType::Entity, id)) + self.id_to_name.get(&(0, id)) } pub fn get_relation_name(&self, id: KeyId) -> Option<&String> { - self.id_to_name.get(&(KeyType::Relation, id)) + self.id_to_name.get(&(1, id)) } pub fn get_column_name(&self, id: KeyId) -> Option<&String> { - self.id_to_name.get(&(KeyType::Column, id)) + self.id_to_name.get(&(2, id)) } /// To get the entities' labels that are bound to a relation of given type @@ -215,18 +209,18 @@ impl Schema { self.is_table_id } - pub fn entity_labels_iter(&self) -> DynIter<(String, LabelId)> { - Box::new( - self.table_name_to_id - .iter() - .filter_map(|(name, (key_type, label_id))| { - if let KeyType::Entity = key_type { - Some((name.clone(), *label_id)) - } else { - None - } - }), - ) + /// Check whether the given entity labels contain all entity labels in the schema + pub fn check_all_entity_labels(&self, label_ids: &Vec) -> bool { + if self.entity_name_to_id.len() != label_ids.len() { + false + } else { + for label_id in label_ids { + if !self.id_to_name.contains_key(&(0, *label_id)) { + return false; + } + } + true + } } /// Check whether a given table contains a given column as a primary key. @@ -247,7 +241,7 @@ impl From for schema_pb::Schema { } else { let mut entities = Vec::new(); for (&(ty, id), name) in &schema.id_to_name { - if ty == KeyType::Entity { + if ty == 0 { entities.push(schema_pb::EntityMeta { label: Some(schema_pb::LabelMeta { id, name: name.to_string() }), columns: vec![], @@ -262,7 +256,7 @@ impl From for schema_pb::Schema { } else { let mut relations = Vec::new(); for (&(ty, id), name) in &schema.id_to_name { - if ty == KeyType::Relation { + if ty == 1 { let mut relation_meta = schema_pb::RelationMeta { label: Some(schema_pb::LabelMeta { id, name: name.to_string() }), entity_pairs: vec![], @@ -304,15 +298,15 @@ impl From for Schema { if schema_pb.is_table_id { if let Some(label) = &entity.label { if !schema - .table_name_to_id + .entity_name_to_id .contains_key(&label.name) { schema - .table_name_to_id - .insert(label.name.clone(), (KeyType::Entity, label.id)); + .entity_name_to_id + .insert(label.name.clone(), label.id); schema .id_to_name - .insert((KeyType::Entity, label.id), label.name.clone()); + .insert((0, label.id), label.name.clone()); } } } @@ -326,7 +320,7 @@ impl From for Schema { .insert(key.name.clone(), key.id); schema .id_to_name - .insert((KeyType::Column, key.id), key.name.clone()); + .insert((2, key.id), key.name.clone()); } } if column.is_primary_key { @@ -346,15 +340,15 @@ impl From for Schema { if schema_pb.is_table_id { if let Some(label) = &rel.label { if !schema - .table_name_to_id + .relation_name_to_id .contains_key(&label.name) { schema - .table_name_to_id - .insert(label.name.clone(), (KeyType::Relation, label.id)); + .relation_name_to_id + .insert(label.name.clone(), label.id); schema .id_to_name - .insert((KeyType::Relation, label.id), label.name.clone()); + .insert((1, label.id), label.name.clone()); } } } @@ -368,7 +362,7 @@ impl From for Schema { .insert(key.name.clone(), key.id); schema .id_to_name - .insert((KeyType::Column, key.id), key.name.clone()); + .insert((2, key.id), key.name.clone()); } } if column.is_primary_key {