File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -2031,7 +2031,11 @@ impl fmt::Display for Expr {
20312031 format,
20322032 } => match kind {
20332033 CastKind :: Cast => {
2034- write ! ( f, "CAST({expr} AS {data_type}" ) ?;
2034+ if matches ! ( data_type, DataType :: Unspecified ) {
2035+ write ! ( f, "CAST({expr} AS" ) ?;
2036+ } else {
2037+ write ! ( f, "CAST({expr} AS {data_type}" ) ?;
2038+ }
20352039 if let Some ( format) = format {
20362040 write ! ( f, " FORMAT {format}" ) ?;
20372041 }
Original file line number Diff line number Diff line change @@ -1887,6 +1887,18 @@ pub trait Dialect: Debug + Any {
18871887 fn supports_map_literal_with_angle_brackets ( & self ) -> bool {
18881888 false
18891889 }
1890+
1891+ /// Returns true if the dialect supports `CAST(expr AS)` with an empty type name.
1892+ ///
1893+ /// Example:
1894+ /// ```sql
1895+ /// SELECT CAST(a AS)
1896+ /// ```
1897+ ///
1898+ /// [SQLite](https://www.sqlite.org/lang_expr.html)
1899+ fn supports_cast_empty_data_type_to_unspecified ( & self ) -> bool {
1900+ false
1901+ }
18901902}
18911903
18921904/// Operators for which precedence must be defined.
Original file line number Diff line number Diff line change @@ -129,4 +129,8 @@ impl Dialect for SQLiteDialect {
129129 fn supports_numeric_literal_underscores ( & self ) -> bool {
130130 true
131131 }
132+
133+ fn supports_cast_empty_data_type_to_unspecified ( & self ) -> bool {
134+ true
135+ }
132136}
Original file line number Diff line number Diff line change @@ -2923,7 +2923,13 @@ impl<'a> Parser<'a> {
29232923 self.expect_token(&Token::LParen)?;
29242924 let expr = self.parse_expr()?;
29252925 self.expect_keyword_is(Keyword::AS)?;
2926- let data_type = self.parse_data_type()?;
2926+ let data_type = if self.dialect.supports_cast_empty_data_type_to_unspecified()
2927+ && self.peek_token_ref().token == Token::RParen
2928+ {
2929+ DataType::Unspecified
2930+ } else {
2931+ self.parse_data_type()?
2932+ };
29272933 let format = self.parse_optional_cast_format()?;
29282934 self.expect_token(&Token::RParen)?;
29292935 Ok(Expr::Cast {
Original file line number Diff line number Diff line change @@ -957,6 +957,18 @@ fn parse_pattern_operators_bind_at_like_precedence() {
957957 }
958958}
959959
960+ #[ test]
961+ fn test_cast_empty_type ( ) {
962+ // SQLite allows CAST(expr AS) with an empty type name (typetoken can be empty)
963+ // See https://www.sqlite.org/lang_expr.html
964+ sqlite ( ) . verified_stmt ( "SELECT CAST(a AS)" ) ;
965+
966+ // Rejected by dialects without the flag
967+ assert ! ( TestedDialects :: new( vec![ Box :: new( GenericDialect { } ) ] )
968+ . parse_sql_statements( "SELECT CAST(a AS)" )
969+ . is_err( ) ) ;
970+ }
971+
960972fn sqlite ( ) -> TestedDialects {
961973 TestedDialects :: new ( vec ! [ Box :: new( SQLiteDialect { } ) ] )
962974}
You can’t perform that action at this time.
0 commit comments