use super::super::super::*;
#[test]
fn test_cast_integer_to_varchar() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(
123,
))),
data_type: vibesql_types::DataType::Varchar { max_length: Some(10) },
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Varchar(arcstr::ArcStr::from("123")));
}
#[test]
fn test_cast_varchar_to_integer() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("456"),
))),
data_type: vibesql_types::DataType::Integer,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Integer(456));
}
#[test]
fn test_cast_null() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Null)),
data_type: vibesql_types::DataType::Integer,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Null);
}
#[test]
fn test_cast_integer_to_unsigned() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(
42,
))),
data_type: vibesql_types::DataType::Unsigned,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Unsigned(42));
}
#[test]
fn test_cast_negative_integer_to_unsigned() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(
-1,
))),
data_type: vibesql_types::DataType::Unsigned,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Unsigned(u64::MAX));
}
#[test]
fn test_cast_varchar_to_unsigned() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Varchar(
arcstr::ArcStr::from("123"),
))),
data_type: vibesql_types::DataType::Unsigned,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Unsigned(123));
}
#[test]
fn test_cast_float_to_unsigned() {
let mut db = vibesql_storage::Database::new();
db.set_sql_mode(vibesql_types::SqlMode::MySQL {
flags: vibesql_types::MySqlModeFlags::default(),
});
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Float(
5.7,
))),
data_type: vibesql_types::DataType::Unsigned,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Unsigned(6));
}
#[test]
fn test_cast_as_signed_positive() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(
42,
))),
data_type: vibesql_types::DataType::Bigint,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Bigint(42));
assert_eq!(format!("{}", result[0].values[0]), "42");
}
#[test]
fn test_cast_as_signed_negative() {
let db = vibesql_storage::Database::new();
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Integer(
-4,
))),
data_type: vibesql_types::DataType::Bigint,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Bigint(-4));
assert_eq!(format!("{}", result[0].values[0]), "-4");
}
#[test]
fn test_cast_as_signed_from_float() {
let mut db = vibesql_storage::Database::new();
db.set_sql_mode(vibesql_types::SqlMode::MySQL {
flags: vibesql_types::MySqlModeFlags::default(),
});
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Float(
5.7,
))),
data_type: vibesql_types::DataType::Bigint,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Bigint(6));
assert_eq!(format!("{}", result[0].values[0]), "6");
}
#[test]
fn test_cast_negative_float_to_signed_rounds() {
let mut db = vibesql_storage::Database::new();
db.set_sql_mode(vibesql_types::SqlMode::MySQL {
flags: vibesql_types::MySqlModeFlags::default(),
});
let executor = SelectExecutor::new(&db);
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(vibesql_types::SqlValue::Numeric(
-0.7,
))),
data_type: vibesql_types::DataType::Bigint,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].values[0], vibesql_types::SqlValue::Bigint(-1));
}
#[test]
fn test_cast_rounding_edge_cases() {
let mut db = vibesql_storage::Database::new();
db.set_sql_mode(vibesql_types::SqlMode::MySQL {
flags: vibesql_types::MySqlModeFlags::default(),
});
let executor = SelectExecutor::new(&db);
let cast_to_signed = |value: f64| -> i64 {
let stmt = vibesql_ast::SelectStmt {
with_clause: None,
set_operation: None,
values: None,
distinct: false,
select_list: vec![vibesql_ast::SelectItem::Expression {
expr: vibesql_ast::Expression::Cast {
expr: Box::new(vibesql_ast::Expression::Literal(
vibesql_types::SqlValue::Numeric(value),
)),
data_type: vibesql_types::DataType::Bigint,
},
alias: Some("result".to_string()),
source_text: None,
}],
from: None,
where_clause: None,
group_by: None,
having: None,
window_definitions: None,
order_by: None,
limit: None,
offset: None,
into_table: None,
into_variables: None,
};
let result = executor.execute(&stmt).unwrap();
match &result[0].values[0] {
vibesql_types::SqlValue::Bigint(n) => *n,
_ => panic!("Expected Bigint"),
}
};
assert_eq!(cast_to_signed(0.4), 0); assert_eq!(cast_to_signed(0.5), 1); assert_eq!(cast_to_signed(0.7), 1);
assert_eq!(cast_to_signed(-0.4), 0); assert_eq!(cast_to_signed(-0.5), -1); assert_eq!(cast_to_signed(-0.7), -1); }