use crate::parser::ast::{Assignment, UpdateStmt, UpdateTarget};
use linkrs_core::Value;
use super::render_contextual;
pub(crate) fn render_update(update: &UpdateStmt, values: &mut Vec<Value>) -> Option<String> {
if update.yield_clause.is_some() {
return None;
}
let mut out = String::new();
out.push_str(if update.is_upsert {
"UPSERT "
} else {
"UPDATE "
});
match &update.target {
UpdateTarget::Vertex(vid) => {
out.push_str("VERTEX ");
render_contextual(&mut out, values, vid)?;
}
UpdateTarget::Edge {
src,
dst,
edge_type,
rank,
} => {
let edge_type = edge_type.as_deref()?;
if update.is_upsert {
out.push_str("EDGE ");
render_contextual(&mut out, values, src)?;
out.push_str(" -> ");
render_contextual(&mut out, values, dst)?;
if let Some(rank) = rank {
out.push_str(" @");
render_contextual(&mut out, values, rank)?;
}
out.push_str(" OF ");
out.push_str(edge_type);
} else {
out.push_str("EDGE OF ");
out.push_str(edge_type);
out.push_str(" FROM ");
render_contextual(&mut out, values, src)?;
out.push_str(" TO ");
render_contextual(&mut out, values, dst)?;
if let Some(rank) = rank {
out.push_str(" @");
render_contextual(&mut out, values, rank)?;
}
}
}
UpdateTarget::Tag(_) => return None,
UpdateTarget::TagOnVertex { vid, tag_name } => {
if !update.is_upsert {
return None;
}
render_contextual(&mut out, values, vid)?;
out.push_str(" ON ");
out.push_str(tag_name);
}
}
if !update.set_clause.assignments.is_empty() {
out.push_str(" SET ");
render_set_assignments(&mut out, values, &update.set_clause.assignments)?;
}
if let Some(where_expr) = &update.where_clause {
out.push_str(" WHERE ");
render_contextual(&mut out, values, where_expr)?;
}
Some(out)
}
pub(crate) fn render_set_assignments(
out: &mut String,
values: &mut Vec<Value>,
assignments: &[Assignment],
) -> Option<()> {
for (index, assignment) in assignments.iter().enumerate() {
if index > 0 {
out.push_str(", ");
}
if assignment.target.is_some() || assignment.object.is_some() {
return None;
}
if assignment.is_map_overwrite {
return None;
}
out.push_str(&assignment.property);
out.push_str(" = ");
render_contextual(out, values, &assignment.value)?;
}
Some(())
}