use ankurah_storage_sqlite::SqliteStorageEngine;
use anyhow::Result;
async fn query_bool(sql: &str) -> Result<bool> {
let engine = SqliteStorageEngine::open_in_memory().await?;
let conn = engine.pool().get().await.map_err(|e| anyhow::anyhow!("{}", e))?;
let sql = sql.to_owned();
let result = conn
.with_connection(move |c| {
let value: i32 = c.query_row(&sql, [], |row| row.get(0))?;
Ok(value != 0)
})
.await?;
Ok(result)
}
#[tokio::test]
async fn test_json_extract_numeric_comparison_is_numeric() -> Result<()> {
let result = query_bool("SELECT json_extract('{\"n\": 9}', '$.n') > json_extract('{\"n\": 10}', '$.n')").await?;
assert!(!result, "json_extract numeric comparison should be numeric, not lexicographic: 9 > 10 should be false");
let result = query_bool("SELECT json_extract('{\"n\": 9}', '$.n') < json_extract('{\"n\": 10}', '$.n')").await?;
assert!(result, "9 < 10 should be true");
let result = query_bool("SELECT json_extract('{\"n\": 100}', '$.n') > json_extract('{\"n\": 9}', '$.n')").await?;
assert!(result, "100 > 9 should be true");
Ok(())
}
#[tokio::test]
async fn test_json_extract_string_comparison_is_lexicographic() -> Result<()> {
let result = query_bool(r#"SELECT json_extract('{"s": "9"}', '$.s') > json_extract('{"s": "10"}', '$.s')"#).await?;
assert!(result, "String '9' > '10' lexicographically");
let result = query_bool(r#"SELECT json_extract('{"s": "abc"}', '$.s') < json_extract('{"s": "abd"}', '$.s')"#).await?;
assert!(result, "String 'abc' < 'abd'");
Ok(())
}
#[tokio::test]
async fn test_json_extract_cross_type_comparison() -> Result<()> {
let result = query_bool(r#"SELECT json_extract('{"n": 9}', '$.n') = json_extract('{"s": "9"}', '$.s')"#).await?;
println!("Number 9 = String '9': {}", result);
let result = query_bool(r#"SELECT json_extract('{"n": 9}', '$.n') = json_extract('{"b": true}', '$.b')"#).await?;
assert!(!result, "Number 9 should not equal boolean true");
Ok(())
}
#[tokio::test]
async fn test_json_extract_float_int_comparison() -> Result<()> {
let result = query_bool("SELECT json_extract('{\"n\": 9}', '$.n') = json_extract('{\"n\": 9.0}', '$.n')").await?;
assert!(result, "Integer 9 should equal float 9.0");
let result = query_bool("SELECT json_extract('{\"n\": 9.5}', '$.n') > json_extract('{\"n\": 9}', '$.n')").await?;
assert!(result, "9.5 > 9 should be true");
let result = query_bool("SELECT json_extract('{\"n\": 9}', '$.n') < json_extract('{\"n\": 9.1}', '$.n')").await?;
assert!(result, "9 < 9.1 should be true");
Ok(())
}
#[tokio::test]
async fn test_json_extract_null_comparison() -> Result<()> {
let result = query_bool("SELECT json_extract('{\"n\": null}', '$.n') IS NULL").await?;
assert!(result, "json_extract of JSON null should be SQL NULL");
let result = query_bool("SELECT COALESCE(json_extract('{\"n\": null}', '$.n') = 0, 0)").await?;
assert!(!result, "JSON null should not equal 0");
Ok(())
}
#[tokio::test]
async fn test_json_extract_path_with_comparison() -> Result<()> {
let result = query_bool(r#"SELECT json_extract('{"count": 9}', '$.count') > 10"#).await?;
assert!(!result, "JSON count 9 > 10 should be false");
let result = query_bool(r#"SELECT json_extract('{"count": 100}', '$.count') > 10"#).await?;
assert!(result, "JSON count 100 > 10 should be true");
let result = query_bool(r#"SELECT json_extract('{"status": "active"}', '$.status') = 'active'"#).await?;
assert!(result, "JSON status = 'active' should match");
let result = query_bool(r#"SELECT json_extract('{"user": {"name": "alice"}}', '$.user.name') = 'alice'"#).await?;
assert!(result, "Nested JSON path extraction should work");
Ok(())
}