Repository: apache/datafusion-sqlparser-rs (Rust)

Issue:
VARBINARY or BLOB columns not parsed
I see the DataType enum has variants for these but it doesn't parse them correctly, or perhaps I am doing something wrong.

Sql:
```mysql
CREATE TABLE IF NOT EXISTS `data` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `key` VARCHAR(255) NOT NULL,
  `secret` BLOB(255) NOT NULL,
  PRIMARY KEY (`id`))

# or

CREATE TABLE IF NOT EXISTS `data` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `key` VARCHAR(255) NOT NULL,
  `secret` VARBINARY(255) NOT NULL,
  PRIMARY KEY (`id`))
```

Error:
```
unexpected end of input, sql parser error: Expected ',' or ')' after column definition, found:
 ( input: 'CREATE TABLE IF NOT EXISTS `data` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, 
`key` VARCHAR(255) NOT NULL, `secret` BLOB (255) NOT NULL, PRIMARY KEY (`id`))'
```


Discussion:
I think this would make a nice contribution to the library -- feel free to make a PR 👍 



Patch:
diff --git a/src/parser.rs b/src/parser.rs
index 968b1a5dd..af63604ec 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -3142,6 +3142,10 @@ impl<'a> Parser<'a> {
                         Ok(DataType::Char(self.parse_optional_precision()?))
                     }
                 }
+                Keyword::CLOB => Ok(DataType::Clob(self.parse_precision()?)),
+                Keyword::BINARY => Ok(DataType::Binary(self.parse_precision()?)),
+                Keyword::VARBINARY => Ok(DataType::Varbinary(self.parse_precision()?)),
+                Keyword::BLOB => Ok(DataType::Blob(self.parse_precision()?)),
                 Keyword::UUID => Ok(DataType::Uuid),
                 Keyword::DATE => Ok(DataType::Date),
                 Keyword::DATETIME => Ok(DataType::Datetime),
@@ -3355,6 +3359,13 @@ impl<'a> Parser<'a> {
         }
     }
 
+    pub fn parse_precision(&mut self) -> Result<u64, ParserError> {
+        self.expect_token(&Token::LParen)?;
+        let n = self.parse_literal_uint()?;
+        self.expect_token(&Token::RParen)?;
+        Ok(n)
+    }
+
     pub fn parse_optional_precision(&mut self) -> Result<Option<u64>, ParserError> {
         if self.consume_token(&Token::LParen) {
             let n = self.parse_literal_uint()?;


Test patch:
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index d2d2646cd..3616870a0 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -1647,6 +1647,46 @@ fn parse_cast() {
         },
         expr_from_projection(only(&select.projection))
     );
+
+    let sql = "SELECT CAST(id AS CLOB(50)) FROM customer";
+    let select = verified_only_select(sql);
+    assert_eq!(
+        &Expr::Cast {
+            expr: Box::new(Expr::Identifier(Ident::new("id"))),
+            data_type: DataType::Clob(50)
+        },
+        expr_from_projection(only(&select.projection))
+    );
+
+    let sql = "SELECT CAST(id AS BINARY(50)) FROM customer";
+    let select = verified_only_select(sql);
+    assert_eq!(
+        &Expr::Cast {
+            expr: Box::new(Expr::Identifier(Ident::new("id"))),
+            data_type: DataType::Binary(50)
+        },
+        expr_from_projection(only(&select.projection))
+    );
+
+    let sql = "SELECT CAST(id AS VARBINARY(50)) FROM customer";
+    let select = verified_only_select(sql);
+    assert_eq!(
+        &Expr::Cast {
+            expr: Box::new(Expr::Identifier(Ident::new("id"))),
+            data_type: DataType::Varbinary(50)
+        },
+        expr_from_projection(only(&select.projection))
+    );
+
+    let sql = "SELECT CAST(id AS BLOB(50)) FROM customer";
+    let select = verified_only_select(sql);
+    assert_eq!(
+        &Expr::Cast {
+            expr: Box::new(Expr::Identifier(Ident::new("id"))),
+            data_type: DataType::Blob(50)
+        },
+        expr_from_projection(only(&select.projection))
+    );
 }
 
 #[test]