diff --git a/src/analyzer/err.rs b/src/analyzer/err.rs index d87030d..f6fe2fc 100644 --- a/src/analyzer/err.rs +++ b/src/analyzer/err.rs @@ -66,7 +66,7 @@ pub enum Err { InvalidDefaultValue { raw_value: String, raw_type: String }, #[display(fmt = "Default null in non-nullable: the default value cannot be null in non-nullable field")] DefaultNullInNonNullable, - #[display(fmt = "Data type exceeded: the defualt value exceeds the maximum value of '{}'", raw_type)] + #[display(fmt = "Data type exceeded: the default value exceeds the maximum value of '{}'", raw_type)] DataTypeExceeded { raw_type: String }, #[display(fmt = "Table group not found")] TableGroupNotFound, diff --git a/src/analyzer/indexer.rs b/src/analyzer/indexer.rs index 1a6ac3a..de31b04 100644 --- a/src/analyzer/indexer.rs +++ b/src/analyzer/indexer.rs @@ -385,7 +385,7 @@ impl IndexedRef { let composition_cols = BTreeSet::from_iter(compositions.iter().map(|s| s.to_string.clone())); let indexes_cols = BTreeSet::from_iter(def_item.cols.iter().filter_map(|s| { match s { - IndexesColumnType::String(s) => Some(s.clone()), + IndexesColumnType::String(s) => Some(s.to_string.clone()), _ => None } })); diff --git a/src/analyzer/mod.rs b/src/analyzer/mod.rs index 4aa4c48..b7a6b07 100644 --- a/src/analyzer/mod.rs +++ b/src/analyzer/mod.rs @@ -145,11 +145,12 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { }) .cloned() .collect(); + let ident_strings: Vec<_> = idents.iter().map(|s| s.to_string.clone()).collect(); for ident in &def.cols { if let IndexesColumnType::String(col_name) = ident { - if table.cols.iter().find(|col| &col.name.to_string == col_name).is_none() { - throw_err(Err::ColumnNotFound, &(0..0), input)?; // FIXME: + if table.cols.iter().find(|col| col.name.to_string == col_name.to_string).is_none() { + throw_err(Err::ColumnNotFound, &col_name.span_range, input)?; } } } @@ -165,29 +166,29 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { throw_err(Err::DuplicatedPrimaryKey, &def.span_range, input)?; } - tmp_table_indexer.pk_list.extend(idents.clone()) + tmp_table_indexer.pk_list.extend(ident_strings.clone()) } else if settings.is_unique { - if tmp_table_indexer.unique_list.iter().any(|uniq_item| idents.iter().all(|id| uniq_item.contains(id))) { + if tmp_table_indexer.unique_list.iter().any(|uniq_item| idents.iter().all(|id| uniq_item.contains(&id.to_string))) { throw_err(Err::DuplicatedUniqueKey, &def.span_range, input)?; } - tmp_table_indexer.unique_list.push(idents.clone().into_iter().collect()) + tmp_table_indexer.unique_list.push(ident_strings.clone().into_iter().collect()) } if settings.r#type.is_some() { - if tmp_table_indexer.indexed_list.iter().any(|(idx_item, idx_type)| idx_item == &idents && idx_type == &settings.r#type) { + if tmp_table_indexer.indexed_list.iter().any(|(idx_item, idx_type)| idx_item == &ident_strings && idx_type == &settings.r#type) { throw_err(Err::DuplicatedIndexKey, &def.span_range, input)?; } - tmp_table_indexer.indexed_list.push((idents, settings.r#type.clone())); + tmp_table_indexer.indexed_list.push((ident_strings, settings.r#type.clone())); } } None => { - if tmp_table_indexer.indexed_list.iter().any(|(idx_item, _)| idx_item == &idents) { + if tmp_table_indexer.indexed_list.iter().any(|(idx_item, _)| idx_item == &ident_strings) { throw_err(Err::DuplicatedIndexKey, &def.span_range, input)?; } - tmp_table_indexer.indexed_list.push((idents, None)) + tmp_table_indexer.indexed_list.push((ident_strings, None)) }, }; } @@ -299,6 +300,8 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { match default_value { Value::Enum(_) => (), Value::String(val) => { + let err = Err::InvalidDefaultValue { raw_value: val.clone(), raw_type: col.r#type.raw.clone() }; + if !matches!( type_name, ColumnTypeName::Bit @@ -307,7 +310,7 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { | ColumnTypeName::VarChar | ColumnTypeName::Enum(_) ) { - throw_err(Err::InvalidDefaultValue { raw_value: val.clone(), raw_type: col.r#type.raw.clone() }, &span_range, input)?; + throw_err(err.clone(), &span_range, input)?; } // validate fixed and variable length data type @@ -315,17 +318,19 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { ColumnTypeName::Bit | ColumnTypeName::Char if matches!(col.r#type.args[0], Value::Integer(len) if val.len() as i64 != len) => { - panic!("defualt value does not match with the specified fixed length") + throw_err(err.clone(), &span_range, input)?; } ColumnTypeName::Varbit | ColumnTypeName::VarChar if matches!(col.r#type.args[0], Value::Integer(cap) if val.len() as i64 > cap) => { - panic!("defualt value exceeds the specified variable length") + throw_err(err.clone(), &span_range, input)?; } _ => () }; }, Value::Integer(val) => { + let err = Err::DataTypeExceeded { raw_type: col.r#type.raw.clone() }; + if !matches!( type_name, ColumnTypeName::SmallSerial @@ -341,15 +346,15 @@ pub fn analyze(schema_block: &SchemaBlock) -> AnalyzerResult { match type_name { ColumnTypeName::SmallInt if (val > i16::MAX as i64) || (val < i16::MIN as i64) => { - panic!("defualt value exceeds the maximum value of the specified type") + throw_err(err.clone(), &span_range, input)?; } ColumnTypeName::Integer if (val > i32::MAX as i64) || (val < i32::MIN as i64) => { - panic!("defualt value exceeds the maximum value of the specified type") + throw_err(err.clone(), &span_range, input)?; } ColumnTypeName::BigInt if val.overflowing_add(1).1 || val.overflowing_sub(1).1 => { - panic!("defualt value exceeds the maximum value of the specified type") + throw_err(err.clone(), &span_range, input)?; } _ => () }; diff --git a/src/ast/indexes.rs b/src/ast/indexes.rs index a1d0f66..be1a0aa 100644 --- a/src/ast/indexes.rs +++ b/src/ast/indexes.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use super::{Attribute, SpanRange}; +use super::*; #[derive(Debug, Clone, Default)] pub struct IndexesBlock { @@ -39,8 +39,8 @@ pub struct IndexesSettings { #[derive(Debug, Clone)] pub enum IndexesColumnType { - String(String), - Expr(String), + String(Ident), + Expr(Literal), } #[derive(Debug, PartialEq, Eq, Clone)] diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ffa2a6a..23efc8d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -732,18 +732,22 @@ fn parse_indexes_ident(pair: Pair) -> ParserResult { match p1.as_rule() { Rule::ident => { let value = parse_ident(p1)?; - Ok(IndexesColumnType::String(value.to_string)) + Ok(IndexesColumnType::String(value)) } Rule::backquoted_quoted_string => { let p2 = p1 + .clone() .into_inner() .next() .ok_or_else(|| unreachable!("something went wrong at indexes_ident"))?; match p2.as_rule() { Rule::backquoted_quoted_value => { - let value = p2.as_str().to_string(); - Ok(IndexesColumnType::Expr(value)) + Ok(IndexesColumnType::Expr(Literal { + span_range: s2r(p1.as_span()), + raw: p1.as_str().to_owned(), + value: Value::String(p2.as_str().to_owned()) + })) } _ => throw_rules(&[Rule::backquoted_quoted_value], p2)?, } diff --git a/tests/out/comment.in.ron b/tests/out/comment.in.ron index 712ec31..4f326ad 100644 --- a/tests/out/comment.in.ron +++ b/tests/out/comment.in.ron @@ -217,7 +217,11 @@ SchemaBlock { span_range: 223..238, cols: [ String( - "id", + Ident { + span_range: 223..225, + raw: "id", + to_string: "id", + }, ), ], settings: Some( @@ -256,7 +260,11 @@ SchemaBlock { span_range: 250..270, cols: [ String( - "created_at", + Ident { + span_range: 250..260, + raw: "created_at", + to_string: "created_at", + }, ), ], settings: None, diff --git a/tests/out/composite_pk.in.ron b/tests/out/composite_pk.in.ron index 467bb12..0a3782a 100644 --- a/tests/out/composite_pk.in.ron +++ b/tests/out/composite_pk.in.ron @@ -238,7 +238,11 @@ SchemaBlock { span_range: 211..218, cols: [ String( - "id", + Ident { + span_range: 211..213, + raw: "id", + to_string: "id", + }, ), ], settings: Some( @@ -505,13 +509,25 @@ SchemaBlock { span_range: 437..465, cols: [ String( - "id", + Ident { + span_range: 438..440, + raw: "id", + to_string: "id", + }, ), String( - "full_name", + Ident { + span_range: 442..451, + raw: "full_name", + to_string: "full_name", + }, ), String( - "gender", + Ident { + span_range: 453..459, + raw: "gender", + to_string: "gender", + }, ), ], settings: Some( diff --git a/tests/out/general_schema.in.ron b/tests/out/general_schema.in.ron index 3511596..1266e93 100644 --- a/tests/out/general_schema.in.ron +++ b/tests/out/general_schema.in.ron @@ -593,10 +593,18 @@ SchemaBlock { span_range: 559..605, cols: [ String( - "merchant_id", + Ident { + span_range: 560..571, + raw: "merchant_id", + to_string: "merchant_id", + }, ), String( - "status", + Ident { + span_range: 573..579, + raw: "status", + to_string: "status", + }, ), ], settings: Some( @@ -635,7 +643,11 @@ SchemaBlock { span_range: 608..631, cols: [ String( - "id", + Ident { + span_range: 608..610, + raw: "id", + to_string: "id", + }, ), ], settings: Some( diff --git a/tests/out/index_tables.in.ron b/tests/out/index_tables.in.ron index 8abc22f..51d5b8c 100644 --- a/tests/out/index_tables.in.ron +++ b/tests/out/index_tables.in.ron @@ -238,7 +238,11 @@ SchemaBlock { span_range: 211..244, cols: [ String( - "id", + Ident { + span_range: 212..214, + raw: "id", + to_string: "id", + }, ), ], settings: Some( @@ -286,7 +290,11 @@ SchemaBlock { span_range: 249..278, cols: [ String( - "full_name", + Ident { + span_range: 249..258, + raw: "full_name", + to_string: "full_name", + }, ), ], settings: Some( @@ -325,10 +333,18 @@ SchemaBlock { span_range: 283..314, cols: [ String( - "email", + Ident { + span_range: 284..289, + raw: "email", + to_string: "email", + }, ), String( - "created_at", + Ident { + span_range: 290..300, + raw: "created_at", + to_string: "created_at", + }, ), ], settings: Some( @@ -367,7 +383,13 @@ SchemaBlock { span_range: 319..331, cols: [ Expr( - "now()", + Literal { + span_range: 319..326, + raw: "`now()`", + value: String( + "now()", + ), + }, ), ], settings: None, @@ -376,10 +398,20 @@ SchemaBlock { span_range: 331..364, cols: [ String( - "active", + Ident { + span_range: 332..338, + raw: "active", + to_string: "active", + }, ), Expr( - "lower(full_name)", + Literal { + span_range: 340..358, + raw: "`lower(full_name)`", + value: String( + "lower(full_name)", + ), + }, ), ], settings: None, @@ -388,10 +420,22 @@ SchemaBlock { span_range: 364..399, cols: [ Expr( - "getdate()", + Literal { + span_range: 365..376, + raw: "`getdate()`", + value: String( + "getdate()", + ), + }, ), Expr( - "upper(gender)", + Literal { + span_range: 378..393, + raw: "`upper(gender)`", + value: String( + "upper(gender)", + ), + }, ), ], settings: None, @@ -400,7 +444,13 @@ SchemaBlock { span_range: 399..427, cols: [ Expr( - "reverse(country_code)", + Literal { + span_range: 400..423, + raw: "`reverse(country_code)`", + value: String( + "reverse(country_code)", + ), + }, ), ], settings: None, diff --git a/tests/out/project.in.ron b/tests/out/project.in.ron index 9f3cb47..49da2d9 100644 --- a/tests/out/project.in.ron +++ b/tests/out/project.in.ron @@ -633,10 +633,18 @@ SchemaBlock { span_range: 709..755, cols: [ String( - "merchant_id", + Ident { + span_range: 710..721, + raw: "merchant_id", + to_string: "merchant_id", + }, ), String( - "status", + Ident { + span_range: 723..729, + raw: "status", + to_string: "status", + }, ), ], settings: Some( @@ -675,7 +683,11 @@ SchemaBlock { span_range: 758..781, cols: [ String( - "id", + Ident { + span_range: 758..760, + raw: "id", + to_string: "id", + }, ), ], settings: Some( diff --git a/tests/out/referential_actions.in.ron b/tests/out/referential_actions.in.ron index f7881bc..792696c 100644 --- a/tests/out/referential_actions.in.ron +++ b/tests/out/referential_actions.in.ron @@ -433,10 +433,18 @@ SchemaBlock { span_range: 393..408, cols: [ String( - "id", + Ident { + span_range: 394..396, + raw: "id", + to_string: "id", + }, ), String( - "name", + Ident { + span_range: 398..402, + raw: "name", + to_string: "name", + }, ), ], settings: Some( diff --git a/tests/out/sea_orm_codegen.ron b/tests/out/sea_orm_codegen.ron index 7453145..aff2d4c 100644 --- a/tests/out/sea_orm_codegen.ron +++ b/tests/out/sea_orm_codegen.ron @@ -589,10 +589,18 @@ SchemaBlock { span_range: 439..465, cols: [ String( - "cake_id", + Ident { + span_range: 440..447, + raw: "cake_id", + to_string: "cake_id", + }, ), String( - "filling_id", + Ident { + span_range: 449..459, + raw: "filling_id", + to_string: "filling_id", + }, ), ], settings: Some( diff --git a/tests/out/table_element.in.ron b/tests/out/table_element.in.ron index 06a316f..aef2b8c 100644 --- a/tests/out/table_element.in.ron +++ b/tests/out/table_element.in.ron @@ -153,7 +153,11 @@ SchemaBlock { span_range: 198..209, cols: [ String( - "gender", + Ident { + span_range: 198..204, + raw: "gender", + to_string: "gender", + }, ), ], settings: None, @@ -162,7 +166,11 @@ SchemaBlock { span_range: 209..222, cols: [ String( - "created_at", + Ident { + span_range: 209..219, + raw: "created_at", + to_string: "created_at", + }, ), ], settings: None,