@@ -703,7 +703,7 @@ impl Parser {
703
703
pub fn parse_create_external_table ( & mut self ) -> Result < SQLStatement , ParserError > {
704
704
self . expect_keyword ( "TABLE" ) ?;
705
705
let table_name = self . parse_object_name ( ) ?;
706
- let columns = self . parse_columns ( ) ?;
706
+ let ( columns, constraints ) = self . parse_columns ( ) ?;
707
707
self . expect_keyword ( "STORED" ) ?;
708
708
self . expect_keyword ( "AS" ) ?;
709
709
let file_format = self . parse_identifier ( ) ?. parse :: < FileFormat > ( ) ?;
@@ -714,6 +714,7 @@ impl Parser {
714
714
Ok ( SQLStatement :: SQLCreateTable {
715
715
name : table_name,
716
716
columns,
717
+ constraints,
717
718
external : true ,
718
719
file_format : Some ( file_format) ,
719
720
location : Some ( location) ,
@@ -742,74 +743,78 @@ impl Parser {
742
743
pub fn parse_create_table ( & mut self ) -> Result < SQLStatement , ParserError > {
743
744
let table_name = self . parse_object_name ( ) ?;
744
745
// parse optional column list (schema)
745
- let columns = self . parse_columns ( ) ?;
746
+ let ( columns, constraints ) = self . parse_columns ( ) ?;
746
747
747
748
Ok ( SQLStatement :: SQLCreateTable {
748
749
name : table_name,
749
750
columns,
751
+ constraints,
750
752
external : false ,
751
753
file_format : None ,
752
754
location : None ,
753
755
} )
754
756
}
755
757
756
- fn parse_columns ( & mut self ) -> Result < Vec < SQLColumnDef > , ParserError > {
758
+ fn parse_columns ( & mut self ) -> Result < ( Vec < SQLColumnDef > , Vec < TableConstraint > ) , ParserError > {
757
759
let mut columns = vec ! [ ] ;
760
+ let mut constraints = vec ! [ ] ;
758
761
if !self . consume_token ( & Token :: LParen ) {
759
- return Ok ( columns) ;
762
+ return Ok ( ( columns, constraints ) ) ;
760
763
}
761
764
762
765
loop {
766
+ if let Some ( constraint) = self . parse_optional_table_constraint ( ) ? {
767
+ constraints. push ( constraint) ;
768
+ } else if let Some ( Token :: SQLWord ( column_name) ) = self . peek_token ( ) {
769
+ self . next_token ( ) ;
770
+ let data_type = self . parse_data_type ( ) ?;
771
+ let is_primary = self . parse_keywords ( vec ! [ "PRIMARY" , "KEY" ] ) ;
772
+ let is_unique = self . parse_keyword ( "UNIQUE" ) ;
773
+ let default = if self . parse_keyword ( "DEFAULT" ) {
774
+ let expr = self . parse_default_expr ( 0 ) ?;
775
+ Some ( expr)
776
+ } else {
777
+ None
778
+ } ;
779
+ let allow_null = if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
780
+ false
781
+ } else {
782
+ let _ = self . parse_keyword ( "NULL" ) ;
783
+ true
784
+ } ;
785
+ debug ! ( "default: {:?}" , default ) ;
786
+
787
+ columns. push ( SQLColumnDef {
788
+ name : column_name. as_sql_ident ( ) ,
789
+ data_type,
790
+ allow_null,
791
+ is_primary,
792
+ is_unique,
793
+ default,
794
+ } ) ;
795
+ } else {
796
+ return self . expected ( "column name or constraint definition" , self . peek_token ( ) ) ;
797
+ }
763
798
match self . next_token ( ) {
764
- Some ( Token :: SQLWord ( column_name) ) => {
765
- let data_type = self . parse_data_type ( ) ?;
766
- let is_primary = self . parse_keywords ( vec ! [ "PRIMARY" , "KEY" ] ) ;
767
- let is_unique = self . parse_keyword ( "UNIQUE" ) ;
768
- let default = if self . parse_keyword ( "DEFAULT" ) {
769
- let expr = self . parse_default_expr ( 0 ) ?;
770
- Some ( expr)
771
- } else {
772
- None
773
- } ;
774
- let allow_null = if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
775
- false
776
- } else {
777
- let _ = self . parse_keyword ( "NULL" ) ;
778
- true
779
- } ;
780
- debug ! ( "default: {:?}" , default ) ;
781
-
782
- columns. push ( SQLColumnDef {
783
- name : column_name. as_sql_ident ( ) ,
784
- data_type,
785
- allow_null,
786
- is_primary,
787
- is_unique,
788
- default,
789
- } ) ;
790
- match self . next_token ( ) {
791
- Some ( Token :: Comma ) => { }
792
- Some ( Token :: RParen ) => {
793
- break ;
794
- }
795
- other => {
796
- return parser_err ! ( format!(
797
- "Expected ',' or ')' after column definition but found {:?}" ,
798
- other
799
- ) ) ;
800
- }
801
- }
799
+ Some ( Token :: Comma ) => { }
800
+ Some ( Token :: RParen ) => {
801
+ break ;
802
802
}
803
- unexpected => {
804
- return parser_err ! ( format!( "Expected column name, got {:?}" , unexpected) ) ;
803
+ other => {
804
+ return parser_err ! ( format!(
805
+ "Expected ',' or ')' after column definition but found {:?}" ,
806
+ other
807
+ ) ) ;
805
808
}
806
809
}
807
810
}
808
811
809
- Ok ( columns)
812
+ Ok ( ( columns, constraints ) )
810
813
}
811
814
812
- pub fn parse_table_constraint ( & mut self ) -> Result < TableConstraint , ParserError > {
815
+ pub fn parse_optional_table_constraint (
816
+ & mut self ,
817
+ ) -> Result < Option < TableConstraint > , ParserError > {
813
818
let name = if self . parse_keyword ( "CONSTRAINT" ) {
814
819
Some ( self . parse_identifier ( ) ?)
815
820
} else {
@@ -822,32 +827,41 @@ impl Parser {
822
827
self . expect_keyword ( "KEY" ) ?;
823
828
}
824
829
let columns = self . parse_parenthesized_column_list ( Mandatory ) ?;
825
- Ok ( TableConstraint :: Unique {
830
+ Ok ( Some ( TableConstraint :: Unique {
826
831
name,
827
832
columns,
828
833
is_primary,
829
- } )
834
+ } ) )
830
835
}
831
836
Some ( Token :: SQLWord ( ref k) ) if k. keyword == "FOREIGN" => {
832
837
self . expect_keyword ( "KEY" ) ?;
833
838
let columns = self . parse_parenthesized_column_list ( Mandatory ) ?;
834
839
self . expect_keyword ( "REFERENCES" ) ?;
835
840
let foreign_table = self . parse_object_name ( ) ?;
836
841
let referred_columns = self . parse_parenthesized_column_list ( Mandatory ) ?;
837
- Ok ( TableConstraint :: ForeignKey {
842
+ Ok ( Some ( TableConstraint :: ForeignKey {
838
843
name,
839
844
columns,
840
845
foreign_table,
841
846
referred_columns,
842
- } )
847
+ } ) )
843
848
}
844
849
Some ( Token :: SQLWord ( ref k) ) if k. keyword == "CHECK" => {
845
850
self . expect_token ( & Token :: LParen ) ?;
846
851
let expr = Box :: new ( self . parse_expr ( ) ?) ;
847
852
self . expect_token ( & Token :: RParen ) ?;
848
- Ok ( TableConstraint :: Check { name, expr } )
853
+ Ok ( Some ( TableConstraint :: Check { name, expr } ) )
854
+ }
855
+ unexpected => {
856
+ if name. is_some ( ) {
857
+ self . expected ( "PRIMARY, UNIQUE, FOREIGN, or CHECK" , unexpected)
858
+ } else {
859
+ if unexpected. is_some ( ) {
860
+ self . prev_token ( ) ;
861
+ }
862
+ Ok ( None )
863
+ }
849
864
}
850
- _ => self . expected ( "PRIMARY, UNIQUE, or FOREIGN" , self . peek_token ( ) ) ,
851
865
}
852
866
}
853
867
@@ -868,7 +882,11 @@ impl Parser {
868
882
let _ = self . parse_keyword ( "ONLY" ) ;
869
883
let table_name = self . parse_object_name ( ) ?;
870
884
let operation = if self . parse_keyword ( "ADD" ) {
871
- AlterOperation :: AddConstraint ( self . parse_table_constraint ( ) ?)
885
+ if let Some ( constraint) = self . parse_optional_table_constraint ( ) ? {
886
+ AlterOperation :: AddConstraint ( constraint)
887
+ } else {
888
+ return self . expected ( "a constraint in ALTER TABLE .. ADD" , self . peek_token ( ) ) ;
889
+ }
872
890
} else {
873
891
return self . expected ( "ADD after ALTER TABLE" , self . peek_token ( ) ) ;
874
892
} ;
0 commit comments