mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 15:04:04 +00:00
add support for MAX as a character length (#1038)
This commit is contained in:
parent
4cdaa40abe
commit
ff8312bfd8
5 changed files with 63 additions and 39 deletions
|
@ -518,18 +518,29 @@ impl fmt::Display for ExactNumberInfo {
|
|||
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub struct CharacterLength {
|
||||
/// Default (if VARYING) or maximum (if not VARYING) length
|
||||
pub length: u64,
|
||||
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
|
||||
pub unit: Option<CharLengthUnits>,
|
||||
pub enum CharacterLength {
|
||||
IntegerLength {
|
||||
/// Default (if VARYING) or maximum (if not VARYING) length
|
||||
length: u64,
|
||||
/// Optional unit. If not informed, the ANSI handles it as CHARACTERS implicitly
|
||||
unit: Option<CharLengthUnits>,
|
||||
},
|
||||
/// VARCHAR(MAX) or NVARCHAR(MAX), used in T-SQL (Miscrosoft SQL Server)
|
||||
Max,
|
||||
}
|
||||
|
||||
impl fmt::Display for CharacterLength {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.length)?;
|
||||
if let Some(unit) = &self.unit {
|
||||
write!(f, " {unit}")?;
|
||||
match self {
|
||||
CharacterLength::IntegerLength { length, unit } => {
|
||||
write!(f, "{}", length)?;
|
||||
if let Some(unit) = unit {
|
||||
write!(f, " {unit}")?;
|
||||
}
|
||||
}
|
||||
CharacterLength::Max => {
|
||||
write!(f, "MAX")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -5617,6 +5617,9 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
pub fn parse_character_length(&mut self) -> Result<CharacterLength, ParserError> {
|
||||
if self.parse_keyword(Keyword::MAX) {
|
||||
return Ok(CharacterLength::Max);
|
||||
}
|
||||
let length = self.parse_literal_uint()?;
|
||||
let unit = if self.parse_keyword(Keyword::CHARACTERS) {
|
||||
Some(CharLengthUnits::Characters)
|
||||
|
@ -5625,8 +5628,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(CharacterLength { length, unit })
|
||||
Ok(CharacterLength::IntegerLength { length, unit })
|
||||
}
|
||||
|
||||
pub fn parse_optional_precision_scale(
|
||||
|
@ -8111,7 +8113,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER(20)",
|
||||
DataType::Character(Some(CharacterLength {
|
||||
DataType::Character(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: None
|
||||
}))
|
||||
|
@ -8120,7 +8122,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER(20 CHARACTERS)",
|
||||
DataType::Character(Some(CharacterLength {
|
||||
DataType::Character(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Characters)
|
||||
}))
|
||||
|
@ -8129,7 +8131,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER(20 OCTETS)",
|
||||
DataType::Character(Some(CharacterLength {
|
||||
DataType::Character(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Octets)
|
||||
}))
|
||||
|
@ -8140,7 +8142,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR(20)",
|
||||
DataType::Char(Some(CharacterLength {
|
||||
DataType::Char(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: None
|
||||
}))
|
||||
|
@ -8149,7 +8151,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR(20 CHARACTERS)",
|
||||
DataType::Char(Some(CharacterLength {
|
||||
DataType::Char(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Characters)
|
||||
}))
|
||||
|
@ -8158,7 +8160,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR(20 OCTETS)",
|
||||
DataType::Char(Some(CharacterLength {
|
||||
DataType::Char(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Octets)
|
||||
}))
|
||||
|
@ -8167,7 +8169,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER VARYING(20)",
|
||||
DataType::CharacterVarying(Some(CharacterLength {
|
||||
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: None
|
||||
}))
|
||||
|
@ -8176,7 +8178,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER VARYING(20 CHARACTERS)",
|
||||
DataType::CharacterVarying(Some(CharacterLength {
|
||||
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Characters)
|
||||
}))
|
||||
|
@ -8185,7 +8187,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHARACTER VARYING(20 OCTETS)",
|
||||
DataType::CharacterVarying(Some(CharacterLength {
|
||||
DataType::CharacterVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Octets)
|
||||
}))
|
||||
|
@ -8194,7 +8196,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR VARYING(20)",
|
||||
DataType::CharVarying(Some(CharacterLength {
|
||||
DataType::CharVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: None
|
||||
}))
|
||||
|
@ -8203,7 +8205,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR VARYING(20 CHARACTERS)",
|
||||
DataType::CharVarying(Some(CharacterLength {
|
||||
DataType::CharVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Characters)
|
||||
}))
|
||||
|
@ -8212,7 +8214,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"CHAR VARYING(20 OCTETS)",
|
||||
DataType::CharVarying(Some(CharacterLength {
|
||||
DataType::CharVarying(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: Some(CharLengthUnits::Octets)
|
||||
}))
|
||||
|
@ -8221,7 +8223,7 @@ mod tests {
|
|||
test_parse_data_type!(
|
||||
dialect,
|
||||
"VARCHAR(20)",
|
||||
DataType::Varchar(Some(CharacterLength {
|
||||
DataType::Varchar(Some(CharacterLength::IntegerLength {
|
||||
length: 20,
|
||||
unit: None
|
||||
}))
|
||||
|
|
|
@ -2381,7 +2381,7 @@ fn parse_create_table() {
|
|||
vec![
|
||||
ColumnDef {
|
||||
name: "name".into(),
|
||||
data_type: DataType::Varchar(Some(CharacterLength {
|
||||
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
|
||||
length: 100,
|
||||
unit: None,
|
||||
})),
|
||||
|
@ -2929,7 +2929,7 @@ fn parse_create_external_table() {
|
|||
vec![
|
||||
ColumnDef {
|
||||
name: "name".into(),
|
||||
data_type: DataType::Varchar(Some(CharacterLength {
|
||||
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
|
||||
length: 100,
|
||||
unit: None,
|
||||
})),
|
||||
|
@ -3000,7 +3000,7 @@ fn parse_create_or_replace_external_table() {
|
|||
columns,
|
||||
vec![ColumnDef {
|
||||
name: "name".into(),
|
||||
data_type: DataType::Varchar(Some(CharacterLength {
|
||||
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
|
||||
length: 100,
|
||||
unit: None,
|
||||
})),
|
||||
|
|
|
@ -127,7 +127,7 @@ fn parse_create_procedure() {
|
|||
value: "@bar".into(),
|
||||
quote_style: None
|
||||
},
|
||||
data_type: DataType::Varchar(Some(CharacterLength {
|
||||
data_type: DataType::Varchar(Some(CharacterLength::IntegerLength {
|
||||
length: 256,
|
||||
unit: None
|
||||
}))
|
||||
|
@ -431,6 +431,11 @@ fn parse_like() {
|
|||
chk(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_cast_varchar_max() {
|
||||
ms_and_generic().verified_expr("CAST('foo' AS VARCHAR(MAX))");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_similar_to() {
|
||||
fn chk(negated: bool) {
|
||||
|
|
|
@ -349,10 +349,12 @@ fn parse_create_table_with_defaults() {
|
|||
},
|
||||
ColumnDef {
|
||||
name: "first_name".into(),
|
||||
data_type: DataType::CharacterVarying(Some(CharacterLength {
|
||||
length: 45,
|
||||
unit: None
|
||||
})),
|
||||
data_type: DataType::CharacterVarying(Some(
|
||||
CharacterLength::IntegerLength {
|
||||
length: 45,
|
||||
unit: None
|
||||
}
|
||||
)),
|
||||
collation: None,
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
|
@ -361,10 +363,12 @@ fn parse_create_table_with_defaults() {
|
|||
},
|
||||
ColumnDef {
|
||||
name: "last_name".into(),
|
||||
data_type: DataType::CharacterVarying(Some(CharacterLength {
|
||||
length: 45,
|
||||
unit: None
|
||||
})),
|
||||
data_type: DataType::CharacterVarying(Some(
|
||||
CharacterLength::IntegerLength {
|
||||
length: 45,
|
||||
unit: None
|
||||
}
|
||||
)),
|
||||
collation: Some(ObjectName(vec![Ident::with_quote('"', "es_ES")])),
|
||||
options: vec![ColumnOptionDef {
|
||||
name: None,
|
||||
|
@ -373,10 +377,12 @@ fn parse_create_table_with_defaults() {
|
|||
},
|
||||
ColumnDef {
|
||||
name: "email".into(),
|
||||
data_type: DataType::CharacterVarying(Some(CharacterLength {
|
||||
length: 50,
|
||||
unit: None
|
||||
})),
|
||||
data_type: DataType::CharacterVarying(Some(
|
||||
CharacterLength::IntegerLength {
|
||||
length: 50,
|
||||
unit: None
|
||||
}
|
||||
)),
|
||||
collation: None,
|
||||
options: vec![],
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue