faster type_from_name

This commit is contained in:
TcMits
2025-09-01 14:38:38 +07:00
parent ed1fb4cabc
commit 6e87b08d64
2 changed files with 32 additions and 56 deletions

View File

@@ -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<ColumnDefinition> 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,
};

View File

@@ -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 {