@@ -3661,7 +3661,11 @@ impl<'a> Parser<'a> {
3661
3661
_ => {
3662
3662
self . prev_token ( ) ;
3663
3663
let type_name = self . parse_object_name ( ) ?;
3664
- Ok ( DataType :: Custom ( type_name) )
3664
+ if let Some ( modifiers) = self . parse_optional_type_modifiers ( ) ? {
3665
+ Ok ( DataType :: Custom ( type_name, modifiers) )
3666
+ } else {
3667
+ Ok ( DataType :: Custom ( type_name, vec ! [ ] ) )
3668
+ }
3665
3669
}
3666
3670
} ,
3667
3671
unexpected => self . expected ( "a data type name" , unexpected) ,
@@ -3907,6 +3911,31 @@ impl<'a> Parser<'a> {
3907
3911
}
3908
3912
}
3909
3913
3914
+ pub fn parse_optional_type_modifiers ( & mut self ) -> Result < Option < Vec < String > > , ParserError > {
3915
+ if self . consume_token ( & Token :: LParen ) {
3916
+ let mut modifiers = Vec :: new ( ) ;
3917
+ loop {
3918
+ match self . next_token ( ) {
3919
+ Token :: Word ( w) => modifiers. push ( w. to_string ( ) ) ,
3920
+ Token :: Number ( n, _) => modifiers. push ( n) ,
3921
+ Token :: SingleQuotedString ( s) => modifiers. push ( s) ,
3922
+
3923
+ Token :: Comma => {
3924
+ continue ;
3925
+ }
3926
+ Token :: RParen => {
3927
+ break ;
3928
+ }
3929
+ unexpected => self . expected ( "type modifiers" , unexpected) ?,
3930
+ }
3931
+ }
3932
+
3933
+ Ok ( Some ( modifiers) )
3934
+ } else {
3935
+ Ok ( None )
3936
+ }
3937
+ }
3938
+
3910
3939
pub fn parse_delete ( & mut self ) -> Result < Statement , ParserError > {
3911
3940
self . expect_keyword ( Keyword :: FROM ) ?;
3912
3941
let table_name = self . parse_table_factor ( ) ?;
@@ -5540,7 +5569,7 @@ mod tests {
5540
5569
#[ cfg( test) ]
5541
5570
mod test_parse_data_type {
5542
5571
use crate :: ast:: {
5543
- CharLengthUnits , CharacterLength , DataType , ExactNumberInfo , TimezoneInfo ,
5572
+ CharLengthUnits , CharacterLength , DataType , ExactNumberInfo , ObjectName , TimezoneInfo ,
5544
5573
} ;
5545
5574
use crate :: dialect:: { AnsiDialect , GenericDialect } ;
5546
5575
use crate :: test_utils:: TestedDialects ;
@@ -5717,6 +5746,36 @@ mod tests {
5717
5746
test_parse_data_type ! ( dialect, "CLOB(20)" , DataType :: Clob ( Some ( 20 ) ) ) ;
5718
5747
}
5719
5748
5749
+ #[ test]
5750
+ fn test_parse_custom_types ( ) {
5751
+ let dialect = TestedDialects {
5752
+ dialects : vec ! [ Box :: new( GenericDialect { } ) , Box :: new( AnsiDialect { } ) ] ,
5753
+ } ;
5754
+ test_parse_data_type ! (
5755
+ dialect,
5756
+ "GEOMETRY" ,
5757
+ DataType :: Custom ( ObjectName ( vec![ "GEOMETRY" . into( ) ] ) , vec![ ] )
5758
+ ) ;
5759
+
5760
+ test_parse_data_type ! (
5761
+ dialect,
5762
+ "GEOMETRY(POINT)" ,
5763
+ DataType :: Custom (
5764
+ ObjectName ( vec![ "GEOMETRY" . into( ) ] ) ,
5765
+ vec![ "POINT" . to_string( ) ]
5766
+ )
5767
+ ) ;
5768
+
5769
+ test_parse_data_type ! (
5770
+ dialect,
5771
+ "GEOMETRY(POINT, 4326)" ,
5772
+ DataType :: Custom (
5773
+ ObjectName ( vec![ "GEOMETRY" . into( ) ] ) ,
5774
+ vec![ "POINT" . to_string( ) , "4326" . to_string( ) ]
5775
+ )
5776
+ ) ;
5777
+ }
5778
+
5720
5779
#[ test]
5721
5780
fn test_ansii_exact_numeric_types ( ) {
5722
5781
// Exact numeric types: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#exact-numeric-type>
0 commit comments