diff --git a/core/schema.rs b/core/schema.rs index b2fa66b31..a26e83a55 100644 --- a/core/schema.rs +++ b/core/schema.rs @@ -906,37 +906,10 @@ fn create_table( let mut typename_exactly_integer = false; let ty = match col_type { - Some(data_type) => 'ty: { - // https://www.sqlite.org/datatype3.html - let mut type_name = data_type.name.clone(); - type_name.make_ascii_uppercase(); - - if type_name.is_empty() { - break 'ty Type::Blob; - } - - if type_name == "INTEGER" { - typename_exactly_integer = true; - break 'ty Type::Integer; - } - - if let Some(ty) = type_name.as_bytes().windows(3).find_map(|s| match s { - b"INT" => Some(Type::Integer), - _ => None, - }) { - break 'ty ty; - } - - if let Some(ty) = type_name.as_bytes().windows(4).find_map(|s| match s { - b"CHAR" | b"CLOB" | b"TEXT" => Some(Type::Text), - b"BLOB" => Some(Type::Blob), - b"REAL" | b"FLOA" | b"DOUB" => Some(Type::Real), - _ => None, - }) { - break 'ty ty; - } - - Type::Numeric + Some(data_type) => { + let (ty, ei) = type_from_name(&data_type.name); + typename_exactly_integer = ei; + ty } None => Type::Null, }; @@ -1103,10 +1076,7 @@ impl From for Column { } let ty = match value.col_type { - Some(ref data_type) => { - // https://www.sqlite.org/datatype3.html - type_from_name(&data_type.name) - } + Some(ref data_type) => type_from_name(&data_type.name).0, None => Type::Null, }; diff --git a/core/util.rs b/core/util.rs index 4d3668db5..208fffbbb 100644 --- a/core/util.rs +++ b/core/util.rs @@ -662,25 +662,34 @@ pub fn exprs_are_equivalent(expr1: &Expr, expr2: &Expr) -> bool { } } -pub(crate) fn type_from_name(type_name: &str) -> Type { +// this function returns the affinity type and whether the type name was exactly "INTEGER" +// https://www.sqlite.org/datatype3.html +pub(crate) fn type_from_name(type_name: &str) -> (Type, bool) { let type_name = type_name.as_bytes(); - if contains_ignore_ascii_case!(type_name, b"INT") { - Type::Integer - } else if contains_ignore_ascii_case!(type_name, b"CHAR") - || contains_ignore_ascii_case!(type_name, b"CLOB") - || contains_ignore_ascii_case!(type_name, b"TEXT") - { - Type::Text - } else if contains_ignore_ascii_case!(type_name, b"BLOB") || type_name.is_empty() { - Type::Blob - } else if contains_ignore_ascii_case!(type_name, b"REAL") - || contains_ignore_ascii_case!(type_name, b"FLOA") - || contains_ignore_ascii_case!(type_name, b"DOUB") - { - Type::Real - } else { - Type::Numeric + if type_name.is_empty() { + return (Type::Blob, false); } + + if eq_ignore_ascii_case!(type_name, b"INTEGER") { + return (Type::Integer, true); + } + + if let Some(ty) = type_name.windows(4).find_map(|s| { + if contains_ignore_ascii_case!(s, b"INT") { + return Some(Type::Integer); + } + + match_ignore_ascii_case!(match s { + b"CHAR" | b"CLOB" | b"TEXT" => Some(Type::Text), + b"BLOB" => Some(Type::Blob), + b"REAL" | b"FLOA" | b"DOUB" => Some(Type::Real), + _ => None, + }) + }) { + return (ty, false); + } + + (Type::Numeric, false) } pub fn columns_from_create_table_body( @@ -705,10 +714,7 @@ pub fn columns_from_create_table_body( Column { name: Some(normalize_ident(name.as_str())), ty: match col_type { - Some(ref data_type) => { - // https://www.sqlite.org/datatype3.html - type_from_name(data_type.name.as_str()) - } + Some(ref data_type) => type_from_name(data_type.name.as_str()).0, None => Type::Null, }, default: constraints.iter().find_map(|c| match &c.constraint {