use crate::common::create_test_evaluator;
#[test]
fn test_concat_null_propagates() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("world"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Null);
}
#[test]
fn test_concat_empty_strings() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("")));
}
#[test]
fn test_concat_single_arg() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("hello")));
}
#[test]
fn test_concat_many_args() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("a"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("b"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("c"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("d"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("e"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("abcde")));
}
#[test]
fn test_concat_integer_conversion() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("ID:"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(123)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("ID:123")));
}
#[test]
fn test_concat_no_args() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![],
character_unit: None,
};
let result = evaluator.eval(&expr, &row);
assert!(result.is_err());
}
#[test]
fn test_concat_character_type() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("CONCAT"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from(" "),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("world"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("hello world")));
}
#[test]
fn test_replace_null() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("a"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("b"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Null);
}
#[test]
fn test_replace_multiple_occurrences() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("ll"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("rr"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("herro herro")));
}
#[test]
fn test_replace_empty_search() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("x"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("xhxexlxlxox")));
}
#[test]
fn test_replace_empty_replacement() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("l"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("heo")));
}
#[test]
fn test_replace_not_found() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("xyz"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("abc"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("hello")));
}
#[test]
fn test_replace_wrong_arg_count() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("l"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row);
assert!(result.is_err());
}
#[test]
fn test_replace_wrong_type() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(123)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("x"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("hello")));
}
#[test]
fn test_replace_character_type() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REPLACE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("l"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("r"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("herro")));
}
#[test]
fn test_reverse_null() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null)],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Null);
}
#[test]
fn test_reverse_empty() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from(""),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("")));
}
#[test]
fn test_reverse_single_char() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("a"),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("a")));
}
#[test]
fn test_reverse_basic() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("olleh")));
}
#[test]
fn test_reverse_multibyte() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("café"),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("éfac")));
}
#[test]
fn test_reverse_wrong_arg_count() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
)),
vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("extra"),
)),
],
character_unit: None,
};
let result = evaluator.eval(&expr, &row);
assert!(result.is_err());
}
#[test]
fn test_reverse_wrong_type() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(123))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("321")));
}
#[test]
fn test_reverse_character_type() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Function {
name: vibesql_ast::FunctionIdentifier::new("REVERSE"),
args: vec![vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Character(
arcstr::ArcStr::from("test"),
))],
character_unit: None,
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("tset")));
}
#[test]
fn test_trim_null_removal_char() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Trim {
position: Some(vibesql_ast::TrimPosition::Both),
removal_char: Some(Box::new(vibesql_ast::Expression::Literal(
vibesql_types::SqlValue::Null,
))),
string: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("hello"),
))),
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Null);
}
#[test]
fn test_trim_null_string() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Trim {
position: None,
removal_char: None,
string: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null)),
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Null);
}
#[test]
fn test_trim_custom_char_multibyte() {
let (evaluator, row) = create_test_evaluator();
let expr = vibesql_ast::Expression::Trim {
position: Some(vibesql_ast::TrimPosition::Both),
removal_char: Some(Box::new(vibesql_ast::Expression::Literal(
vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("x")),
))),
string: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("xxxhelloxxx"),
))),
};
let result = evaluator.eval(&expr, &row).unwrap();
assert_eq!(result, vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("hello")));
}