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