@@ -155,29 +155,6 @@ impl Parser {
155
155
Ok ( expr)
156
156
}
157
157
158
- /// Parse expression for DEFAULT clause in CREATE TABLE
159
- pub fn parse_default_expr ( & mut self , precedence : u8 ) -> Result < ASTNode , ParserError > {
160
- debug ! ( "parsing expr" ) ;
161
- let mut expr = self . parse_prefix ( ) ?;
162
- debug ! ( "prefix: {:?}" , expr) ;
163
- loop {
164
- // stop parsing on `NULL` | `NOT NULL`
165
- match self . peek_token ( ) {
166
- Some ( Token :: SQLWord ( ref k) ) if k. keyword == "NOT" || k. keyword == "NULL" => break ,
167
- _ => { }
168
- }
169
-
170
- let next_precedence = self . get_next_precedence ( ) ?;
171
- debug ! ( "next precedence: {:?}" , next_precedence) ;
172
- if precedence >= next_precedence {
173
- break ;
174
- }
175
-
176
- expr = self . parse_infix ( expr, next_precedence) ?;
177
- }
178
- Ok ( expr)
179
- }
180
-
181
158
/// Parse an expression prefix
182
159
pub fn parse_prefix ( & mut self ) -> Result < ASTNode , ParserError > {
183
160
let tok = self
@@ -843,29 +820,18 @@ impl Parser {
843
820
} else if let Some ( Token :: SQLWord ( column_name) ) = self . peek_token ( ) {
844
821
self . next_token ( ) ;
845
822
let data_type = self . parse_data_type ( ) ?;
846
- let is_primary = self . parse_keywords ( vec ! [ "PRIMARY" , "KEY" ] ) ;
847
- let is_unique = self . parse_keyword ( "UNIQUE" ) ;
848
- let default = if self . parse_keyword ( "DEFAULT" ) {
849
- let expr = self . parse_default_expr ( 0 ) ?;
850
- Some ( expr)
851
- } else {
852
- None
853
- } ;
854
- let allow_null = if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
855
- false
856
- } else {
857
- let _ = self . parse_keyword ( "NULL" ) ;
858
- true
859
- } ;
860
- debug ! ( "default: {:?}" , default ) ;
823
+ let mut constraints = vec ! [ ] ;
824
+ loop {
825
+ match self . peek_token ( ) {
826
+ None | Some ( Token :: Comma ) | Some ( Token :: RParen ) => break ,
827
+ _ => constraints. push ( self . parse_column_constraint ( ) ?) ,
828
+ }
829
+ }
861
830
862
831
columns. push ( SQLColumnDef {
863
832
name : column_name. as_sql_ident ( ) ,
864
833
data_type,
865
- allow_null,
866
- is_primary,
867
- is_unique,
868
- default,
834
+ constraints,
869
835
} ) ;
870
836
} else {
871
837
return self . expected ( "column name or constraint definition" , self . peek_token ( ) ) ;
@@ -882,6 +848,58 @@ impl Parser {
882
848
Ok ( ( columns, constraints) )
883
849
}
884
850
851
+ pub fn parse_column_constraint ( & mut self ) -> Result < ColumnConstraint , ParserError > {
852
+ if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
853
+ return Ok ( ColumnConstraint :: NotNull ) ;
854
+ } else if self . parse_keyword ( "NULL" ) {
855
+ return Ok ( ColumnConstraint :: Null ) ;
856
+ } else if self . parse_keyword ( "DEFAULT" ) {
857
+ // We want to allow as many DEFAULT expressions as possible, but
858
+ // calling self.parse_expr() will choke on expressions like "DEFAULT
859
+ // 1 NOT NULL". Typically this would be a syntax error, as "1 NOT
860
+ // NULL" is not a valid SQL expression, but in this case we know
861
+ // that NOT NULL is part of the next column constraint. As it turns
862
+ // out, the only expressions that cause trouble all have precedence
863
+ // less than or equal to BETWEEN, so we pass BETWEEN_PREC to stop
864
+ // parsing on tokens with precedence less than or equal to BETWEEN.
865
+ // The same trick is employed by PostgreSQL [0].
866
+ // https://github.com/postgres/postgres/blob/56b78626c/src/backend/parser/gram.y#L13366-L13370
867
+ let expr = self . parse_subexpr ( Self :: BETWEEN_PREC ) ?;
868
+ return Ok ( ColumnConstraint :: Default ( expr) ) ;
869
+ }
870
+
871
+ let name = if self . parse_keyword ( "CONSTRAINT" ) {
872
+ Some ( self . parse_identifier ( ) ?)
873
+ } else {
874
+ None
875
+ } ;
876
+
877
+ if self . parse_keywords ( vec ! [ "PRIMARY" , "KEY" ] ) {
878
+ Ok ( ColumnConstraint :: Unique {
879
+ name,
880
+ is_primary : true ,
881
+ } )
882
+ } else if self . parse_keyword ( "UNIQUE" ) {
883
+ Ok ( ColumnConstraint :: Unique {
884
+ name,
885
+ is_primary : false ,
886
+ } )
887
+ } else if self . parse_keyword ( "REFERENCES" ) {
888
+ let foreign_table = self . parse_object_name ( ) ?;
889
+ let referred_columns = self . parse_parenthesized_column_list ( Mandatory ) ?;
890
+ Ok ( ColumnConstraint :: ForeignKey {
891
+ name,
892
+ foreign_table,
893
+ referred_columns,
894
+ } )
895
+ } else {
896
+ parser_err ! ( format!(
897
+ "Unexpected token in column definition: {:?}" ,
898
+ self . peek_token( )
899
+ ) )
900
+ }
901
+ }
902
+
885
903
pub fn parse_optional_table_constraint (
886
904
& mut self ,
887
905
) -> Result < Option < TableConstraint > , ParserError > {
0 commit comments