From 0cdf54a8c7704f0eda8ceec9cf8dbcc4fe95d1f9 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 4 Sep 2023 21:19:12 +0300 Subject: [PATCH] Fix column affinity detection As it turns out, column affinity is tricky in SQLite... https://www.sqlite.org/datatype3.html#determination_of_column_affinity --- core/schema.rs | 35 ++++++++++++++++++++++++++--------- core/sqlite3_ondisk.rs | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/core/schema.rs b/core/schema.rs index 74f975562..139b381e6 100644 --- a/core/schema.rs +++ b/core/schema.rs @@ -47,13 +47,28 @@ impl Table { for column in columns { let name = column.col_name.0.to_string(); let ty = match column.col_type { - Some(data_type) => match data_type.name.as_str() { - "INT" => Type::Integer, - "REAL" => Type::Real, - "TEXT" => Type::Text, - "BLOB" => Type::Blob, - _ => unreachable!("Unknown type: {:?}", data_type.name), - }, + Some(data_type) => { + let type_name = data_type.name.as_str(); + if type_name.contains("INT") { + Type::Integer + } else if type_name.contains("CHAR") + || type_name.contains("CLOB") + || type_name.contains("TEXT") + { + Type::Text + } else if type_name.contains("BLOB") + || type_name.is_empty() + { + Type::Blob + } else if type_name.contains("REAL") + || type_name.contains("FLOA") + || type_name.contains("DOUB") + { + Type::Real + } else { + Type::Numeric + } + } None => Type::Null, }; cols.push(Column { name, ty }); @@ -104,9 +119,10 @@ pub struct Column { pub enum Type { Null, + Text, + Numeric, Integer, Real, - Text, Blob, } @@ -114,9 +130,10 @@ impl fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match self { Type::Null => "NULL", + Type::Text => "TEXT", + Type::Numeric => "NUMERIC", Type::Integer => "INTEGER", Type::Real => "REAL", - Type::Text => "TEXT", Type::Blob => "BLOB", }; write!(f, "{}", s) diff --git a/core/sqlite3_ondisk.rs b/core/sqlite3_ondisk.rs index 745158a3f..1d2d6d879 100644 --- a/core/sqlite3_ondisk.rs +++ b/core/sqlite3_ondisk.rs @@ -321,4 +321,4 @@ fn read_varint(buf: &[u8]) -> (u64, usize) { } v = (v << 8) + buf[8] as u64; (v, 9) -} \ No newline at end of file +}