Skip to content
This repository has been archived by the owner on Sep 28, 2021. It is now read-only.

Commit

Permalink
use new query engine for update queries (#474)
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-dukhno committed Jan 30, 2021
1 parent 34a89ae commit f6b9991
Show file tree
Hide file tree
Showing 16 changed files with 751 additions and 637 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 40 additions & 3 deletions data/catalog/src/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use binary::Binary;
use data_definition_operations::{
ExecutionError, ExecutionOutcome, Kind, ObjectState, Record, Step, SystemObject, SystemOperation,
};
use data_manipulation_typed_tree::{StaticTypedItem, StaticTypedTree, TypedValue};
use data_manipulation_typed_tree::{DynamicTypedItem, DynamicTypedTree, StaticTypedItem, StaticTypedTree, TypedValue};
use definition::{ColumnDef, FullTableName, SchemaName, TableDef};
use repr::Datum;
use std::{collections::HashMap, sync::Arc};
Expand Down Expand Up @@ -419,7 +419,7 @@ impl InMemoryTable {
InMemoryTable { columns, data_table }
}

fn eval(&self, tree: &StaticTypedTree) -> Datum {
fn eval_static(&self, tree: &StaticTypedTree) -> Datum {
match tree {
StaticTypedTree::Item(StaticTypedItem::Const(TypedValue::SmallInt(value))) => Datum::from_i16(*value),
StaticTypedTree::Item(StaticTypedItem::Const(TypedValue::Integer(value))) => Datum::from_i32(*value),
Expand All @@ -433,6 +433,20 @@ impl InMemoryTable {
}
}

fn eval_dynamic(&self, tree: &DynamicTypedTree) -> Datum {
match tree {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::SmallInt(value))) => Datum::from_i16(*value),
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Integer(value))) => Datum::from_i32(*value),
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::BigInt(value))) => Datum::from_i64(*value),
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Bool(value))) => Datum::from_bool(*value),
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::String(string))) => {
Datum::from_string(string.clone())
}
DynamicTypedTree::Item(_) => unimplemented!(),
DynamicTypedTree::Operation { .. } => unimplemented!(),
}
}

fn has_column(&self, column_name: &str) -> Option<(usize, &ColumnDef)> {
self.columns
.iter()
Expand All @@ -448,7 +462,11 @@ impl SqlTable for InMemoryTable {
.map(|row| {
let mut to_insert = vec![];
for v in row {
to_insert.push(v.as_ref().map(|v| self.eval(&v)).unwrap_or_else(Datum::from_null));
to_insert.push(
v.as_ref()
.map(|v| self.eval_static(&v))
.unwrap_or_else(Datum::from_null),
);
}
println!("{:#?}", to_insert);
Binary::pack(&to_insert)
Expand Down Expand Up @@ -517,6 +535,25 @@ impl SqlTable for InMemoryTable {
let keys = self.data_table.select().map(|(key, _value)| key).collect();
self.data_table.delete(keys)
}

fn update(&self, column_names: Vec<String>, assignments: Vec<DynamicTypedTree>) -> usize {
let delta = self
.data_table
.select()
.map(|(key, value)| {
let mut unpacked_row = value.unpack();
for (column_name, assignment) in column_names.iter().zip(assignments.iter()) {
let new_value = match self.has_column(column_name) {
None => unimplemented!(),
Some((index, _)) => (index, self.eval_dynamic(assignment)),
};
unpacked_row[new_value.0] = new_value.1;
}
(key, Binary::pack(&unpacked_row))
})
.collect();
self.data_table.update(delta)
}
}

#[cfg(test)]
Expand Down
4 changes: 3 additions & 1 deletion data/catalog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod on_disk;

use binary::Binary;
use data_definition_operations::{ExecutionError, ExecutionOutcome, SystemOperation};
use data_manipulation_typed_tree::StaticTypedTree;
use data_manipulation_typed_tree::{DynamicTypedTree, StaticTypedTree};
use definition::{ColumnDef, FullTableName, SchemaName, TableDef};
use std::{
fmt::{self, Debug, Formatter},
Expand Down Expand Up @@ -100,6 +100,8 @@ pub trait SqlTable {
fn select_with_columns(&self, column_names: Vec<String>) -> Result<(Vec<ColumnDef>, Vec<Vec<Datum>>), String>;

fn delete_all(&self) -> usize;

fn update(&self, column_names: Vec<String>, assignments: Vec<DynamicTypedTree>) -> usize;
}

pub trait Database {
Expand Down
1 change: 1 addition & 0 deletions data_manipulation/query_result/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use repr::Datum;
pub enum QueryExecution {
Inserted(usize),
Deleted(usize),
Updated(usize),
Selected((Vec<ColumnDef>, Vec<Vec<Datum>>)),
}

Expand Down
1 change: 0 additions & 1 deletion data_manipulation/typed_queries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ publish = false
[dependencies]
data_manipulation_typed_tree = { path = "../typed_tree" }
definition = { path = "../../entities/definition" }
types = { path = "../../entities/types" }
8 changes: 8 additions & 0 deletions data_manipulation/typed_queries/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,18 @@ pub struct DeleteQuery {
pub full_table_name: FullTableName,
}

#[derive(Debug, PartialEq)]
pub struct UpdateQuery {
pub full_table_name: FullTableName,
pub column_names: Vec<String>,
pub assignments: Vec<DynamicTypedTree>,
}

#[derive(Debug, PartialEq)]
pub enum TypedWrite {
Insert(InsertQuery),
Delete(DeleteQuery),
Update(UpdateQuery),
}

#[derive(Debug, PartialEq)]
Expand Down
4 changes: 2 additions & 2 deletions data_manipulation/typed_tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl TypedValue {
}
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum DynamicTypedTree {
Operation {
left: Box<DynamicTypedTree>,
Expand All @@ -90,7 +90,7 @@ pub enum DynamicTypedTree {
Item(DynamicTypedItem),
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum DynamicTypedItem {
Const(TypedValue),
Column(String),
Expand Down
1 change: 0 additions & 1 deletion data_manipulation/untyped_queries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ publish = false
[dependencies]
data_manipulation_untyped_tree = { path = "../untyped_tree" }
definition = { path = "../../entities/definition" }
types = { path = "../../entities/types" }
3 changes: 1 addition & 2 deletions data_manipulation/untyped_queries/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

use data_manipulation_untyped_tree::{DynamicUntypedTree, StaticUntypedTree};
use definition::FullTableName;
use types::SqlType;

#[derive(Debug, PartialEq)]
pub struct InsertQuery {
Expand All @@ -26,7 +25,7 @@ pub struct InsertQuery {
#[derive(Debug, PartialEq)]
pub struct UpdateQuery {
pub full_table_name: FullTableName,
pub sql_types: Vec<SqlType>,
pub column_names: Vec<String>,
pub assignments: Vec<DynamicUntypedTree>,
}

Expand Down
12 changes: 6 additions & 6 deletions query_analyzer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,33 +97,33 @@ impl<CD: CatalogDefinition> Analyzer<CD> {
Some(None) => Err(AnalysisError::table_does_not_exist(full_table_name)),
Some(Some(table_info)) => {
let table_columns = table_info.columns();
let mut sql_types = vec![];
let mut column_names = vec![];
let mut assignments = vec![];
for assignment in stmt_assignments {
let sql_ast::Assignment { id, value } = assignment;
let name = id.to_string();
let mut found = None;
for table_column in table_columns {
if table_column.has_name(&name) {
found = Some(table_column.sql_type());
found = Some(name.clone());
break;
}
}
match found {
None => unimplemented!("Column not found is not covered yet"),
Some(sql_type) => {
None => return Err(AnalysisError::ColumnNotFound(name)),
Some(name) => {
assignments.push(DynamicTreeBuilder::build_from(
&value,
&statement,
&table_columns,
)?);
sql_types.push(sql_type);
column_names.push(name);
}
}
}
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name,
sql_types,
column_names,
assignments,
})))
}
Expand Down
24 changes: 12 additions & 12 deletions query_analyzer/src/tests/updates/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn update_number() {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::small_int()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::Number(BigDecimal::from(1))
))]
Expand All @@ -53,7 +53,7 @@ fn update_string() {
analyzer.analyze(update_statement(vec![SCHEMA, TABLE], vec![("col", string("str"))])),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::char(5)],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::String("str".to_owned())
))]
Expand All @@ -74,7 +74,7 @@ fn update_boolean() {
analyzer.analyze(update_statement(vec![SCHEMA, TABLE], vec![("col", boolean(true))])),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::bool()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::Bool(
Bool(true)
)))],
Expand All @@ -95,7 +95,7 @@ fn update_null() {
analyzer.analyze(update_statement(vec![SCHEMA, TABLE], vec![("col", null())])),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::bool()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::Null))],
})))
);
Expand All @@ -121,7 +121,7 @@ fn update_with_column_value() {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::small_int()],
column_names: vec!["col_1".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Column {
name: "col_2".to_owned(),
sql_type: SqlType::small_int(),
Expand Down Expand Up @@ -170,7 +170,7 @@ fn update_table_with_parameters() {
analyzer.analyze(update_stmt_with_parameters(vec![SCHEMA, TABLE])),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::integer()],
column_names: vec!["col_2".to_owned()],
assignments: vec![DynamicUntypedTree::Item(DynamicUntypedItem::Param(0))]
})))
);
Expand Down Expand Up @@ -217,7 +217,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::small_int()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::Number(BigDecimal::from(1))
Expand Down Expand Up @@ -248,7 +248,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::var_char(255)],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::String("str".to_owned())
Expand Down Expand Up @@ -279,7 +279,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::bool()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::Number(BigDecimal::from(1))
Expand Down Expand Up @@ -310,7 +310,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::bool()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::Bool(
Bool(true)
Expand Down Expand Up @@ -341,7 +341,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::small_int()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::Number(BigDecimal::from(1))
Expand Down Expand Up @@ -372,7 +372,7 @@ mod multiple_values {
)),
Ok(QueryAnalysis::Write(UntypedWrite::Update(UpdateQuery {
full_table_name: FullTableName::from((&SCHEMA, &TABLE)),
sql_types: vec![SqlType::bool()],
column_names: vec!["col".to_owned()],
assignments: vec![DynamicUntypedTree::Operation {
left: Box::new(DynamicUntypedTree::Item(DynamicUntypedItem::Const(
UntypedValue::String("s".to_owned())
Expand Down
25 changes: 25 additions & 0 deletions query_processing/type_inference/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,31 @@ impl TypeInference {
DynamicUntypedTree::Item(DynamicUntypedItem::Column { name, .. }) => {
DynamicTypedTree::Item(DynamicTypedItem::Column(name))
}
DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::Number(num))) => {
if num.is_integer() {
if self.small_int_range.contains(&num) {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::SmallInt(num.to_i16().unwrap())))
} else if self.integer_range.contains(&num) {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Integer(num.to_i32().unwrap())))
} else if self.big_int_range.contains(&num) {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::BigInt(num.to_i64().unwrap())))
} else {
unimplemented!()
}
} else if self.real_range.contains(&num) {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Real(num.to_f32().unwrap())))
} else if self.double_precision_range.contains(&num) {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Double(num.to_f64().unwrap())))
} else {
unimplemented!()
}
}
DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::String(str))) => {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::String(str)))
}
DynamicUntypedTree::Item(DynamicUntypedItem::Const(UntypedValue::Bool(Bool(boolean)))) => {
DynamicTypedTree::Item(DynamicTypedItem::Const(TypedValue::Bool(boolean)))
}
_ => unimplemented!(),
}
}
Expand Down

0 comments on commit f6b9991

Please sign in to comment.