From bb158a54334da6e91d514ac5db70aa0fc168c235 Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Thu, 8 May 2025 23:12:11 -0300 Subject: [PATCH] add unique field to Column --- core/schema.rs | 16 ++++++++++++++++ core/translate/group_by.rs | 1 + core/translate/order_by.rs | 2 ++ core/translate/plan.rs | 1 + core/translate/schema.rs | 2 +- core/util.rs | 8 +++++++- 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/core/schema.rs b/core/schema.rs index 9b1163a97..0961bcb8c 100644 --- a/core/schema.rs +++ b/core/schema.rs @@ -259,6 +259,7 @@ impl PseudoTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }); } pub fn get_column(&self, name: &str) -> Option<(usize, &Column)> { @@ -365,6 +366,7 @@ fn create_table( let mut primary_key = false; let mut notnull = false; let mut order = SortOrder::Asc; + let mut unique = false; for c_def in &col_def.constraints { match &c_def.constraint { limbo_sqlite3_parser::ast::ColumnConstraint::PrimaryKey { @@ -382,6 +384,10 @@ fn create_table( limbo_sqlite3_parser::ast::ColumnConstraint::Default(expr) => { default = Some(expr.clone()) } + // TODO: for now we don't check Resolve type of unique + limbo_sqlite3_parser::ast::ColumnConstraint::Unique(..) => { + unique = true; + } _ => {} } } @@ -403,6 +409,7 @@ fn create_table( is_rowid_alias: typename_exactly_integer && primary_key, notnull, default, + unique, }); } if options.contains(TableOptions::WITHOUT_ROWID) { @@ -456,6 +463,7 @@ pub struct Column { pub is_rowid_alias: bool, pub notnull: bool, pub default: Option, + pub unique: bool, } impl Column { @@ -658,6 +666,7 @@ pub fn sqlite_schema_table() -> BTreeTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }, Column { name: Some("name".to_string()), @@ -667,6 +676,7 @@ pub fn sqlite_schema_table() -> BTreeTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }, Column { name: Some("tbl_name".to_string()), @@ -676,6 +686,7 @@ pub fn sqlite_schema_table() -> BTreeTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }, Column { name: Some("rootpage".to_string()), @@ -685,6 +696,7 @@ pub fn sqlite_schema_table() -> BTreeTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }, Column { name: Some("sql".to_string()), @@ -694,6 +706,7 @@ pub fn sqlite_schema_table() -> BTreeTable { is_rowid_alias: false, notnull: false, default: None, + unique: false, }, ], } @@ -775,6 +788,8 @@ impl Index { )); } + // let unique_columns = + let index_columns = table .primary_key_columns .iter() @@ -1188,6 +1203,7 @@ mod tests { is_rowid_alias: false, notnull: false, default: None, + unique: false, }], }; diff --git a/core/translate/group_by.rs b/core/translate/group_by.rs index 0034bc172..9bb10a57e 100644 --- a/core/translate/group_by.rs +++ b/core/translate/group_by.rs @@ -216,6 +216,7 @@ pub fn group_by_create_pseudo_table( is_rowid_alias: false, notnull: false, default: None, + unique: false, }) .collect::>(); diff --git a/core/translate/order_by.rs b/core/translate/order_by.rs index 5260e8286..6c8f4d90a 100644 --- a/core/translate/order_by.rs +++ b/core/translate/order_by.rs @@ -72,6 +72,7 @@ pub fn emit_order_by( is_rowid_alias: false, notnull: false, default: None, + unique: false, }); } for i in 0..result_columns.len() { @@ -90,6 +91,7 @@ pub fn emit_order_by( is_rowid_alias: false, notnull: false, default: None, + unique: false, }); } diff --git a/core/translate/plan.rs b/core/translate/plan.rs index 2a047b3a1..29d192b1c 100644 --- a/core/translate/plan.rs +++ b/core/translate/plan.rs @@ -597,6 +597,7 @@ impl TableReference { primary_key: false, notnull: false, default: None, + unique: false, }) .collect(), ))); diff --git a/core/translate/schema.rs b/core/translate/schema.rs index d4060b11c..003006c9c 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -358,7 +358,7 @@ fn check_automatic_pk_index_required( is_descending, } => { let is_integer = - typename.is_some() && typename.unwrap().to_uppercase() == "INTEGER"; + typename.is_some() && typename.unwrap().eq_ignore_ascii_case("INTEGER"); // Should match on any case of INTEGER !is_integer || *is_descending } PrimaryKeyDefinitionType::Composite => true, diff --git a/core/util.rs b/core/util.rs index b48773ed8..b5380271b 100644 --- a/core/util.rs +++ b/core/util.rs @@ -121,7 +121,7 @@ pub fn parse_schema_rows( }); } _ => { - // Automatic index on primary key, e.g. + // Automatic index on primary key and/or unique constraint, e.g. // table|foo|foo|2|CREATE TABLE foo (a text PRIMARY KEY, b) // index|sqlite_autoindex_foo_1|foo|3| let index_name = row.get::<&str>(1)?.to_string(); @@ -559,6 +559,12 @@ pub fn columns_from_create_table_body(body: &ast::CreateTableBody) -> crate::Res ) }), is_rowid_alias: false, + unique: column_def.constraints.iter().any(|c| { + matches!( + c.constraint, + limbo_sqlite3_parser::ast::ColumnConstraint::Unique(..) + ) + }), }; Some(column) })