use vibesql_ast::Expression;
use vibesql_catalog::{ColumnSchema, TableSchema};
use vibesql_executor::ExpressionEvaluator;
use vibesql_storage::Row;
use vibesql_types::{DataType, SqlValue};
fn create_test_schema() -> TableSchema {
TableSchema::new(
"test_table".to_string(),
vec![ColumnSchema::new("id".to_string(), DataType::Integer, false)],
)
}
fn eval_expr(expr: Expression) -> Result<SqlValue, String> {
let schema = create_test_schema();
let evaluator = ExpressionEvaluator::new(&schema);
let row = Row::new(vec![SqlValue::Integer(1)]);
evaluator.eval(&expr, &row).map_err(|e| format!("{:?}", e))
}
#[test]
fn test_st_simplify_linestring() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_ASTEXT"),
args: vec![Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![
Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"LINESTRING(0 0, 1 0.1, 2 0, 3 0)",
)))],
character_unit: None,
},
Expression::Literal(SqlValue::Double(0.5)), ],
character_unit: None,
}],
character_unit: None,
};
let result = eval_expr(expr).unwrap();
if let SqlValue::Varchar(s) | SqlValue::Character(s) = result {
assert!(s.contains("LINESTRING"), "Expected LINESTRING, got {}", s);
} else {
panic!("Expected Varchar, got {:?}", result);
}
}
#[test]
fn test_st_simplify_polygon() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_ASTEXT"),
args: vec![Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![
Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"POLYGON((0 0, 10 0, 10.1 5, 10 10, 0 10, 0 0))",
)))],
character_unit: None,
},
Expression::Literal(SqlValue::Double(1.0)), ],
character_unit: None,
}],
character_unit: None,
};
let result = eval_expr(expr).unwrap();
if let SqlValue::Varchar(s) | SqlValue::Character(s) = result {
assert!(s.contains("POLYGON"), "Expected POLYGON, got {}", s);
} else {
panic!("Expected Varchar, got {:?}", result);
}
}
#[test]
fn test_st_simplify_null_handling() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![Expression::Literal(SqlValue::Null), Expression::Literal(SqlValue::Double(0.1))],
character_unit: None,
};
let result = eval_expr(expr).unwrap();
assert!(matches!(result, SqlValue::Null), "Expected NULL, got {:?}", result);
}
#[test]
fn test_st_simplify_zero_tolerance() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_ASTEXT"),
args: vec![Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![
Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"LINESTRING(0 0, 1 1, 2 2)",
)))],
character_unit: None,
},
Expression::Literal(SqlValue::Double(0.0)), ],
character_unit: None,
}],
character_unit: None,
};
let result = eval_expr(expr).unwrap();
if let SqlValue::Varchar(s) | SqlValue::Character(s) = result {
assert!(s.contains("LINESTRING"), "Expected LINESTRING, got {}", s);
} else {
panic!("Expected Varchar, got {:?}", result);
}
}
#[test]
fn test_st_simplify_wrong_arity() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"LINESTRING(0 0, 1 1)",
)))],
character_unit: None,
}],
character_unit: None,
};
let result = eval_expr(expr);
assert!(result.is_err(), "Expected error for wrong arity");
}
#[test]
fn test_st_simplify_negative_tolerance() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![
Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"LINESTRING(0 0, 1 1)",
)))],
character_unit: None,
},
Expression::Literal(SqlValue::Double(-1.0)), ],
character_unit: None,
};
let result = eval_expr(expr);
assert!(result.is_err(), "Expected error for negative tolerance");
}
#[test]
fn test_st_simplify_with_integer_tolerance() {
let expr = Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_ASTEXT"),
args: vec![Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_SIMPLIFY"),
args: vec![
Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("ST_GEOMFROMTEXT"),
args: vec![Expression::Literal(SqlValue::Varchar(arcstr::ArcStr::from(
"LINESTRING(0 0, 1 1, 2 2)",
)))],
character_unit: None,
},
Expression::Literal(SqlValue::Integer(1)), ],
character_unit: None,
}],
character_unit: None,
};
let result = eval_expr(expr).unwrap();
if let SqlValue::Varchar(s) | SqlValue::Character(s) = result {
assert!(s.contains("LINESTRING"), "Expected LINESTRING, got {}", s);
} else {
panic!("Expected Varchar, got {:?}", result);
}
}