Skip to content

Commit ff8312b

Browse files
authored
add support for MAX as a character length (#1038)
1 parent 4cdaa40 commit ff8312b

File tree

5 files changed

+63
-39
lines changed

5 files changed

+63
-39
lines changed

src/ast/data_type.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -518,18 +518,29 @@ impl fmt::Display for ExactNumberInfo {
518518
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
519519
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
520520
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
521-
pub struct CharacterLength {
522-
/// Default (if VARYING) or maximum (if not VARYING) length
523-
pub length: u64,
524-
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
525-
pub unit: Option<CharLengthUnits>,
521+
pub enum CharacterLength {
522+
IntegerLength {
523+
/// Default (if VARYING) or maximum (if not VARYING) length
524+
length: u64,
525+
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
526+
unit: Option<CharLengthUnits>,
527+
},
528+
/// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Miscrosoft SQL Server)
529+
Max,
526530
}
527531

528532
impl fmt::Display for CharacterLength {
529533
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
530-
write!(f, "{}", self.length)?;
531-
if let Some(unit) = &self.unit {
532-
write!(f, " {unit}")?;
534+
match self {
535+
CharacterLength::IntegerLength { length, unit } => {
536+
write!(f, "{}", length)?;
537+
if let Some(unit) = unit {
538+
write!(f, " {unit}")?;
539+
}
540+
}
541+
CharacterLength::Max => {
542+
write!(f, "MAX")?;
543+
}
533544
}
534545
Ok(())
535546
}

src/parser/mod.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5617,6 +5617,9 @@ impl<'a> Parser<'a> {
56175617
}
56185618

56195619
pub fn parse_character_length(&mut self) -> Result<CharacterLength, ParserError> {
5620+
if self.parse_keyword(Keyword::MAX) {
5621+
return Ok(CharacterLength::Max);
5622+
}
56205623
let length = self.parse_literal_uint()?;
56215624
let unit = if self.parse_keyword(Keyword::CHARACTERS) {
56225625
Some(CharLengthUnits::Characters)
@@ -5625,8 +5628,7 @@ impl<'a> Parser<'a> {
56255628
} else {
56265629
None
56275630
};
5628-
5629-
Ok(CharacterLength { length, unit })
5631+
Ok(CharacterLength::IntegerLength { length, unit })
56305632
}
56315633

56325634
pub fn parse_optional_precision_scale(
@@ -8111,7 +8113,7 @@ mod tests {
81118113
test_parse_data_type!(
81128114
dialect,
81138115
"CHARACTER(20)",
8114-
DataType::Character(Some(CharacterLength {
8116+
DataType::Character(Some(CharacterLength::IntegerLength {
81158117
length: 20,
81168118
unit: None
81178119
}))
@@ -8120,7 +8122,7 @@ mod tests {
81208122
test_parse_data_type!(
81218123
dialect,
81228124
"CHARACTER(20 CHARACTERS)",
8123-
DataType::Character(Some(CharacterLength {
8125+
DataType::Character(Some(CharacterLength::IntegerLength {
81248126
length: 20,
81258127
unit: Some(CharLengthUnits::Characters)
81268128
}))
@@ -8129,7 +8131,7 @@ mod tests {
81298131
test_parse_data_type!(
81308132
dialect,
81318133
"CHARACTER(20 OCTETS)",
8132-
DataType::Character(Some(CharacterLength {
8134+
DataType::Character(Some(CharacterLength::IntegerLength {
81338135
length: 20,
81348136
unit: Some(CharLengthUnits::Octets)
81358137
}))
@@ -8140,7 +8142,7 @@ mod tests {
81408142
test_parse_data_type!(
81418143
dialect,
81428144
"CHAR(20)",
8143-
DataType::Char(Some(CharacterLength {
8145+
DataType::Char(Some(CharacterLength::IntegerLength {
81448146
length: 20,
81458147
unit: None
81468148
}))
@@ -8149,7 +8151,7 @@ mod tests {
81498151
test_parse_data_type!(
81508152
dialect,
81518153
"CHAR(20 CHARACTERS)",
8152-
DataType::Char(Some(CharacterLength {
8154+
DataType::Char(Some(CharacterLength::IntegerLength {
81538155
length: 20,
81548156
unit: Some(CharLengthUnits::Characters)
81558157
}))
@@ -8158,7 +8160,7 @@ mod tests {
81588160
test_parse_data_type!(
81598161
dialect,
81608162
"CHAR(20 OCTETS)",
8161-
DataType::Char(Some(CharacterLength {
8163+
DataType::Char(Some(CharacterLength::IntegerLength {
81628164
length: 20,
81638165
unit: Some(CharLengthUnits::Octets)
81648166
}))
@@ -8167,7 +8169,7 @@ mod tests {
81678169
test_parse_data_type!(
81688170
dialect,
81698171
"CHARACTER VARYING(20)",
8170-
DataType::CharacterVarying(Some(CharacterLength {
8172+
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
81718173
length: 20,
81728174
unit: None
81738175
}))
@@ -8176,7 +8178,7 @@ mod tests {
81768178
test_parse_data_type!(
81778179
dialect,
81788180
"CHARACTER VARYING(20 CHARACTERS)",
8179-
DataType::CharacterVarying(Some(CharacterLength {
8181+
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
81808182
length: 20,
81818183
unit: Some(CharLengthUnits::Characters)
81828184
}))
@@ -8185,7 +8187,7 @@ mod tests {
81858187
test_parse_data_type!(
81868188
dialect,
81878189
"CHARACTER VARYING(20 OCTETS)",
8188-
DataType::CharacterVarying(Some(CharacterLength {
8190+
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
81898191
length: 20,
81908192
unit: Some(CharLengthUnits::Octets)
81918193
}))
@@ -8194,7 +8196,7 @@ mod tests {
81948196
test_parse_data_type!(
81958197
dialect,
81968198
"CHAR VARYING(20)",
8197-
DataType::CharVarying(Some(CharacterLength {
8199+
DataType::CharVarying(Some(CharacterLength::IntegerLength {
81988200
length: 20,
81998201
unit: None
82008202
}))
@@ -8203,7 +8205,7 @@ mod tests {
82038205
test_parse_data_type!(
82048206
dialect,
82058207
"CHAR VARYING(20 CHARACTERS)",
8206-
DataType::CharVarying(Some(CharacterLength {
8208+
DataType::CharVarying(Some(CharacterLength::IntegerLength {
82078209
length: 20,
82088210
unit: Some(CharLengthUnits::Characters)
82098211
}))
@@ -8212,7 +8214,7 @@ mod tests {
82128214
test_parse_data_type!(
82138215
dialect,
82148216
"CHAR VARYING(20 OCTETS)",
8215-
DataType::CharVarying(Some(CharacterLength {
8217+
DataType::CharVarying(Some(CharacterLength::IntegerLength {
82168218
length: 20,
82178219
unit: Some(CharLengthUnits::Octets)
82188220
}))
@@ -8221,7 +8223,7 @@ mod tests {
82218223
test_parse_data_type!(
82228224
dialect,
82238225
"VARCHAR(20)",
8224-
DataType::Varchar(Some(CharacterLength {
8226+
DataType::Varchar(Some(CharacterLength::IntegerLength {
82258227
length: 20,
82268228
unit: None
82278229
}))

tests/sqlparser_common.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,7 +2381,7 @@ fn parse_create_table() {
23812381
vec![
23822382
ColumnDef {
23832383
name: "name".into(),
2384-
data_type: DataType::Varchar(Some(CharacterLength {
2384+
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
23852385
length: 100,
23862386
unit: None,
23872387
})),
@@ -2929,7 +2929,7 @@ fn parse_create_external_table() {
29292929
vec![
29302930
ColumnDef {
29312931
name: "name".into(),
2932-
data_type: DataType::Varchar(Some(CharacterLength {
2932+
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
29332933
length: 100,
29342934
unit: None,
29352935
})),
@@ -3000,7 +3000,7 @@ fn parse_create_or_replace_external_table() {
30003000
columns,
30013001
vec![ColumnDef {
30023002
name: "name".into(),
3003-
data_type: DataType::Varchar(Some(CharacterLength {
3003+
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
30043004
length: 100,
30053005
unit: None,
30063006
})),

tests/sqlparser_mssql.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn parse_create_procedure() {
127127
value: "@bar".into(),
128128
quote_style: None
129129
},
130-
data_type: DataType::Varchar(Some(CharacterLength {
130+
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
131131
length: 256,
132132
unit: None
133133
}))
@@ -431,6 +431,11 @@ fn parse_like() {
431431
chk(true);
432432
}
433433

434+
#[test]
435+
fn parse_cast_varchar_max() {
436+
ms_and_generic().verified_expr("CAST('foo' AS VARCHAR(MAX))");
437+
}
438+
434439
#[test]
435440
fn parse_similar_to() {
436441
fn chk(negated: bool) {

tests/sqlparser_postgres.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,12 @@ fn parse_create_table_with_defaults() {
349349
},
350350
ColumnDef {
351351
name: "first_name".into(),
352-
data_type: DataType::CharacterVarying(Some(CharacterLength {
353-
length: 45,
354-
unit: None
355-
})),
352+
data_type: DataType::CharacterVarying(Some(
353+
CharacterLength::IntegerLength {
354+
length: 45,
355+
unit: None
356+
}
357+
)),
356358
collation: None,
357359
options: vec![ColumnOptionDef {
358360
name: None,
@@ -361,10 +363,12 @@ fn parse_create_table_with_defaults() {
361363
},
362364
ColumnDef {
363365
name: "last_name".into(),
364-
data_type: DataType::CharacterVarying(Some(CharacterLength {
365-
length: 45,
366-
unit: None
367-
})),
366+
data_type: DataType::CharacterVarying(Some(
367+
CharacterLength::IntegerLength {
368+
length: 45,
369+
unit: None
370+
}
371+
)),
368372
collation: Some(ObjectName(vec![Ident::with_quote('"', "es_ES")])),
369373
options: vec![ColumnOptionDef {
370374
name: None,
@@ -373,10 +377,12 @@ fn parse_create_table_with_defaults() {
373377
},
374378
ColumnDef {
375379
name: "email".into(),
376-
data_type: DataType::CharacterVarying(Some(CharacterLength {
377-
length: 50,
378-
unit: None
379-
})),
380+
data_type: DataType::CharacterVarying(Some(
381+
CharacterLength::IntegerLength {
382+
length: 50,
383+
unit: None
384+
}
385+
)),
380386
collation: None,
381387
options: vec![],
382388
},

0 commit comments

Comments
 (0)