use super::common;
use common::test_scenario::TestScenario;
use linkrs_core::Value;
use linkrs_query::parser::Parser;
use std::collections::HashMap;
#[test]
fn test_update_parser_vertex() {
let query = "UPDATE 1 ON Person SET name = 'Bob', age = 35";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE VERTEX parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_parser_vertex_with_when() {
let query = "UPDATE 1 ON Person SET age = 35 WHEN age < 30";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE with WHEN parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_parser_vertex_yield() {
let query = "UPDATE 1 ON Person SET name = 'Bob' YIELD name, age";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE with YIELD parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_execution_vertex() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET name = 'Bob', age = 35")
.assert_success();
}
#[test]
fn test_update_execution_vertex_with_when() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET age = 35 WHEN age < 40")
.assert_success();
}
#[test]
fn test_update_parser_edge() {
let query = "UPDATE EDGE 1 -> 2 OF KNOWS SET since = '2024-02-01'";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE EDGE parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_execution_edge() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since) VALUES 1 -> 2:('2024-01-01')")
.assert_success()
.exec_dml("UPDATE EDGE 1 -> 2 OF KNOWS SET since = '2024-02-01'")
.assert_success();
}
#[test]
fn test_update_edge_map_overwrite_replaces_row() {
let mut expected = HashMap::new();
expected.insert("since", Value::string("2024-02-01"));
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since STRING, weight INT)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since, weight) VALUES 1 -> 2:('2024-01-01', 5)")
.assert_success()
.exec_dml("UPDATE EDGE 1 -> 2 OF KNOWS SET e = {since: '2024-02-01'}")
.assert_success()
.assert_edge_exists(1, 2, "KNOWS")
.assert_edge_props(1, 2, "KNOWS", expected)
.assert_edge_prop_absent(1, 2, "KNOWS", "weight");
}
#[test]
fn test_update_vertex_and_verify() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT, city STRING)")
.assert_success()
.exec_dml("INSERT VERTEX Person(name, age, city) VALUES 1:('Alice', 30, 'NYC')")
.assert_success()
.assert_vertex_props(1, "Person", {
let mut map = std::collections::HashMap::new();
map.insert("age", linkrs_core::Value::Int(30));
map.insert("city", linkrs_core::Value::string("NYC"));
map
})
.exec_dml("UPDATE 1 ON Person SET age = 31")
.assert_success()
.assert_vertex_props(1, "Person", {
let mut map = std::collections::HashMap::new();
map.insert("age", linkrs_core::Value::Int(31));
map
})
.exec_dml("UPDATE 1 ON Person SET age = 32, city = 'LA'")
.assert_success()
.assert_vertex_props(1, "Person", {
let mut map = std::collections::HashMap::new();
map.insert("age", linkrs_core::Value::Int(32));
map.insert("city", linkrs_core::Value::string("LA"));
map
});
}
#[test]
fn test_update_vertex_with_condition() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT, state STRING)")
.assert_success()
.exec_dml("INSERT VERTEX Person(name, age, state) VALUES 1:('Alice', 30, 'active'), 2:('Bob', 25, 'inactive'), 3:('Charlie', 35, 'active')")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET state = 'premium' WHEN state == 'active'")
.assert_success()
.assert_vertex_props(1, "Person", {
let mut map = std::collections::HashMap::new();
map.insert("state", linkrs_core::Value::string("premium"));
map
})
.query("FETCH PROP ON Person 2")
.assert_vertex_or_edge_has_property("state", linkrs_core::Value::string("inactive"));
}
#[test]
fn test_update_edge_and_verify() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE, strength DOUBLE)")
.assert_success()
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.assert_success()
.exec_dml("INSERT EDGE KNOWS(since, strength) VALUES 1 -> 2:('2020-01-01', 0.5)")
.assert_success()
.exec_dml("UPDATE 1 -> 2 OF KNOWS SET strength = 0.9")
.assert_success()
.query("FETCH PROP ON KNOWS 1 -> 2")
.assert_vertex_or_edge_has_property("strength", linkrs_core::Value::Double(0.9));
}
#[test]
fn test_update_nonexistent_vertex() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_dml("UPDATE 999 ON Person SET name = 'Nobody'")
.assert_error();
}
#[test]
fn test_update_nonexistent_property() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice')")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET nonexistent = 'value'")
.assert_error();
}
#[test]
fn test_update_arithmetic_add() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val INT)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(10)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val + 5")
.assert_success()
.assert_vertex_props(1, "Counter", HashMap::from([("val", Value::Int(15))]));
}
#[test]
fn test_update_arithmetic_subtract() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val INT)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(10)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val - 3")
.assert_success()
.assert_vertex_props(1, "Counter", HashMap::from([("val", Value::Int(7))]));
}
#[test]
fn test_update_arithmetic_multiply() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val INT)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(10)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val * 2")
.assert_success()
.assert_vertex_props(1, "Counter", HashMap::from([("val", Value::Int(20))]));
}
#[test]
fn test_update_arithmetic_divide() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val DOUBLE)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(10.0)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val / 3")
.assert_success();
}
#[test]
fn test_update_double_decrement() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val INT)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(5)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val - 1")
.assert_success()
.assert_vertex_props(1, "Counter", HashMap::from([("val", Value::Int(4))]))
.exec_dml("UPDATE 1 ON Counter SET val = val - 1")
.assert_success()
.assert_vertex_props(1, "Counter", HashMap::from([("val", Value::Int(3))]));
}
#[test]
fn test_update_arithmetic_multiple_fields() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, a INT, b INT, total INT)")
.exec_dml("INSERT VERTEX Counter(a, b, total) VALUES 1:(3, 7, 0)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET total = a + b")
.assert_success()
.assert_vertex_props(
1,
"Counter",
HashMap::from([
("a", Value::Int(3)),
("b", Value::Int(7)),
("total", Value::Int(10)),
]),
);
}
#[test]
fn test_update_arithmetic_chain() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Calc(id INT, val INT)")
.exec_dml("INSERT VERTEX Calc(val) VALUES 1:(2)")
.assert_success()
.exec_dml("UPDATE 1 ON Calc SET val = val * 2 + 1")
.assert_success()
.assert_vertex_props(1, "Calc", HashMap::from([("val", Value::Int(5))]));
}
#[test]
fn test_update_property_to_null() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET age = NULL")
.assert_success();
}
#[test]
fn test_update_when_false_condition() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET age = 99 WHEN age > 100")
.assert_success()
.assert_vertex_props(1, "Person", HashMap::from([("age", Value::Int(30))]));
}
#[test]
fn test_update_edge_ranked() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE, strength DOUBLE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since, strength) VALUES 1 -> 2 @0:('2020-01-01', 0.5)")
.assert_success()
.exec_dml("UPDATE 1 -> 2 OF KNOWS SET strength = 0.9")
.assert_success()
.query("FETCH PROP ON KNOWS 1 -> 2")
.assert_vertex_or_edge_has_property("strength", Value::Double(0.9));
}
#[test]
fn test_update_yield_parser() {
let query = "UPDATE 1 ON Person SET name = 'Bob' YIELD name, age";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE with YIELD parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_yield_execution() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET name = 'Bob', age = 35 YIELD name, age");
assert!(
scenario
.error()
.is_some_and(|e| e.contains("YIELD is not supported")),
"UPDATE with YIELD should fail explicitly, got: {:?}",
scenario.error()
);
scenario.assert_error();
}
#[test]
fn test_update_edge_with_when_condition() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE, strength DOUBLE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since, strength) VALUES 1 -> 2:('2020-01-01', 0.5)")
.assert_success()
.exec_dml("UPDATE 1 -> 2 OF KNOWS SET strength = 1.0 WHEN strength < 0.8")
.assert_success()
.query("FETCH PROP ON KNOWS 1 -> 2")
.assert_vertex_or_edge_has_property("strength", Value::Double(1.0));
}
#[test]
fn test_update_edge_when_false_condition() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE, strength DOUBLE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since, strength) VALUES 1 -> 2:('2020-01-01', 0.9)")
.assert_success()
.exec_dml("UPDATE 1 -> 2 OF KNOWS SET strength = 1.0 WHEN strength < 0.8")
.assert_success()
.query("FETCH PROP ON KNOWS 1 -> 2")
.assert_vertex_or_edge_has_property("strength", Value::Double(0.9));
}
#[test]
fn test_update_nonexistent_edge() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("UPDATE 1 -> 2 OF KNOWS SET since = '2024-01-01'")
.assert_error();
}
#[test]
fn test_update_edge_yield_parser() {
let query = "UPDATE EDGE 1 -> 2 OF KNOWS SET since = '2024-01-01' YIELD since";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE EDGE with YIELD parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_edge_yield_execution() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since DATE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml("INSERT EDGE KNOWS(since) VALUES 1 -> 2:('2024-01-01')")
.assert_success()
.exec_dml("UPDATE EDGE 1 -> 2 OF KNOWS SET since = '2024-06-01' YIELD since");
assert!(
scenario
.error()
.is_some_and(|e| e.contains("YIELD is not supported")),
"UPDATE EDGE with YIELD should fail explicitly, got: {:?}",
scenario.error()
);
scenario.assert_error();
}
#[test]
fn test_update_divide_by_zero() {
use crate::common::TestStorage;
use linkrs_metrics::StatsManager;
use linkrs_query::optimizer::OptimizerEngine;
use linkrs_query::pipeline::QueryPipelineManager;
use linkrs_query::storage::{StorageReader, StorageSchemaContextOps};
use std::sync::Arc;
let test_storage = TestStorage::new().expect("Failed to create test storage");
let storage = test_storage.storage();
let stats_manager = Arc::new(StatsManager::new());
let optimizer = Arc::new(OptimizerEngine::default());
let schema_manager = {
let storage_guard = storage.write();
storage_guard
.get_schema_manager()
.expect("Storage should provide a schema manager")
};
let mut pipeline =
QueryPipelineManager::with_optimizer(storage.clone(), stats_manager, optimizer)
.with_schema_manager(schema_manager);
let space_name = "test_space";
let create_space = format!("CREATE SPACE IF NOT EXISTS {}", space_name);
pipeline
.execute_query(&create_space)
.expect("Failed to create space");
let space_info = {
let storage_guard = storage.read();
storage_guard
.get_space(space_name)
.expect("Failed to get space")
.expect("Space not found")
};
let create_tag = "CREATE TAG Counter(id INT, val INT)";
pipeline
.execute_query_with_space(create_tag, Some(space_info.clone()))
.expect("Failed to create tag");
let insert = "INSERT VERTEX Counter(val) VALUES 1:(10)";
pipeline
.execute_query_with_space(insert, Some(space_info.clone()))
.expect("Failed to insert vertex");
let update = "UPDATE 1 ON Counter SET val = val / 0";
let result = pipeline.execute_query_with_space(update, Some(space_info.clone()));
assert!(
result.is_err(),
"UPDATE with division by zero should return an error, got {:?}",
result
);
}
#[test]
fn test_update_null_arithmetic() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Counter(id INT, val INT NULL)")
.exec_dml("INSERT VERTEX Counter(val) VALUES 1:(NULL)")
.assert_success()
.exec_dml("UPDATE 1 ON Counter SET val = val + 1")
.assert_error();
}
#[test]
fn test_update_map_overwrite_executes_replace() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET v = {age: 20}")
.assert_success()
.assert_vertex_prop_absent(1, "Person", "name");
}
#[test]
fn test_update_map_overwrite_replaces_row() {
let mut expected = HashMap::new();
expected.insert("age", Value::Int(20));
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET v = {age: 20}")
.assert_success()
.assert_vertex_props(1, "Person", expected)
.assert_vertex_prop_absent(1, "Person", "name");
}
#[test]
fn test_update_map_overwrite_empty_clears_row() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET v = {}")
.assert_success()
.assert_vertex_prop_absent(1, "Person", "name")
.assert_vertex_prop_absent(1, "Person", "age");
}
#[test]
fn test_update_mixed_map_and_property_overlays() {
let mut expected = HashMap::new();
expected.insert("age", Value::Int(20));
expected.insert("name", Value::string("Bob"));
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET v = {age: 20}, name = 'Bob'")
.assert_success()
.assert_vertex_props(1, "Person", expected);
}
#[test]
fn test_update_unrelated_alias_reference_stays_rejected() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET age = w.age + 1")
.assert_error();
}
#[test]
fn test_update_variable_vid_is_rejected_with_precise_error() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE v ON Person SET age = 31");
let error = scenario.error().expect("Variable vid should be rejected");
assert!(
error.contains("Standalone UPDATE vid"),
"unexpected error: {error}"
);
}
#[test]
fn test_update_complex_vid_expression_is_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 + 2 ON Person SET age = 31");
let error = scenario.error().expect("Complex vid should be rejected");
assert!(
error.contains("Standalone UPDATE vid"),
"unexpected error: {error}"
);
}
#[test]
fn test_update_tag_bulk_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE TAG Person SET age = 31");
assert!(
scenario
.error()
.is_some_and(|e| e.contains("not supported yet")),
"UPDATE TAG bulk update should fail explicitly, got: {:?}",
scenario.error()
);
scenario.assert_error();
}
#[test]
fn test_update_yield_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING, age INT)")
.exec_dml("INSERT VERTEX Person(name, age) VALUES 1:('Alice', 30)")
.assert_success()
.exec_dml("UPDATE 1 ON Person SET age = 31 YIELD age");
assert!(
scenario
.error()
.is_some_and(|e| e.contains("YIELD is not supported")),
"UPDATE with YIELD should fail explicitly, got: {:?}",
scenario.error()
);
scenario.assert_error();
}
#[test]
fn test_update_edge_expression_endpoints_parser() {
let query = "UPDATE EDGE v -> dst OF KNOWS SET degree = 1.0";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE EDGE with expression endpoints parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_edge_expression_endpoints_with_rank_parser() {
let query = "UPDATE EDGE v -> dst @0 OF KNOWS SET degree = 1.0";
let mut parser = Parser::new(query);
let result = parser.parse();
assert!(
result.is_ok(),
"UPDATE EDGE with expression endpoints and rank parsing should succeed: {:?}",
result.err()
);
let stmt = result.expect("UPDATE statement parsing should succeed");
assert_eq!(stmt.ast.stmt.kind(), "UPDATE");
}
#[test]
fn test_update_edge_variable_endpoints_execution_rejected() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since INT)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.assert_success()
.exec_dml("UPDATE EDGE v -> dst OF KNOWS SET since = 2024")
.assert_error();
}
#[test]
fn test_update_edge_mixed_map_and_property_with_rank() {
let mut expected = HashMap::new();
expected.insert("degree", Value::Double(1.0));
expected.insert("since", Value::Int(2022));
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TAG Person(id INT, name STRING)")
.exec_ddl("CREATE EDGE KNOWS(since INT, degree DOUBLE)")
.exec_dml("INSERT VERTEX Person(name) VALUES 1:('Alice'), 2:('Bob')")
.exec_dml(
"INSERT EDGE KNOWS(since, degree) VALUES 1 -> 2 @0:(2020, 0.5), 1 -> 2 @1:(2021, 0.9)",
)
.assert_success()
.exec_dml("UPDATE EDGE 1 -> 2 @1 OF KNOWS SET e = {degree: 1.0}, since = 2022")
.assert_success()
.exec_dml("DELETE EDGE 1 -> 2 @0 OF KNOWS")
.assert_success()
.assert_edge_count("KNOWS", 1)
.assert_edge_props(1, 2, "KNOWS", expected);
}