Skip to content

Commit

Permalink
wip with draft
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandre-ricciardi committed Jun 4, 2024
1 parent c3bed68 commit e87bfef
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 45 deletions.
1 change: 1 addition & 0 deletions integration/cypher-tests/tests/aggregation_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ async fn _test_aggregation(mut client: Client) {
let result1 = client.execute_cypher_request("create (test:Person) return test").await;
let result2 = client.execute_cypher_request("create (test:Person) return test").await;
if let (Ok(d1), Ok(d2)) = (result1, result2) {
println!("{}", d1.to_string());
let id1 = extract_node_id(d1).expect("node id");
let id2 = extract_node_id(d2).expect("node id");
for i in 0..100 {
Expand Down
6 changes: 4 additions & 2 deletions lib/zawgl-cypher-query-model/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ impl BoolResult {
pub struct RelationshipResult {
pub name: String,
pub value: EdgeData<NodeIndex, EdgeIndex, Relationship>,
pub source_nid: i64,
pub target_nid: i64,
}

impl RelationshipResult {
pub fn new(name: String, value: EdgeData<NodeIndex, EdgeIndex, Relationship>) -> Self {
RelationshipResult{name, value}
pub fn new(name: String, value: EdgeData<NodeIndex, EdgeIndex, Relationship>, source_nid: i64, target_nid: i64) -> Self {
RelationshipResult{name, value, source_nid, target_nid}
}
}
pub enum EvalResultItem {
Expand Down
99 changes: 68 additions & 31 deletions lib/zawgl-front/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{collections::{HashMap, hash_map::Entry}, slice::Iter};
use bson::{Bson, Document, doc};
use cypher::query_engine::{process_cypher_query, CypherError};
use zawgl_core::{model::{Property, PropertyValue, PropertyGraph, Relationship, Node}, graph::{EdgeData, NodeIndex, EdgeIndex}};
use zawgl_cypher_query_model::{model::{EvalScopeClause, EvalScopeExpression, Request, ValueItem}, parameters::build_parameters, QueryResult, StepType};
use zawgl_cypher_query_model::{model::{EvalResultItem, EvalScopeClause, EvalScopeExpression, NodeResult, RelationshipResult, Request, ValueItem}, parameters::build_parameters, QueryResult, StepType};
use tx_handler::{handle_graph_request, request_handler::RequestHandler, handler::TxHandler, DatabaseError};

extern crate zawgl_core;
Expand Down Expand Up @@ -82,16 +82,32 @@ fn get_return_clause(request: &Request) -> Option<&EvalScopeClause> {
})
}

fn eval_item_to_bson(eval_item: &EvalResultItem) -> Result<Document, CypherError> {
match eval_item {
EvalResultItem::Node(n) => make_node_doc(&n),
EvalResultItem::Relationship(rel) => make_relationship_doc(&rel),
EvalResultItem::Scalar(value) => Ok(doc! {
value.name.to_string(): value.value
}),
EvalResultItem::Bool(value) => Ok(doc! {
value.name.to_string(): value.value
}),
EvalResultItem::String(value) => Ok(doc! {
value.name.to_string(): value.value.to_string()
})
}
}

fn build_response(request_id: &str, qr: QueryResult, request: &Request) -> Result<Document, CypherError> {
let mut result_doc = Document::new();
let mut graph_list = Vec::new();
let return_wildcard = request.steps.last().map(|ret| {
match ret.step_type {
let return_wildcard = &request.steps.last().map(|ret| {
match &ret.step_type {
StepType::RETURN(ret_clause) => ret_clause.has_wildcard(),
_ => false
}
});
let wildcard = return_wildcard == Some(true);
let wildcard = return_wildcard == &Some(true);
for pattern in &qr.matched_graphs {
let mut graph_doc = Document::new();
let mut nodes_doc = Vec::new();
Expand Down Expand Up @@ -125,10 +141,10 @@ fn build_response(request_id: &str, qr: QueryResult, request: &Request) -> Resul
}

let mut values_doc = vec![];
for res in qr.return_eval {
for res in &qr.return_eval {
let mut row = vec![];
for item in res {
row.push(value)
for eval_item in res {
row.push(eval_item_to_bson(eval_item)?);
}
values_doc.push(row);
}
Expand Down Expand Up @@ -307,34 +323,24 @@ fn get_named_items<'a>(name: &str, graph: &'a PropertyGraph) -> Result<Vec<Item<
Ok(res)
}

fn make_node_doc(alias: Option<&String>, name: &str, node: &Node) -> Result<Document, CypherError> {
let ret_name = if let Some(a) = alias {
a.to_string()
} else {
name.to_string()
};
fn make_node_doc(node: &NodeResult) -> Result<Document, CypherError> {
let node_doc = doc!{
"name": ret_name,
"id": node.get_id().ok_or(CypherError::ResponseError)? as i64,
"properties": build_properties(node.get_properties_ref()),
"labels": Bson::from(node.get_labels_ref()),
"name": node.name.to_string(),
"id": node.value.get_id().ok_or(CypherError::ResponseError)? as i64,
"properties": build_properties(node.value.get_properties_ref()),
"labels": Bson::from(node.value.get_labels_ref()),
};
Ok(node_doc)
}

fn make_relationship_doc(alias: Option<&String>, name: &str, rel: &EdgeData<NodeIndex, EdgeIndex, Relationship>, graph: &PropertyGraph) -> Result<Document, CypherError> {
let ret_name = if let Some(a) = alias {
a.to_string()
} else {
name.to_string()
};
fn make_relationship_doc(rel: &RelationshipResult) -> Result<Document, CypherError> {
let rel_doc = doc!{
"name": ret_name,
"id": rel.relationship.get_id().ok_or(CypherError::ResponseError)? as i64,
"source_id": graph.get_node_ref(&rel.get_source()).get_id().ok_or(CypherError::ResponseError)? as i64,
"target_id": graph.get_node_ref(&rel.get_target()).get_id().ok_or(CypherError::ResponseError)? as i64,
"properties": build_properties(rel.relationship.get_properties_ref()),
"labels": Bson::from(rel.relationship.get_labels_ref()),
"name": rel.name.to_string(),
"id": rel.value.relationship.get_id().ok_or(CypherError::ResponseError)? as i64,
"source_id": rel.source_nid,
"target_id": rel.target_nid,
"properties": build_properties(rel.value.relationship.get_properties_ref()),
"labels": Bson::from(rel.value.relationship.get_labels_ref()),
};
Ok(rel_doc)
}
Expand All @@ -344,7 +350,7 @@ fn get_nodes_named(ret_all: bool, alias: Option<&String>, name: &str, graph: &Pr
for node in graph.get_nodes() {
if let Some(var) = node.get_var() {
if var == name || ret_all {
nodes_doc.push(make_node_doc(alias, name, node)?);
nodes_doc.push(make_node(alias, name, node)?);
}
}
}
Expand All @@ -355,13 +361,44 @@ fn get_relationships_named(ret_all: bool, alias: Option<&String>, name: &str, gr
for rel in graph.get_relationships_and_edges() {
if let Some(var) = rel.relationship.get_var() {
if var == name || ret_all {
rels_doc.push(make_relationship_doc(alias, name, rel, graph)?);
rels_doc.push(make_relationship(alias, name, rel, graph)?);
}
}
}
Ok(rels_doc)
}

fn make_node(alias: Option<&String>, name: &str, node: &Node) -> Result<Document, CypherError> {
let ret_name = if let Some(a) = alias {
a.to_string()
} else {
name.to_string()
};
let node_doc = doc!{
"name": ret_name,
"id": node.get_id().ok_or(CypherError::ResponseError)? as i64,
"properties": build_properties(node.get_properties_ref()),
"labels": Bson::from(node.get_labels_ref()),
};
Ok(node_doc)
}

fn make_relationship(alias: Option<&String>, name: &str, rel: &EdgeData<NodeIndex, EdgeIndex, Relationship>, graph: &PropertyGraph) -> Result<Document, CypherError> {
let ret_name = if let Some(a) = alias {
a.to_string()
} else {
name.to_string()
};
let rel_doc = doc!{
"name": ret_name,
"id": rel.relationship.get_id().ok_or(CypherError::ResponseError)? as i64,
"source_id": graph.get_node_ref(&rel.get_source()).get_id().ok_or(CypherError::ResponseError)? as i64,
"target_id": graph.get_node_ref(&rel.get_target()).get_id().ok_or(CypherError::ResponseError)? as i64,
"properties": build_properties(rel.relationship.get_properties_ref()),
"labels": Bson::from(rel.relationship.get_labels_ref()),
};
Ok(rel_doc)
}
fn build_property_value(name: &str, value: &PropertyValue) -> Document {
match value {
PropertyValue::PBool(v) => doc! {
Expand Down
26 changes: 14 additions & 12 deletions lib/zawgl-front/src/planner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub fn handle_query_steps(steps: Vec<QueryStep>, graph_engine: &mut GraphEngine)
let mut eval_results = Vec::<Vec<EvalResultItem>>::new();
let mut return_eval_results = Vec::<Vec<EvalResultItem>>::new();
let mut first_step = true;
let mut result_graphs = vec![];
for step in steps {
match step.step_type {
StepType::MATCH => {
Expand Down Expand Up @@ -97,19 +98,18 @@ pub fn handle_query_steps(steps: Vec<QueryStep>, graph_engine: &mut GraphEngine)
}
},
StepType::WITH(eval_scope) => {
eval_results = handle_eval(&mut results, eval_scope)?;
results = vec![];
(_, eval_results) = handle_eval(&mut results, eval_scope)?;
},
StepType::RETURN(eval_scope) => {
return_eval_results = handle_eval(&mut results, eval_scope)?;
(result_graphs, return_eval_results) = handle_eval(&mut results, eval_scope)?;
},
}
first_step = false;
}
Ok(QueryResult::new(flatten_results(&mut results), return_eval_results))
Ok(QueryResult::new(result_graphs, return_eval_results))
}

fn handle_eval(results: &mut Vec::<Vec<PropertyGraph>>, eval_scope: EvalScopeClause) -> Result<Vec<Vec<EvalResultItem>>, CypherError> {
fn handle_eval(results: &mut Vec::<Vec<PropertyGraph>>, eval_scope: EvalScopeClause) -> Result<(Vec<PropertyGraph>, Vec<Vec<EvalResultItem>>), CypherError> {
let matched_graphs = flatten_results(results);
let mut grouping = Vec::new();
for ret_exp in &eval_scope.expressions {
Expand Down Expand Up @@ -172,7 +172,7 @@ fn handle_eval(results: &mut Vec::<Vec<PropertyGraph>>, eval_scope: EvalScopeCla
Item::Relationship(rel) => {
if let Some(var) = rel.relationship.get_var() {
if var == named_item {
row.push(EvalResultItem::Relationship(make_relationship(ret_item.alias.as_ref(), &named_item, rel, combination.graph)));
row.push(EvalResultItem::Relationship(make_relationship(ret_item.alias.as_ref(), &named_item, rel, combination.graph)?));
}
}
}
Expand Down Expand Up @@ -208,7 +208,7 @@ fn handle_eval(results: &mut Vec::<Vec<PropertyGraph>>, eval_scope: EvalScopeCla
}
eval_result_scope.push(row);
}
Ok(eval_result_scope)
Ok((matched_graphs, eval_result_scope))
}

fn handle_match(results: &Vec::<Vec<PropertyGraph>>, graph_engine: &mut GraphEngine, step: &QueryStep, eval_row: &Vec<EvalResultItem>) -> Vec::<Vec<PropertyGraph>> {
Expand Down Expand Up @@ -346,27 +346,29 @@ fn make_node(alias: Option<&String>, name: &str, node: &Node) -> NodeResult {
NodeResult::new(ret_name, ret_node)
}

fn make_relationship(alias: Option<&String>, name: &str, rel: &EdgeData<NodeIndex, EdgeIndex, Relationship>, graph: &PropertyGraph) -> RelationshipResult {
fn make_relationship(alias: Option<&String>, name: &str, rel: &EdgeData<NodeIndex, EdgeIndex, Relationship>, graph: &PropertyGraph) -> Result<RelationshipResult, CypherError> {
let ret_name = if let Some(a) = alias {
a.to_string()
} else {
name.to_string()
};
let mut ret_rel = rel.clone();
ret_rel.relationship.set_var(&ret_name);
RelationshipResult::new(ret_name, ret_rel)
let sid = graph.get_node_ref(&ret_rel.get_source()).get_id().ok_or(CypherError::ResponseError)? as i64;
let tid = graph.get_node_ref(&ret_rel.get_target()).get_id().ok_or(CypherError::ResponseError)? as i64;
Ok(RelationshipResult::new(ret_name, ret_rel, sid, tid))
}

fn get_relationships_named(ret_all: bool, alias: Option<&String>, name: &str, graph: &PropertyGraph) -> Vec<RelationshipResult> {
fn get_relationships_named(ret_all: bool, alias: Option<&String>, name: &str, graph: &PropertyGraph) -> Result<Vec<RelationshipResult>, CypherError> {
let mut rels = vec![];
for rel in graph.get_relationships_and_edges() {
if let Some(var) = rel.relationship.get_var() {
if var == name || ret_all {
rels.push(make_relationship(alias, name, rel, graph));
rels.push(make_relationship(alias, name, rel, graph)?);
}
}
}
rels
Ok(rels)
}

fn get_property_sum_value(prop: &PropertyValue) -> f64 {
Expand Down

0 comments on commit e87bfef

Please sign in to comment.