Skip to content

Commit

Permalink
make column_name type optional
Browse files Browse the repository at this point in the history
  • Loading branch information
mnmandahalf committed May 12, 2024
1 parent e7d627e commit 09defe6
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 53 deletions.
57 changes: 30 additions & 27 deletions src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub struct BoundSubqueryTableReferenceAST {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct BoundInsertStatementAST {
pub table_name: String,
pub column_names: Vec<String>,
pub column_names: Option<Vec<String>>,
pub values: Vec<BoundExpressionAST>,
pub first_page_id: PageID,
pub table_schema: Schema,
Expand Down Expand Up @@ -441,33 +441,36 @@ impl Binder {
.lock()
.map_err(|_| anyhow::anyhow!("lock error"))?
.get_schema_by_table_name(&statement.table_name, self.txn_id)?;
if statement.column_names.len() > 0 {
if statement.column_names.len() != statement.values.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
statement.column_names.len(),
statement.values.len()
));
}
if statement.column_names.len() > schema.columns.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
schema.columns.len(),
statement.column_names.len()
));
}
for column_name in &statement.column_names {
if !schema.columns.iter().any(|column| column.name == *column_name) {
return Err(anyhow::anyhow!("column {} not found", column_name));
match &statement.column_names {
Some(column_names) => {
if column_names.len() != statement.values.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
column_names.len(),
statement.values.len()
));
}
if column_names.len() > schema.columns.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
schema.columns.len(),
column_names.len()
));
}
for column_name in column_names {
if !schema.columns.iter().any(|column| column.name == *column_name) {
return Err(anyhow::anyhow!("column {} not found", column_name));
}
}
}
} else {
if statement.values.len() != schema.columns.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
schema.columns.len(),
statement.values.len()
));
None => {
if statement.values.len() != schema.columns.len() {
return Err(anyhow::anyhow!(
"expected {} values, but got {}",
schema.columns.len(),
statement.values.len()
));
}
}
}
let mut values = Vec::new();
Expand Down Expand Up @@ -1307,7 +1310,7 @@ mod tests {
bound_statement,
BoundStatementAST::Insert(BoundInsertStatementAST {
table_name: "t1".to_string(),
column_names: vec![],
column_names: None,
values: vec![
BoundExpressionAST::Literal(BoundLiteralExpressionAST {
value: Value::Integer(IntegerValue(1)),
Expand Down
22 changes: 10 additions & 12 deletions src/executor/insert_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,17 @@ impl InsertExecutor<'_> {
.enumerate()
.map(|(i, c)| {
let index;
if self.plan.column_names.len() > 0 {
let position = self
.plan
.column_names
.iter()
.position(|x| x == &c.name);
// TODO: support default value
match position {
Some(i) => index = i,
None => return Ok(Value::Null),
match &self.plan.column_names {
Some(column_names) => {
let position = column_names.iter().position(|x| x == &c.name);
match position {
Some(pos) => index = pos,
None => return Ok(Value::Null)
}
},
None => {
index = i;
}
} else {
index = i;
}
let raw_value = self.plan.values[index].eval(
&vec![&Tuple::new(None, &[])],
Expand Down
24 changes: 11 additions & 13 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub struct LimitAST {
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct InsertStatementAST {
pub table_name: String,
pub column_names: Vec<String>,
pub column_names: Option<Vec<String>>,
// TODO: support multiple rows
pub values: Vec<ExpressionAST>,
}
Expand Down Expand Up @@ -461,20 +461,18 @@ impl Parser {
self.consume_token_or_error(Token::Keyword(Keyword::Insert))?;
self.consume_token_or_error(Token::Keyword(Keyword::Into))?;
let table_name = self.identifier()?;
// verify column names
let column_names = if self.consume_token(Token::LeftParen) {
let mut column_names = Vec::new();
let mut column_names: Option<Vec<String>> = None;
if self.consume_token(Token::LeftParen) {
let mut names = Vec::new();
loop {
column_names.push(self.identifier()?);
names.push(self.identifier()?);
if !self.consume_token(Token::Comma) {
break;
}
}
self.consume_token_or_error(Token::RightParen)?;
column_names
} else {
Vec::new()
};
column_names = Some(names);
}
self.consume_token_or_error(Token::Keyword(Keyword::Values))?;
self.consume_token_or_error(Token::LeftParen)?;
let mut values = Vec::new();
Expand Down Expand Up @@ -971,7 +969,7 @@ mod tests {
statement,
StatementAST::Insert(InsertStatementAST {
table_name: String::from("users"),
column_names: vec![],
column_names: None,
values: vec![
ExpressionAST::Literal(LiteralExpressionAST {
value: Value::Integer(IntegerValue(1)),
Expand All @@ -989,7 +987,7 @@ mod tests {
}

#[test]
fn test_parse_insert_with_column_names() -> Result<()> {
fn test_parse_insert_with_columns() -> Result<()> {
let sql = "INSERT INTO users (id, name, is_deleted) VALUES (1, 'foo', true)";
let mut parser = Parser::new(tokenize(&mut sql.chars().peekable())?);

Expand All @@ -998,11 +996,11 @@ mod tests {
statement,
StatementAST::Insert(InsertStatementAST {
table_name: String::from("users"),
column_names: vec![
column_names: Some(vec![
String::from("id"),
String::from("name"),
String::from("is_deleted"),
],
]),
values: vec![
ExpressionAST::Literal(LiteralExpressionAST {
value: Value::Integer(IntegerValue(1)),
Expand Down
2 changes: 1 addition & 1 deletion src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub struct EmptyRowPlan {
pub struct InsertPlan {
pub first_page_id: PageID,
pub table_schema: Schema,
pub column_names: Vec<String>,
pub column_names: Option<Vec<String>>,
pub values: Vec<BoundExpressionAST>,
pub schema: Schema,
}
Expand Down

0 comments on commit 09defe6

Please sign in to comment.