@@ -102,6 +102,7 @@ impl Parser {
102
102
"CREATE" => Ok ( self . parse_create ( ) ?) ,
103
103
"DELETE" => Ok ( self . parse_delete ( ) ?) ,
104
104
"INSERT" => Ok ( self . parse_insert ( ) ?) ,
105
+ "ALTER" => Ok ( self . parse_alter ( ) ?) ,
105
106
"COPY" => Ok ( self . parse_copy ( ) ?) ,
106
107
"TRUE" => {
107
108
self . prev_token ( ) ;
@@ -544,6 +545,68 @@ impl Parser {
544
545
}
545
546
}
546
547
548
+ pub fn parse_table_key ( & mut self , constraint_name : & str ) -> Result < TableKey , ParserError > {
549
+ let is_primary_key = self . parse_keywords ( vec ! [ "PRIMARY" , "KEY" ] ) ;
550
+ let is_unique_key = self . parse_keywords ( vec ! [ "UNIQUE" , "KEY" ] ) ;
551
+ let is_foreign_key = self . parse_keywords ( vec ! [ "FOREIGN" , "KEY" ] ) ;
552
+ self . consume_token ( & Token :: LParen ) ?;
553
+ let column_names= self . parse_column_names ( ) ?;
554
+ self . consume_token ( & Token :: RParen ) ?;
555
+ let key = Key {
556
+ name : Some ( constraint_name. to_string ( ) ) ,
557
+ columns : column_names
558
+ } ;
559
+ if is_primary_key{
560
+ Ok ( TableKey :: PrimaryKey ( key) )
561
+ }
562
+ else if is_unique_key{
563
+ Ok ( TableKey :: UniqueKey ( key) )
564
+ }
565
+ else if is_foreign_key{
566
+ if self . parse_keyword ( "REFERENCES" ) {
567
+ let foreign_table = self . parse_tablename ( ) ?;
568
+ self . consume_token ( & Token :: LParen ) ?;
569
+ let referred_columns = self . parse_column_names ( ) ?;
570
+ self . consume_token ( & Token :: RParen ) ?;
571
+ Ok ( TableKey :: ForeignKey {
572
+ key,
573
+ foreign_table,
574
+ referred_columns,
575
+ } )
576
+ } else {
577
+ parser_err ! ( "Expecting references" )
578
+ }
579
+ } else {
580
+ parser_err ! ( format!( "Expecting primary key, unique key, or foreign key, found: {:?}" , self . peek_token( ) ) )
581
+ }
582
+ }
583
+
584
+ pub fn parse_alter ( & mut self ) -> Result < ASTNode , ParserError > {
585
+ if self . parse_keyword ( "TABLE" ) {
586
+ let is_only = self . parse_keyword ( "ONLY" ) ;
587
+ let table_name = self . parse_tablename ( ) ?;
588
+ let operation: Result < AlterOperation , ParserError > = if self . parse_keywords ( vec ! [ "ADD" , "CONSTRAINT" ] ) {
589
+ match self . next_token ( ) {
590
+ Some ( Token :: Identifier ( ref id) ) => {
591
+ let table_key = self . parse_table_key ( id) ?;
592
+ Ok ( AlterOperation :: AddConstraint ( table_key) )
593
+ }
594
+ _ => {
595
+ return parser_err ! ( format!( "Expecting identifier, found : {:?}" , self . peek_token( ) ) ) ;
596
+ }
597
+ }
598
+ } else {
599
+ return parser_err ! ( format!( "Expecting ADD CONSTRAINT, found :{:?}" , self . peek_token( ) ) ) ;
600
+ } ;
601
+ Ok ( ASTNode :: SQLAlterTable {
602
+ name : table_name,
603
+ operation : operation?,
604
+ } )
605
+ } else {
606
+ parser_err ! ( format!( "Expecting TABLE after ALTER, found {:?}" , self . peek_token( ) ) )
607
+ }
608
+ }
609
+
547
610
548
611
/// Parse a copy statement
549
612
pub fn parse_copy ( & mut self ) -> Result < ASTNode , ParserError > {
@@ -1585,6 +1648,13 @@ mod tests {
1585
1648
ALTER TABLE ONLY bazaar.address
1586
1649
ADD CONSTRAINT address_pkey PRIMARY KEY (address_id)" ) ;
1587
1650
let ast = parse_sql ( & sql) ;
1651
+ println ! ( "ast: {:?}" , ast) ;
1652
+ match ast {
1653
+ ASTNode :: SQLAlterTable { name, operation } => {
1654
+ assert_eq ! ( name, "bazaar.address" ) ;
1655
+ }
1656
+ _ => assert ! ( false ) ,
1657
+ }
1588
1658
}
1589
1659
1590
1660
#[ test]
@@ -1594,6 +1664,13 @@ mod tests {
1594
1664
ADD CONSTRAINT customer_address_id_fkey FOREIGN KEY (address_id) REFERENCES public.address(address_id) ON UPDATE CASCADE ON DELETE RESTRICT;
1595
1665
" ) ;
1596
1666
let ast = parse_sql ( & sql) ;
1667
+ println ! ( "ast: {:?}" , ast) ;
1668
+ match ast {
1669
+ ASTNode :: SQLAlterTable { name, operation } => {
1670
+ assert_eq ! ( name, "public.customer" ) ;
1671
+ }
1672
+ _ => assert ! ( false ) ,
1673
+ }
1597
1674
}
1598
1675
1599
1676
#[ test]
0 commit comments