Skip to content

Commit 52856f2

Browse files
committed
Add create index statement parser.
1 parent 984c969 commit 52856f2

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

src/lexer.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub enum Token {
3333
pub enum Keyword {
3434
Create,
3535
Table,
36+
Index,
3637
Insert,
3738
Into,
3839
Values,
@@ -73,6 +74,7 @@ impl TryFrom<&str> for Keyword {
7374
match &*s.to_uppercase() {
7475
"CREATE" => Ok(Keyword::Create),
7576
"TABLE" => Ok(Keyword::Table),
77+
"INDEX" => Ok(Keyword::Index),
7678
"INSERT" => Ok(Keyword::Insert),
7779
"INTO" => Ok(Keyword::Into),
7880
"VALUES" => Ok(Keyword::Values),
@@ -306,7 +308,7 @@ mod tests {
306308
#[test]
307309
fn test_all_keywords() -> Result<()> {
308310
let text = r#"
309-
CREATE table Insert INTO VALUES DELETE FROM WHERE UPDATE SET
311+
CREATE table Index INSERT INTO VALUES DELETE FROM WHERE UPDATE SET
310312
SELECT INNER LEFT JOIN ON GROUP BY HAVING ORDER ASC
311313
DESC LIMIT OFFSET INT INTEGER VARCHAR BOOLEAN BEGIN
312314
COMMIT ROLLBACK AS AND OR NOT IS
@@ -318,6 +320,7 @@ mod tests {
318320
vec![
319321
Token::Keyword(Keyword::Create),
320322
Token::Keyword(Keyword::Table),
323+
Token::Keyword(Keyword::Index),
321324
Token::Keyword(Keyword::Insert),
322325
Token::Keyword(Keyword::Into),
323326
Token::Keyword(Keyword::Values),

src/parser.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
#[derive(Debug, PartialEq, Eq, Clone)]
1010
pub enum StatementAST {
1111
CreateTable(CreateTableStatementAST),
12+
CreateIndex(CreateIndexStatementAST),
1213
Select(SelectStatementAST),
1314
Insert(InsertStatementAST),
1415
Delete(DeleteStatementAST),
@@ -28,6 +29,12 @@ pub struct TableElementAST {
2829
pub data_type: DataType,
2930
}
3031
#[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)]
3138
pub struct SelectStatementAST {
3239
pub select_elements: Vec<SelectElementAST>,
3340
pub table_reference: Option<TableReferenceAST>,
@@ -186,6 +193,11 @@ impl Parser {
186193
{
187194
return Ok(StatementAST::CreateTable(self.create_table_statement()?));
188195
}
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+
}
189201
if self.match_token(Token::Keyword(Keyword::Select)) {
190202
return Ok(StatementAST::Select(self.select_statement()?));
191203
}
@@ -259,6 +271,27 @@ impl Parser {
259271
_ => Err(anyhow!("invalid data type")),
260272
}
261273
}
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+
}
262295
fn select_statement(&mut self) -> Result<SelectStatementAST> {
263296
self.consume_token_or_error(Token::Keyword(Keyword::Select))?;
264297
let select_elements = if self.consume_token(Token::Asterisk) {
@@ -746,6 +779,25 @@ mod tests {
746779
Ok(())
747780
}
748781

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+
749801
#[test]
750802
fn test_parse_select() -> Result<()> {
751803
let sql = r#"

src/server.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ impl Session {
179179
.create_table(&ast, txn_id)?;
180180
format!("table {} created", ast.table_name)
181181
}
182+
StatementAST::CreateIndex(ast) => {
183+
format!(
184+
"create index is not implemented yet ({:?}, {:?}, {:?})",
185+
ast.index_name, ast.table_name, ast.column_names
186+
)
187+
}
182188
_ => {
183189
let (rows, schema) = self
184190
.instance

0 commit comments

Comments
 (0)