Support MySQL size variants for BLOB and TEXT columns (#1564)

This commit is contained in:
Michael Victor Zink 2024-11-30 04:55:54 -08:00 committed by GitHub
parent a134910a36
commit 48b0e4db4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 0 deletions

View file

@ -76,6 +76,18 @@ pub enum DataType {
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type /// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#binary-large-object-string-type
/// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html /// [Oracle]: https://docs.oracle.com/javadb/10.8.3.0/ref/rrefblob.html
Blob(Option<u64>), Blob(Option<u64>),
/// [MySQL] blob with up to 2**8 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
TinyBlob,
/// [MySQL] blob with up to 2**24 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
MediumBlob,
/// [MySQL] blob with up to 2**32 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
LongBlob,
/// Variable-length binary data with optional length. /// Variable-length binary data with optional length.
/// ///
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#bytes_type /// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#bytes_type
@ -275,6 +287,18 @@ pub enum DataType {
Regclass, Regclass,
/// Text /// Text
Text, Text,
/// [MySQL] text with up to 2**8 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
TinyText,
/// [MySQL] text with up to 2**24 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
MediumText,
/// [MySQL] text with up to 2**32 bytes
///
/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/blob.html
LongText,
/// String with optional length. /// String with optional length.
String(Option<u64>), String(Option<u64>),
/// A fixed-length string e.g [ClickHouse][1]. /// A fixed-length string e.g [ClickHouse][1].
@ -355,6 +379,9 @@ impl fmt::Display for DataType {
format_type_with_optional_length(f, "VARBINARY", size, false) format_type_with_optional_length(f, "VARBINARY", size, false)
} }
DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false), DataType::Blob(size) => format_type_with_optional_length(f, "BLOB", size, false),
DataType::TinyBlob => write!(f, "TINYBLOB"),
DataType::MediumBlob => write!(f, "MEDIUMBLOB"),
DataType::LongBlob => write!(f, "LONGBLOB"),
DataType::Bytes(size) => format_type_with_optional_length(f, "BYTES", size, false), DataType::Bytes(size) => format_type_with_optional_length(f, "BYTES", size, false),
DataType::Numeric(info) => { DataType::Numeric(info) => {
write!(f, "NUMERIC{info}") write!(f, "NUMERIC{info}")
@ -486,6 +513,9 @@ impl fmt::Display for DataType {
DataType::JSONB => write!(f, "JSONB"), DataType::JSONB => write!(f, "JSONB"),
DataType::Regclass => write!(f, "REGCLASS"), DataType::Regclass => write!(f, "REGCLASS"),
DataType::Text => write!(f, "TEXT"), DataType::Text => write!(f, "TEXT"),
DataType::TinyText => write!(f, "TINYTEXT"),
DataType::MediumText => write!(f, "MEDIUMTEXT"),
DataType::LongText => write!(f, "LONGTEXT"),
DataType::String(size) => format_type_with_optional_length(f, "STRING", size, false), DataType::String(size) => format_type_with_optional_length(f, "STRING", size, false),
DataType::Bytea => write!(f, "BYTEA"), DataType::Bytea => write!(f, "BYTEA"),
DataType::Array(ty) => match ty { DataType::Array(ty) => match ty {

View file

@ -453,6 +453,8 @@ define_keywords!(
LOCKED, LOCKED,
LOGIN, LOGIN,
LOGS, LOGS,
LONGBLOB,
LONGTEXT,
LOWCARDINALITY, LOWCARDINALITY,
LOWER, LOWER,
LOW_PRIORITY, LOW_PRIORITY,
@ -471,7 +473,9 @@ define_keywords!(
MAXVALUE, MAXVALUE,
MAX_DATA_EXTENSION_TIME_IN_DAYS, MAX_DATA_EXTENSION_TIME_IN_DAYS,
MEASURES, MEASURES,
MEDIUMBLOB,
MEDIUMINT, MEDIUMINT,
MEDIUMTEXT,
MEMBER, MEMBER,
MERGE, MERGE,
METADATA, METADATA,
@ -765,7 +769,9 @@ define_keywords!(
TIMEZONE_HOUR, TIMEZONE_HOUR,
TIMEZONE_MINUTE, TIMEZONE_MINUTE,
TIMEZONE_REGION, TIMEZONE_REGION,
TINYBLOB,
TINYINT, TINYINT,
TINYTEXT,
TO, TO,
TOP, TOP,
TOTALS, TOTALS,

View file

@ -8129,6 +8129,9 @@ impl<'a> Parser<'a> {
Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)), Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)),
Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_optional_precision()?)), Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_optional_precision()?)),
Keyword::BLOB => Ok(DataType::Blob(self.parse_optional_precision()?)), Keyword::BLOB => Ok(DataType::Blob(self.parse_optional_precision()?)),
Keyword::TINYBLOB => Ok(DataType::TinyBlob),
Keyword::MEDIUMBLOB => Ok(DataType::MediumBlob),
Keyword::LONGBLOB => Ok(DataType::LongBlob),
Keyword::BYTES => Ok(DataType::Bytes(self.parse_optional_precision()?)), Keyword::BYTES => Ok(DataType::Bytes(self.parse_optional_precision()?)),
Keyword::UUID => Ok(DataType::Uuid), Keyword::UUID => Ok(DataType::Uuid),
Keyword::DATE => Ok(DataType::Date), Keyword::DATE => Ok(DataType::Date),
@ -8188,6 +8191,9 @@ impl<'a> Parser<'a> {
Ok(DataType::FixedString(character_length)) Ok(DataType::FixedString(character_length))
} }
Keyword::TEXT => Ok(DataType::Text), Keyword::TEXT => Ok(DataType::Text),
Keyword::TINYTEXT => Ok(DataType::TinyText),
Keyword::MEDIUMTEXT => Ok(DataType::MediumText),
Keyword::LONGTEXT => Ok(DataType::LongText),
Keyword::BYTEA => Ok(DataType::Bytea), Keyword::BYTEA => Ok(DataType::Bytea),
Keyword::NUMERIC => Ok(DataType::Numeric( Keyword::NUMERIC => Ok(DataType::Numeric(
self.parse_exact_number_optional_precision_scale()?, self.parse_exact_number_optional_precision_scale()?,

View file

@ -3014,3 +3014,20 @@ fn parse_bitstring_literal() {
))] ))]
); );
} }
#[test]
fn parse_longblob_type() {
let sql = "CREATE TABLE foo (bar LONGBLOB)";
let stmt = mysql_and_generic().verified_stmt(sql);
if let Statement::CreateTable(CreateTable { columns, .. }) = stmt {
assert_eq!(columns.len(), 1);
assert_eq!(columns[0].data_type, DataType::LongBlob);
} else {
unreachable!()
}
mysql_and_generic().verified_stmt("CREATE TABLE foo (bar TINYBLOB)");
mysql_and_generic().verified_stmt("CREATE TABLE foo (bar MEDIUMBLOB)");
mysql_and_generic().verified_stmt("CREATE TABLE foo (bar TINYTEXT)");
mysql_and_generic().verified_stmt("CREATE TABLE foo (bar MEDIUMTEXT)");
mysql_and_generic().verified_stmt("CREATE TABLE foo (bar LONGTEXT)");
}