Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions src/binder/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,22 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
})
}
Expr::Exists { subquery, negated } => {
let (sub_query, column) = self.bind_subquery(subquery)?;
let (sub_query, column) = self.bind_subquery(None, subquery)?;
let (_, sub_query) = if !self.context.is_step(&QueryBindStep::Where) {
self.bind_temp_table(column, sub_query)?
} else {
(ScalarExpression::ColumnRef(column), sub_query)
(column, sub_query)
};
self.context
.sub_query(SubQueryType::ExistsSubQuery(*negated, sub_query));
Ok(ScalarExpression::Constant(DataValue::Boolean(true)))
}
Expr::Subquery(subquery) => {
let (sub_query, column) = self.bind_subquery(subquery)?;
let (sub_query, column) = self.bind_subquery(None, subquery)?;
let (expr, sub_query) = if !self.context.is_step(&QueryBindStep::Where) {
self.bind_temp_table(column, sub_query)?
} else {
(ScalarExpression::ColumnRef(column), sub_query)
(column, sub_query)
};
self.context.sub_query(SubQueryType::SubQuery(sub_query));
Ok(expr)
Expand All @@ -169,7 +169,8 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
negated,
} => {
let left_expr = Box::new(self.bind_expr(expr)?);
let (sub_query, column) = self.bind_subquery(subquery)?;
let (sub_query, column) =
self.bind_subquery(Some(left_expr.return_type()), subquery)?;

if !self.context.is_step(&QueryBindStep::Where) {
return Err(DatabaseError::UnsupportedStmt(
Expand Down Expand Up @@ -250,14 +251,14 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T

fn bind_temp_table(
&mut self,
column: ColumnRef,
expr: ScalarExpression,
sub_query: LogicalPlan,
) -> Result<(ScalarExpression, LogicalPlan), DatabaseError> {
let mut alias_column = ColumnCatalog::clone(&column);
let mut alias_column = ColumnCatalog::clone(&expr.output_column());
alias_column.set_ref_table(self.context.temp_table(), ColumnId::new(), true);

let alias_expr = ScalarExpression::Alias {
expr: Box::new(ScalarExpression::ColumnRef(column)),
expr: Box::new(expr),
alias: AliasType::Expr(Box::new(ScalarExpression::ColumnRef(ColumnRef::from(
alias_column,
)))),
Expand All @@ -268,8 +269,9 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T

fn bind_subquery(
&mut self,
in_ty: Option<LogicalType>,
subquery: &Query,
) -> Result<(LogicalPlan, ColumnRef), DatabaseError> {
) -> Result<(LogicalPlan, ScalarExpression), DatabaseError> {
let BinderContext {
table_cache,
view_cache,
Expand All @@ -294,14 +296,30 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
let mut sub_query = binder.bind_query(subquery)?;
let sub_query_schema = sub_query.output_schema();

if sub_query_schema.len() != 1 {
return Err(DatabaseError::MisMatch(
"expects only one expression to be returned",
"the expression returned by the subquery",
));
}
let column = sub_query_schema[0].clone();
Ok((sub_query, column))
let fn_check = |len: usize| {
if sub_query_schema.len() != len {
return Err(DatabaseError::MisMatch(
"expects only one expression to be returned",
"the expression returned by the subquery",
));
}
Ok(())
};

let expr = if let Some(LogicalType::Tuple(tys)) = in_ty {
fn_check(tys.len())?;

let columns = sub_query_schema
.iter()
.map(|column| ScalarExpression::ColumnRef(column.clone()))
.collect::<Vec<_>>();
ScalarExpression::Tuple(columns)
} else {
fn_check(1)?;

ScalarExpression::ColumnRef(sub_query_schema[0].clone())
};
Ok((sub_query, expr))
}

pub fn bind_like(
Expand Down
6 changes: 5 additions & 1 deletion src/binder/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,12 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>

ConstantCalculator.visit(&mut expression)?;
match expression {
ScalarExpression::Constant(value) => {
ScalarExpression::Constant(mut value) => {
let ty = schema_ref[i].datatype();

if &value.logical_type() != ty {
value = value.cast(ty)?;
}
// Check if the value length is too long
value.check_len(ty)?;

Expand Down
8 changes: 5 additions & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ pub enum DatabaseError {
),
#[error("cache size overflow")]
CacheSizeOverFlow,
#[error("cast fail")]
CastFail,
#[error("cast fail: {from} -> {to}")]
CastFail { from: LogicalType, to: LogicalType },
#[error("channel close")]
ChannelClose,
#[error("columns empty")]
Expand Down Expand Up @@ -89,8 +89,10 @@ pub enum DatabaseError {
ParametersNotFound(String),
#[error("no transaction begin")]
NoTransactionBegin,
#[error("cannot be Null")]
#[error("cannot be null")]
NotNull,
#[error("over flow")]
OverFlow,
#[error("parser bool: {0}")]
ParseBool(
#[source]
Expand Down
2 changes: 1 addition & 1 deletion src/execution/dql/aggregate/avg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ impl Accumulator for AvgAccumulator {
value = value.cast(&quantity_ty)?
}
let evaluator = EvaluatorFactory::binary_create(quantity_ty, BinaryOperator::Divide)?;
Ok(evaluator.0.binary_eval(&value, &quantity))
evaluator.0.binary_eval(&value, &quantity)
}
}
2 changes: 1 addition & 1 deletion src/execution/dql/aggregate/min_max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Accumulator for MinMaxAccumulator {
if !value.is_null() {
if let Some(inner_value) = &self.inner {
let evaluator = EvaluatorFactory::binary_create(value.logical_type(), self.op)?;
if let DataValue::Boolean(result) = evaluator.0.binary_eval(inner_value, value) {
if let DataValue::Boolean(result) = evaluator.0.binary_eval(inner_value, value)? {
result
} else {
return Err(DatabaseError::InvalidType);
Expand Down
2 changes: 1 addition & 1 deletion src/execution/dql/aggregate/sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Accumulator for SumAccumulator {
if self.result.is_null() {
self.result = value.clone();
} else {
self.result = self.evaluator.0.binary_eval(&self.result, value);
self.result = self.evaluator.0.binary_eval(&self.result, value)?;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/expression/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ impl ScalarExpression {
let left = left_expr.eval(tuple)?;
let right = right_expr.eval(tuple)?;

Ok(evaluator
evaluator
.as_ref()
.ok_or(DatabaseError::EvaluatorNotFound)?
.0
.binary_eval(&left, &right))
.binary_eval(&left, &right)
}
ScalarExpression::IsNull { expr, negated } => {
let mut is_null = expr.eval(tuple)?.is_null();
Expand Down Expand Up @@ -340,7 +340,7 @@ impl ScalarExpression {
}
evaluator
.0
.binary_eval(operand_value, &when_value)
.binary_eval(operand_value, &when_value)?
.is_true()?
} else {
when_value.is_true()?
Expand Down
Loading
Loading