Skip to content

Commit

Permalink
Feat/prepare statment (#249)
Browse files Browse the repository at this point in the history
* feat: impl `PrepareStatement`

* chore: TPCC use `PrepareStatement` on Test
  • Loading branch information
KKould authored Nov 26, 2024
1 parent 2e1bb34 commit 874529a
Show file tree
Hide file tree
Showing 25 changed files with 816 additions and 269 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ fncksql_data
fncksql_bench
sqlite_bench
fnck_sql_tpcc
copy.csv

tests/data/row_20000.csv
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Order-Status : 0.492 (0.575)
Delivery : 6.109 (6.473)
Stock-Level : 0.001 (0.001)
<TpmC>
89.9205557572134 Tpmc
98 Tpmc
```
#### PG Wire Service
run `cargo run --features="net"` to start server
Expand Down
26 changes: 14 additions & 12 deletions src/binder/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ impl<T: Transaction> Binder<'_, '_, T> {
select_list: &mut [ScalarExpression],
groupby: &[Expr],
) -> Result<(), DatabaseError> {
self.validate_groupby_illegal_column(select_list, groupby)?;
let mut group_by_exprs = Vec::with_capacity(groupby.len());
for expr in groupby.iter() {
group_by_exprs.push(self.bind_expr(expr)?);
}

self.validate_groupby_illegal_column(select_list, &group_by_exprs)?;

for gb in groupby {
let mut expr = self.bind_expr(gb)?;
self.visit_group_by_expr(select_list, &mut expr);
for expr in group_by_exprs.iter_mut() {
self.visit_group_by_expr(select_list, expr);
}
Ok(())
}
Expand Down Expand Up @@ -213,41 +217,39 @@ impl<T: Transaction> Binder<'_, '_, T> {
fn validate_groupby_illegal_column(
&mut self,
select_items: &[ScalarExpression],
groupby: &[Expr],
groupby: &[ScalarExpression],
) -> Result<(), DatabaseError> {
let mut group_raw_exprs = vec![];
for expr in groupby {
let expr = self.bind_expr(expr)?;

if let ScalarExpression::Alias { alias, .. } = expr {
let alias_expr = select_items.iter().find(|column| {
if let ScalarExpression::Alias {
alias: inner_alias, ..
} = &column
{
alias == *inner_alias
alias == inner_alias
} else {
false
}
});

if let Some(inner_expr) = alias_expr {
group_raw_exprs.push(inner_expr.clone());
group_raw_exprs.push(inner_expr);
}
} else {
group_raw_exprs.push(expr);
}
}
let mut group_raw_set: HashSet<&ScalarExpression, RandomState> =
HashSet::from_iter(group_raw_exprs.iter());
HashSet::from_iter(group_raw_exprs.iter().copied());

for expr in select_items {
if expr.has_agg_call() {
continue;
}
group_raw_set.remove(expr);

if !group_raw_exprs.iter().contains(expr) {
if !group_raw_exprs.iter().contains(&expr) {
return Err(DatabaseError::AggMiss(format!(
"`{}` must appear in the GROUP BY clause or be used in an aggregate function",
expr
Expand All @@ -257,7 +259,7 @@ impl<T: Transaction> Binder<'_, '_, T> {

if !group_raw_set.is_empty() {
return Err(DatabaseError::AggMiss(
"In the GROUP BY clause the field must be in the select clause".to_string(),
"in the GROUP BY clause the field must be in the select clause".to_string(),
));
}

Expand Down
3 changes: 3 additions & 0 deletions src/binder/create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ mod tests {
use crate::types::LogicalType;
use crate::utils::lru::SharedLruCache;
use sqlparser::ast::CharLengthUnits;
use std::cell::RefCell;
use std::hash::RandomState;
use std::sync::atomic::AtomicUsize;
use tempfile::TempDir;
Expand All @@ -172,6 +173,7 @@ mod tests {
let table_functions = Default::default();

let sql = "create table t1 (id int primary key, name varchar(10) null)";
let args = RefCell::new(Vec::new());
let mut binder = Binder::new(
BinderContext::new(
&table_cache,
Expand All @@ -181,6 +183,7 @@ mod tests {
&table_functions,
Arc::new(AtomicUsize::new(0)),
),
&args,
None,
);
let stmt = crate::parser::parse_sql(sql).unwrap();
Expand Down
19 changes: 17 additions & 2 deletions src/binder/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::expression::agg::AggKind;
use itertools::Itertools;
use sqlparser::ast::{
BinaryOperator, CharLengthUnits, DataType, Expr, Function, FunctionArg, FunctionArgExpr, Ident,
Query, UnaryOperator,
Query, UnaryOperator, Value,
};
use std::collections::HashMap;
use std::slice;
Expand Down Expand Up @@ -48,7 +48,21 @@ impl<'a, T: Transaction> Binder<'a, '_, T> {
}
Expr::CompoundIdentifier(idents) => self.bind_column_ref_from_identifiers(idents, None),
Expr::BinaryOp { left, right, op } => self.bind_binary_op_internal(left, right, op),
Expr::Value(v) => Ok(ScalarExpression::Constant(v.into())),
Expr::Value(v) => {
let value = if let Value::Placeholder(name) = v {
let (i, _) = self
.args
.borrow()
.iter()
.enumerate()
.find(|(_, (key, _))| key == name)
.ok_or_else(|| DatabaseError::ParametersNotFound(name.to_string()))?;
self.args.borrow_mut().remove(i).1
} else {
v.into()
};
Ok(ScalarExpression::Constant(value))
}
Expr::Function(func) => self.bind_function(func),
Expr::Nested(expr) => self.bind_expr(expr),
Expr::UnaryOp { expr, op } => self.bind_unary_op_internal(expr, op),
Expand Down Expand Up @@ -266,6 +280,7 @@ impl<'a, T: Transaction> Binder<'a, '_, T> {
table_functions,
temp_table_id.clone(),
),
self.args,
Some(self),
);
let mut sub_query = binder.bind_query(subquery)?;
Expand Down
5 changes: 1 addition & 4 deletions src/binder/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,11 @@ impl<T: Transaction> Binder<'_, '_, T> {

expression.constant_calculation()?;
match expression {
ScalarExpression::Constant(mut value) => {
ScalarExpression::Constant(value) => {
let ty = schema_ref[i].datatype();
// Check if the value length is too long
value.check_len(ty)?;

if value.logical_type() != *ty {
value = value.cast(ty)?;
}
row.push(value);
}
ScalarExpression::Empty => {
Expand Down
14 changes: 12 additions & 2 deletions src/binder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ mod truncate;
mod update;

use sqlparser::ast::{Ident, ObjectName, ObjectType, SetExpr, Statement};
use std::cell::RefCell;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

use crate::catalog::view::View;
use crate::catalog::{ColumnRef, TableCatalog, TableName};
use crate::db::{ScalaFunctions, TableFunctions};
use crate::db::{Args, ScalaFunctions, TableFunctions};
use crate::errors::DatabaseError;
use crate::expression::ScalarExpression;
use crate::planner::operator::join::JoinType;
Expand Down Expand Up @@ -321,14 +322,20 @@ impl<'a, T: Transaction> BinderContext<'a, T> {
pub struct Binder<'a, 'b, T: Transaction> {
context: BinderContext<'a, T>,
table_schema_buf: HashMap<TableName, Option<SchemaOutput>>,
args: &'a RefCell<Args>,
pub(crate) parent: Option<&'b Binder<'a, 'b, T>>,
}

impl<'a, 'b, T: Transaction> Binder<'a, 'b, T> {
pub fn new(context: BinderContext<'a, T>, parent: Option<&'b Binder<'a, 'b, T>>) -> Self {
pub fn new(
context: BinderContext<'a, T>,
args: &'a RefCell<Args>,
parent: Option<&'b Binder<'a, 'b, T>>,
) -> Self {
Binder {
context,
table_schema_buf: Default::default(),
args,
parent,
}
}
Expand Down Expand Up @@ -487,6 +494,7 @@ pub mod test {
use crate::types::ColumnId;
use crate::types::LogicalType::Integer;
use crate::utils::lru::SharedLruCache;
use std::cell::RefCell;
use std::hash::RandomState;
use std::path::PathBuf;
use std::sync::atomic::AtomicUsize;
Expand All @@ -505,6 +513,7 @@ pub mod test {
let scala_functions = Default::default();
let table_functions = Default::default();
let transaction = self.storage.transaction()?;
let args = RefCell::new(Vec::new());
let mut binder = Binder::new(
BinderContext::new(
&self.table_cache,
Expand All @@ -514,6 +523,7 @@ pub mod test {
&table_functions,
Arc::new(AtomicUsize::new(0)),
),
&args,
None,
);
let stmt = crate::parser::parse_sql(sql)?;
Expand Down
1 change: 1 addition & 0 deletions src/binder/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@ impl<'a: 'b, 'b, T: Transaction> Binder<'a, 'b, T> {
table_functions,
temp_table_id.clone(),
),
self.args,
Some(self),
);
let mut right = binder.bind_single_table_ref(relation, Some(join_type))?;
Expand Down
Loading

0 comments on commit 874529a

Please sign in to comment.