use arrow::datatypes::DataType;
use llkv_result::{Error, Result};
pub fn sql_type_to_arrow(type_str: &str) -> Result<DataType> {
let normalized = type_str.trim().to_uppercase();
let base_type = if let Some(paren_pos) = normalized.find('(') {
&normalized[..paren_pos]
} else {
&normalized
};
match base_type {
"TEXT" | "VARCHAR" | "CHAR" | "STRING" => Ok(DataType::Utf8),
"INTEGER" | "INT" | "BIGINT" | "SMALLINT" | "TINYINT" => Ok(DataType::Int64),
"FLOAT" | "REAL" => Ok(DataType::Float64),
"DOUBLE" | "DOUBLE PRECISION" => Ok(DataType::Float64),
"DECIMAL" | "NUMERIC" => Ok(DataType::Float64),
"BOOLEAN" | "BOOL" => Ok(DataType::Boolean),
"DATE" => Ok(DataType::Date32),
_ => Err(Error::InvalidArgumentError(format!(
"unsupported SQL data type: '{}'",
type_str
))),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_text_types() {
assert_eq!(sql_type_to_arrow("TEXT").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("VARCHAR").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("VARCHAR(255)").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("CHAR(10)").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("STRING").unwrap(), DataType::Utf8);
}
#[test]
fn test_integer_types() {
assert_eq!(sql_type_to_arrow("INTEGER").unwrap(), DataType::Int64);
assert_eq!(sql_type_to_arrow("INT").unwrap(), DataType::Int64);
assert_eq!(sql_type_to_arrow("BIGINT").unwrap(), DataType::Int64);
assert_eq!(sql_type_to_arrow("SMALLINT").unwrap(), DataType::Int64);
assert_eq!(sql_type_to_arrow("TINYINT").unwrap(), DataType::Int64);
}
#[test]
fn test_float_types() {
assert_eq!(sql_type_to_arrow("FLOAT").unwrap(), DataType::Float64);
assert_eq!(sql_type_to_arrow("REAL").unwrap(), DataType::Float64);
assert_eq!(sql_type_to_arrow("DOUBLE").unwrap(), DataType::Float64);
assert_eq!(sql_type_to_arrow("DECIMAL").unwrap(), DataType::Float64);
assert_eq!(sql_type_to_arrow("NUMERIC").unwrap(), DataType::Float64);
}
#[test]
fn test_boolean_type() {
assert_eq!(sql_type_to_arrow("BOOLEAN").unwrap(), DataType::Boolean);
assert_eq!(sql_type_to_arrow("BOOL").unwrap(), DataType::Boolean);
}
#[test]
fn test_date_type() {
assert_eq!(sql_type_to_arrow("DATE").unwrap(), DataType::Date32);
}
#[test]
fn test_case_insensitive() {
assert_eq!(sql_type_to_arrow("varchar").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("VarChar").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("INTEGER").unwrap(), DataType::Int64);
assert_eq!(sql_type_to_arrow("integer").unwrap(), DataType::Int64);
}
#[test]
fn test_whitespace_handling() {
assert_eq!(sql_type_to_arrow(" VARCHAR ").unwrap(), DataType::Utf8);
assert_eq!(sql_type_to_arrow("\tINTEGER\n").unwrap(), DataType::Int64);
}
#[test]
fn test_unsupported_type() {
assert!(sql_type_to_arrow("BLOB").is_err());
assert!(sql_type_to_arrow("GEOMETRY").is_err());
}
}