Skip to content
25 changes: 15 additions & 10 deletions src/cli/ast/delete_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ mod tests {
use crate::cli::ast::OrderByDirection;
use crate::cli::ast::LimitClause;
use crate::cli::ast::Operator;
use crate::cli::ast::WhereClause;
use crate::cli::ast::WhereStackElement;
use crate::cli::ast::WhereCondition;
use crate::db::table::Value;

#[test]
Expand Down Expand Up @@ -86,15 +87,19 @@ mod tests {
let statement = result.unwrap();
let expected = SqlStatement::DeleteStatement(DeleteStatement {
table_name: "users".to_string(),
where_clause: Some(WhereClause {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(1),
}),
order_by_clause: Some(vec![OrderByClause {
column: "id".to_string(),
direction: OrderByDirection::Asc,
}]),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(1),
})
]),
order_by_clause: Some(vec![
OrderByClause {
column: "id".to_string(),
direction: OrderByDirection::Asc,
}
]),
limit_clause: Some(LimitClause {
limit: Value::Integer(10),
offset: Some(Value::Integer(5)),
Expand Down
538 changes: 513 additions & 25 deletions src/cli/ast/helpers/where_clause.rs

Large diffs are not rendered by default.

48 changes: 44 additions & 4 deletions src/cli/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ pub struct InsertIntoStatement {
pub struct SelectStatement {
pub table_name: String,
pub columns: SelectStatementColumns,
pub where_clause: Option<WhereClause>,
pub where_clause: Option<Vec<WhereStackElement>>,
pub order_by_clause: Option<Vec<OrderByClause>>,
pub limit_clause: Option<LimitClause>,
}

#[derive(Debug, PartialEq)]
pub struct DeleteStatement {
pub table_name: String,
pub where_clause: Option<WhereClause>,
pub where_clause: Option<Vec<WhereStackElement>>,
pub order_by_clause: Option<Vec<OrderByClause>>,
pub limit_clause: Option<LimitClause>,
}
Expand All @@ -54,7 +54,7 @@ pub struct DeleteStatement {
pub struct UpdateStatement {
pub table_name: String,
pub update_values: Vec<ColumnValue>,
pub where_clause: Option<WhereClause>,
pub where_clause: Option<Vec<WhereStackElement>>,
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -89,12 +89,52 @@ pub enum Operator {
}

#[derive(Debug, PartialEq)]
pub struct WhereClause {
pub struct WhereCondition {
pub column: String,
pub operator: Operator,
pub value: Value,
}

#[derive(Debug, PartialEq)]
pub enum WhereStackElement {
Condition(WhereCondition),
LogicalOperator(LogicalOperator),
Parentheses(Parentheses),
}

pub enum WhereStackOperators {
LogicalOperator(LogicalOperator),
Parentheses(Parentheses),
}

#[derive(Debug, PartialEq)]
pub enum LogicalOperator {
Not,
And,
Or,
}

impl LogicalOperator {
pub fn is_greater_precedence(&self, other: &LogicalOperator) -> bool {
match (self, other) {
(LogicalOperator::Not, LogicalOperator::Not) => false,
(LogicalOperator::Not, _) => true,
(LogicalOperator::And, LogicalOperator::Not) => false,
(LogicalOperator::And, LogicalOperator::And) => false,
(LogicalOperator::And, LogicalOperator::Or) => true,
(LogicalOperator::Or, LogicalOperator::Not) => false,
(LogicalOperator::Or, LogicalOperator::And) => false,
(LogicalOperator::Or, LogicalOperator::Or) => false,
}
}
}

#[derive(Debug, PartialEq)]
pub enum Parentheses {
Left,
Right,
}

#[derive(Debug, PartialEq)]
pub enum OrderByDirection {
Asc,
Expand Down
12 changes: 12 additions & 0 deletions src/cli/ast/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ impl<'a> Parser<'a> {
}
}

pub fn format_error_nearby(&self) -> String {
if self.current < self.tokens.len() {
let token = &self.tokens[self.current];
return format!(
"Error near line {:?}, column {:?}",
token.line_num, token.col_num
);
} else {
return "Error at end of input.".to_string();
}
}

pub fn next_statement(&mut self, builder: &dyn StatementBuilder) -> Option<Result<SqlStatement, String>> {
match self.current_token() {
Ok(token) => match token.token_type {
Expand Down
18 changes: 11 additions & 7 deletions src/cli/ast/select_statement.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{cli::{
ast::{
parser::Parser, SelectStatement, SelectStatementColumns, SqlStatement, WhereClause,
parser::Parser, SelectStatement, SelectStatementColumns, SqlStatement, WhereStackElement,
helpers::{
common::{expect_token_type, tokens_to_identifier_list, get_table_name},
order_by_clause::get_order_by, where_clause::get_where_clause, limit_clause::get_limit
Expand All @@ -14,7 +14,7 @@ pub fn build(parser: &mut Parser) -> Result<SqlStatement, String> {
let columns = get_columns(parser)?;
let table_name = get_table_name(parser)?;
parser.advance()?;
let where_clause: Option<WhereClause> = get_where_clause(parser)?;
let where_clause: Option<Vec<WhereStackElement>> = get_where_clause(parser)?;
let order_by_clause = get_order_by(parser)?;
let limit_clause = get_limit(parser)?;

Expand Down Expand Up @@ -49,6 +49,8 @@ mod tests {
use crate::cli::ast::OrderByClause;
use crate::cli::ast::OrderByDirection;
use crate::cli::ast::LimitClause;
use crate::cli::ast::WhereStackElement;
use crate::cli::ast::WhereCondition;
use crate::cli::ast::test_utils::token;

#[test]
Expand Down Expand Up @@ -163,11 +165,13 @@ mod tests {
columns: SelectStatementColumns::Specific(vec![
"id".to_string(),
]),
where_clause: Some(WhereClause {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(1),
}),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(1),
}),
]),
order_by_clause: Some(vec![
OrderByClause {
column: "id".to_string(),
Expand Down
29 changes: 17 additions & 12 deletions src/cli/ast/update_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ mod tests {
use super::*;
use crate::db::table::Value;
use crate::cli::ast::Operator;
use crate::cli::ast::WhereClause;
use crate::cli::ast::WhereStackElement;
use crate::cli::ast::WhereCondition;
use crate::cli::ast::test_utils::token;

#[test]
Expand Down Expand Up @@ -116,11 +117,13 @@ mod tests {
column: "column".to_string(),
value: Value::Integer(1),
}],
where_clause: Some(WhereClause {
column: "id".to_string(),
operator: Operator::GreaterThan,
value: Value::Integer(2),
}),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "id".to_string(),
operator: Operator::GreaterThan,
value: Value::Integer(2),
}),
]),
});
assert_eq!(statement, expected);
}
Expand Down Expand Up @@ -162,12 +165,14 @@ mod tests {
value: Value::Text("False".to_string()),
},
],
where_clause: Some(WhereClause {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(3),
}),
});
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "id".to_string(),
operator: Operator::Equals,
value: Value::Integer(3),
}),
]),
});
assert_eq!(statement, expected);
}
}
51 changes: 32 additions & 19 deletions src/db/table/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ pub mod where_clause;
pub mod limit_clause;
pub mod order_by_clause;
use crate::db::table::{Table, Value};
use crate::cli::ast::SelectStatement;
use crate::cli::ast::SelectStatementColumns;
use crate::cli::ast::{SelectStatement, WhereStackElement, SelectStatementColumns};
use crate::db::table::common::validate_and_clone_row;


Expand All @@ -23,7 +22,13 @@ pub fn select(table: &Table, statement: SelectStatement) -> Result<Vec<Vec<Value

pub fn get_initial_rows(table: &Table, statement: &SelectStatement) -> Result<Vec<Vec<Value>>, String> {
let mut rows: Vec<Vec<Value>> = vec![];
if let Some(where_clause) = &statement.where_clause {
if let Some(where_stack) = &statement.where_clause {
// This will need to be updated once we have multiple conditions working properly
let where_clause = match where_stack.first() {
Some(WhereStackElement::Condition(where_clause)) => where_clause,
_ => return Err(format!("Found nothing when expected edge")),
};

if !table.has_column(&where_clause.column) {
return Err(format!("Column {} does not exist in table {}", where_clause.column, table.name));

Expand Down Expand Up @@ -61,7 +66,9 @@ pub fn get_columns_from_row(table: &Table, row: &Vec<Value>, selected_columns: &
mod tests {
use super::*;
use crate::db::table::{Table, Value, DataType, ColumnDefinition};
use crate::cli::ast::{SelectStatementColumns, WhereClause, LimitClause, OrderByClause, OrderByDirection, Operator};
use crate::cli::ast::{SelectStatementColumns, LimitClause, OrderByClause, OrderByDirection, Operator};
use crate::cli::ast::WhereStackElement;
use crate::cli::ast::WhereCondition;

fn default_table() -> Table {
Table {
Expand Down Expand Up @@ -129,11 +136,13 @@ mod tests {
let statement = SelectStatement {
table_name: "users".to_string(),
columns: SelectStatementColumns::All,
where_clause: Some(WhereClause {
column: "name".to_string(),
operator: Operator::Equals,
value: Value::Text("John".to_string()),
}),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "name".to_string(),
operator: Operator::Equals,
value: Value::Text("John".to_string()),
}),
]),
order_by_clause: None,
limit_clause: None,
};
Expand All @@ -151,11 +160,13 @@ mod tests {
let statement = SelectStatement {
table_name: "users".to_string(),
columns: SelectStatementColumns::Specific(vec!["name".to_string(), "age".to_string()]),
where_clause: Some(WhereClause {
column: "money".to_string(),
operator: Operator::Equals,
value: Value::Real(1000.0),
}),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "money".to_string(),
operator: Operator::Equals,
value: Value::Real(1000.0),
}),
]),
order_by_clause: None,
limit_clause: None,
};
Expand Down Expand Up @@ -194,11 +205,13 @@ mod tests {
let statement = SelectStatement {
table_name: "users".to_string(),
columns: SelectStatementColumns::All,
where_clause: Some(WhereClause {
column: "column_not_included".to_string(),
operator: Operator::Equals,
value: Value::Text("John".to_string()),
}),
where_clause: Some(vec![
WhereStackElement::Condition(WhereCondition {
column: "column_not_included".to_string(),
operator: Operator::Equals,
value: Value::Text("John".to_string()),
}),
]),
order_by_clause: None,
limit_clause: None,
};
Expand Down
Loading
Loading