use serde_json::json;
use sql_cli::data::csv_datasource::CsvApiClient;
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Testing scientific notation in numeric comparisons");
println!("{}", "=".repeat(60));
let scientific_data = json!([
{
"id": 1,
"name": "Small value",
"value": "1e-4", "amount": "1.5e3" },
{
"id": 2,
"name": "Medium value",
"value": "5E-2", "amount": "2.5E+3" },
{
"id": 3,
"name": "Large value",
"value": "3.14159", "amount": "1e6" },
{
"id": 4,
"name": "Tiny value",
"value": "2.718e-10", "amount": "9.8E1" },
{
"id": 5,
"name": "Invalid",
"value": "NaN", "amount": "infinity" }
]);
let temp_dir = std::env::temp_dir();
let temp_file = temp_dir.join("scientific_test.json");
fs::write(&temp_file, scientific_data.to_string())?;
let mut client = CsvApiClient::new();
client.load_json(&temp_file, "scientific")?;
let test_queries = vec![
("All records", "SELECT * FROM scientific"),
(
"value > 0.001 (values larger than 1e-3)",
"SELECT * FROM scientific WHERE value > 0.001",
),
(
"value < 0.1 (values less than 0.1)",
"SELECT * FROM scientific WHERE value < 0.1",
),
(
"value BETWEEN 0.00001 AND 1",
"SELECT * FROM scientific WHERE value BETWEEN 0.00001 AND 1",
),
(
"amount > 1000 (amounts larger than 1000)",
"SELECT * FROM scientific WHERE amount > 1000",
),
(
"amount = 1500 (exact match with 1.5e3)",
"SELECT * FROM scientific WHERE amount = 1500",
),
(
"amount < 100 (amounts less than 100)",
"SELECT * FROM scientific WHERE amount < 100",
),
(
"Complex: value < 0.01 AND amount > 100",
"SELECT * FROM scientific WHERE value < 0.01 AND amount > 100",
),
];
for (description, query) in test_queries {
println!("\n{}", "-".repeat(60));
println!("Query: {description}");
println!("SQL: {query}");
match client.query_csv(query) {
Ok(result) => {
println!("Result count: {} rows", result.data.len());
for row in &result.data {
if let Some(obj) = row.as_object() {
let id = obj
.get("id")
.and_then(serde_json::Value::as_i64)
.unwrap_or(0);
let name = obj.get("name").and_then(|v| v.as_str()).unwrap_or("");
let value = obj.get("value").map(|v| format!("{v}")).unwrap_or_default();
let amount = obj
.get("amount")
.map(|v| format!("{v}"))
.unwrap_or_default();
println!(" Row {id}: {name} - value={value}, amount={amount}");
}
}
}
Err(e) => {
println!("Error: {e}");
}
}
}
let _ = fs::remove_file(&temp_file);
Ok(())
}