Skip to content

Commit

Permalink
Support INSERT INTO
Browse files Browse the repository at this point in the history
  • Loading branch information
PakhomovAlexander committed Oct 22, 2024
1 parent a9ee074 commit 706757d
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 3 deletions.
5 changes: 2 additions & 3 deletions agenda.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
Today we are going to:
- [x] WHERE statement support in parser
- [x] Maybe CREATE TABLE
- [ ] DROP TABLE
- [ ] INSERT INTO support
- [ ] Function call support
- [x] DROP TABLE
- [x] INSERT INTO support



Expand Down
120 changes: 120 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ pub enum Op {

CreateTable,
DropTable,
InsertInto,

ColumnDefinition,
ColumnList,
Values,
}

impl<'a> Parser<'a> {
Expand Down Expand Up @@ -134,6 +137,7 @@ impl<'a> Parser<'a> {
Some(Ok(Token::Select)) => self.parse_select(min_bp),
Some(Ok(Token::Create)) => self.parse_create(min_bp),
Some(Ok(Token::Drop)) => self.parse_drop(min_bp),
Some(Ok(Token::Insert)) => self.parse_insert(min_bp),
s => panic!("Unexpected token: {:?}", s),
};

Expand Down Expand Up @@ -295,6 +299,82 @@ impl<'a> Parser<'a> {
}
}

fn parse_insert(&mut self, min_bp: u8) -> Node {
match self.lexer.next() {
Some(Ok(Token::Into)) => self.parse_insert_into(min_bp),
s => panic!("Unexpected token: {:?}", s),
}
}

fn parse_insert_into(&mut self, _min_bp: u8) -> Node {
let lhs = match self.lexer.next() {
Some(Ok(Token::Identifier {
first_name,
second_name: None,
third_name: None,
})) => Literal::identifier(first_name),
s => panic!("Unexpected token: {:?}", s),
};

match self.lexer.next() {
Some(Ok(Token::OpenParen)) => {
let mut columns = vec![];

loop {
let column_name = match self.lexer.next() {
Some(Ok(Token::Identifier {
first_name,
second_name: None,
third_name: None,
})) => Literal::identifier(first_name),
Some(Ok(Token::Comma)) => continue,
Some(Ok(Token::CloseParen)) => break,
s => panic!("Unexpected token: {:?}", s),
};

columns.push(Node::Leaf(column_name));
}

let values = match self.lexer.next() {
Some(Ok(Token::Values)) => self.parse_values(),
s => panic!("Unexpected token: {:?}", s),
};

Node::Prefix(
Op::InsertInto,
vec![
Node::Leaf(lhs),
Node::Prefix(Op::ColumnList, columns),
Node::Prefix(Op::Values, values),
],
)
}
s => panic!("Unexpected token: {:?}", s),
}
}

fn parse_values(&mut self) -> Vec<Node> {
match self.lexer.next() {
Some(Ok(Token::OpenParen)) => {
let mut values = vec![];

loop {
let value = match self.lexer.next() {
Some(Ok(Token::NumericLiteral(i))) => Node::Leaf(Literal::numeric(i)),
Some(Ok(Token::CloseParen)) => break,
Some(Ok(Token::Comma)) => continue,
s => panic!("Unexpected token: {:?}", s),
};

values.push(value);
}

values
}
s => panic!("Unexpected token: {:?}", s),
}
}

fn prefix_operator_bp(op: &Op) -> ((), u8) {
match op {
Op::Not => ((), 7),
Expand Down Expand Up @@ -365,6 +445,10 @@ mod tests {
Node::Infix(op, nodes)
}

fn prefix_vec(op: Op, nodes: Vec<Node>) -> Node {
Node::Prefix(op, nodes)
}

fn prefix(op: Op, lhs: Node) -> Node {
Node::Prefix(op, vec![lhs])
}
Expand Down Expand Up @@ -701,4 +785,40 @@ mod tests {
prefix(Op::DropTable, leaf(id("table1")),)
);
}

#[test]
fn insert_into_single_column() {
let input = r"
insert into table1 (col1) values (1)";

assert_eq!(
parse(input),
prefix_vec(
Op::InsertInto,
vec![
leaf(id("table1")),
prefix_vec(Op::ColumnList, vec![leaf(id("col1"))]),
prefix_vec(Op::Values, vec![leaf(num(1))])
]
)
);
}

#[test]
fn insert_into() {
let input = r"
insert into table1 (col1, col2) values (1, 2)";

assert_eq!(
parse(input),
prefix_vec(
Op::InsertInto,
vec![
leaf(id("table1")),
prefix_vec(Op::ColumnList, vec![leaf(id("col1")), leaf(id("col2"))]),
prefix_vec(Op::Values, vec![leaf(num(1)), leaf(num(2))])
]
)
);
}
}

0 comments on commit 706757d

Please sign in to comment.