@@ -9,6 +9,7 @@ use crate::{
9
9
#[ derive( Debug , PartialEq , Eq , Clone ) ]
10
10
pub enum StatementAST {
11
11
CreateTable ( CreateTableStatementAST ) ,
12
+ CreateIndex ( CreateIndexStatementAST ) ,
12
13
Select ( SelectStatementAST ) ,
13
14
Insert ( InsertStatementAST ) ,
14
15
Delete ( DeleteStatementAST ) ,
@@ -28,6 +29,12 @@ pub struct TableElementAST {
28
29
pub data_type : DataType ,
29
30
}
30
31
#[ derive( Debug , PartialEq , Eq , Clone ) ]
32
+ pub struct CreateIndexStatementAST {
33
+ pub index_name : String ,
34
+ pub table_name : String ,
35
+ pub column_names : Vec < String > ,
36
+ }
37
+ #[ derive( Debug , PartialEq , Eq , Clone ) ]
31
38
pub struct SelectStatementAST {
32
39
pub select_elements : Vec < SelectElementAST > ,
33
40
pub table_reference : Option < TableReferenceAST > ,
@@ -186,6 +193,11 @@ impl Parser {
186
193
{
187
194
return Ok ( StatementAST :: CreateTable ( self . create_table_statement ( ) ?) ) ;
188
195
}
196
+ if self . match_token ( Token :: Keyword ( Keyword :: Create ) )
197
+ && self . match_look_ahead ( Token :: Keyword ( Keyword :: Index ) )
198
+ {
199
+ return Ok ( StatementAST :: CreateIndex ( self . create_index_statement ( ) ?) ) ;
200
+ }
189
201
if self . match_token ( Token :: Keyword ( Keyword :: Select ) ) {
190
202
return Ok ( StatementAST :: Select ( self . select_statement ( ) ?) ) ;
191
203
}
@@ -259,6 +271,27 @@ impl Parser {
259
271
_ => Err ( anyhow ! ( "invalid data type" ) ) ,
260
272
}
261
273
}
274
+ fn create_index_statement ( & mut self ) -> Result < CreateIndexStatementAST > {
275
+ self . consume_token_or_error ( Token :: Keyword ( Keyword :: Create ) ) ?;
276
+ self . consume_token_or_error ( Token :: Keyword ( Keyword :: Index ) ) ?;
277
+ let index_name = self . identifier ( ) ?;
278
+ self . consume_token_or_error ( Token :: Keyword ( Keyword :: On ) ) ?;
279
+ let table_name = self . identifier ( ) ?;
280
+ self . consume_token_or_error ( Token :: LeftParen ) ?;
281
+ let mut column_names = Vec :: new ( ) ;
282
+ loop {
283
+ column_names. push ( self . identifier ( ) ?) ;
284
+ if !self . consume_token ( Token :: Comma ) {
285
+ break ;
286
+ }
287
+ }
288
+ self . consume_token_or_error ( Token :: RightParen ) ?;
289
+ Ok ( CreateIndexStatementAST {
290
+ index_name,
291
+ table_name,
292
+ column_names,
293
+ } )
294
+ }
262
295
fn select_statement ( & mut self ) -> Result < SelectStatementAST > {
263
296
self . consume_token_or_error ( Token :: Keyword ( Keyword :: Select ) ) ?;
264
297
let select_elements = if self . consume_token ( Token :: Asterisk ) {
@@ -746,6 +779,25 @@ mod tests {
746
779
Ok ( ( ) )
747
780
}
748
781
782
+ #[ test]
783
+ fn test_parse_create_index ( ) -> Result < ( ) > {
784
+ let sql = r#"
785
+ CREATE INDEX id_name_index ON users (id, name);
786
+ "# ;
787
+ let mut parser = Parser :: new ( tokenize ( & mut sql. chars ( ) . peekable ( ) ) ?) ;
788
+
789
+ let statement = parser. parse ( ) ?;
790
+ assert_eq ! (
791
+ statement,
792
+ StatementAST :: CreateIndex ( CreateIndexStatementAST {
793
+ index_name: String :: from( "id_name_index" ) ,
794
+ table_name: String :: from( "users" ) ,
795
+ column_names: vec![ String :: from( "id" ) , String :: from( "name" ) ] ,
796
+ } )
797
+ ) ;
798
+ Ok ( ( ) )
799
+ }
800
+
749
801
#[ test]
750
802
fn test_parse_select ( ) -> Result < ( ) > {
751
803
let sql = r#"
0 commit comments