Skip to content

Commit cb9af34

Browse files
committed
Accept compact persisted definitions
1 parent 9259d9c commit cb9af34

1 file changed

Lines changed: 52 additions & 2 deletions

File tree

sidemantic-rs/src/ffi.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ fn starts_with_definition_keyword(sql: &str, keyword: &str) -> bool {
412412
trimmed[keyword.len()..]
413413
.chars()
414414
.next()
415-
.map(|ch| ch.is_whitespace())
415+
.map(|ch| ch.is_whitespace() || ch == '(')
416416
.unwrap_or(true)
417417
}
418418

@@ -461,7 +461,7 @@ fn keyword_matches_at(bytes: &[u8], idx: usize, keyword: &[u8]) -> bool {
461461

462462
bytes
463463
.get(idx + keyword.len())
464-
.map(|byte| byte.is_ascii_whitespace())
464+
.map(|byte| byte.is_ascii_whitespace() || *byte == b'(')
465465
.unwrap_or(true)
466466
}
467467

@@ -1887,6 +1887,56 @@ models:
18871887
remove_definitions_file(&db_path);
18881888
}
18891889

1890+
#[test]
1891+
fn test_compact_parenthesized_definitions_are_detected_for_persistence_updates() {
1892+
let _guard = test_lock();
1893+
sidemantic_clear();
1894+
1895+
let db_path = unique_db_path("compact_parenthesized_persistence");
1896+
let db_path = CString::new(db_path.to_string_lossy().to_string()).unwrap();
1897+
remove_definitions_file(&db_path);
1898+
let definitions_path = get_definitions_path(db_path.as_ptr()).unwrap();
1899+
1900+
let model = CString::new("MODEL(name orders, table orders, primary_key order_id)").unwrap();
1901+
assert_success(sidemantic_define(model.as_ptr(), db_path.as_ptr(), false));
1902+
1903+
let old_metric = CString::new("METRIC(name revenue, agg sum, sql gross_amount)").unwrap();
1904+
assert_success(sidemantic_add_definition(
1905+
old_metric.as_ptr(),
1906+
db_path.as_ptr(),
1907+
false,
1908+
));
1909+
1910+
let new_metric = CString::new("METRIC(name revenue, agg sum, sql net_amount)").unwrap();
1911+
assert_success(sidemantic_add_definition(
1912+
new_metric.as_ptr(),
1913+
db_path.as_ptr(),
1914+
true,
1915+
));
1916+
1917+
let content = fs::read_to_string(&definitions_path).unwrap();
1918+
assert_eq!(
1919+
content.matches("METRIC(name revenue").count(),
1920+
1,
1921+
"{content}"
1922+
);
1923+
assert!(!content.contains("gross_amount"), "{content}");
1924+
assert!(content.contains("net_amount"), "{content}");
1925+
1926+
sidemantic_clear();
1927+
assert_success(sidemantic_autoload(db_path.as_ptr()));
1928+
1929+
let rewritten = take_rewrite_sql(sidemantic_rewrite(
1930+
CString::new("SELECT orders.revenue FROM orders")
1931+
.unwrap()
1932+
.as_ptr(),
1933+
));
1934+
assert!(rewritten.contains("net_amount"), "{rewritten}");
1935+
assert!(!rewritten.contains("gross_amount"), "{rewritten}");
1936+
1937+
remove_definitions_file(&db_path);
1938+
}
1939+
18901940
#[test]
18911941
fn test_prefixed_definition_persists_under_target_model_block() {
18921942
let _guard = test_lock();

0 commit comments

Comments
 (0)