Skip to content

Commit b626555

Browse files
authored
test: add e2e test crdb/where.slt (#272)
* test: add e2e test `crdb/where.slt` * chore: codefmt * chore: codefmt
1 parent 2d46b69 commit b626555

File tree

36 files changed

+1061
-654
lines changed

36 files changed

+1061
-654
lines changed

src/binder/expr.rs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,22 +143,22 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
143143
})
144144
}
145145
Expr::Exists { subquery, negated } => {
146-
let (sub_query, column) = self.bind_subquery(subquery)?;
146+
let (sub_query, column) = self.bind_subquery(None, subquery)?;
147147
let (_, sub_query) = if !self.context.is_step(&QueryBindStep::Where) {
148148
self.bind_temp_table(column, sub_query)?
149149
} else {
150-
(ScalarExpression::ColumnRef(column), sub_query)
150+
(column, sub_query)
151151
};
152152
self.context
153153
.sub_query(SubQueryType::ExistsSubQuery(*negated, sub_query));
154154
Ok(ScalarExpression::Constant(DataValue::Boolean(true)))
155155
}
156156
Expr::Subquery(subquery) => {
157-
let (sub_query, column) = self.bind_subquery(subquery)?;
157+
let (sub_query, column) = self.bind_subquery(None, subquery)?;
158158
let (expr, sub_query) = if !self.context.is_step(&QueryBindStep::Where) {
159159
self.bind_temp_table(column, sub_query)?
160160
} else {
161-
(ScalarExpression::ColumnRef(column), sub_query)
161+
(column, sub_query)
162162
};
163163
self.context.sub_query(SubQueryType::SubQuery(sub_query));
164164
Ok(expr)
@@ -169,7 +169,8 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
169169
negated,
170170
} => {
171171
let left_expr = Box::new(self.bind_expr(expr)?);
172-
let (sub_query, column) = self.bind_subquery(subquery)?;
172+
let (sub_query, column) =
173+
self.bind_subquery(Some(left_expr.return_type()), subquery)?;
173174

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

251252
fn bind_temp_table(
252253
&mut self,
253-
column: ColumnRef,
254+
expr: ScalarExpression,
254255
sub_query: LogicalPlan,
255256
) -> Result<(ScalarExpression, LogicalPlan), DatabaseError> {
256-
let mut alias_column = ColumnCatalog::clone(&column);
257+
let mut alias_column = ColumnCatalog::clone(&expr.output_column());
257258
alias_column.set_ref_table(self.context.temp_table(), ColumnId::new(), true);
258259

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

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

297-
if sub_query_schema.len() != 1 {
298-
return Err(DatabaseError::MisMatch(
299-
"expects only one expression to be returned",
300-
"the expression returned by the subquery",
301-
));
302-
}
303-
let column = sub_query_schema[0].clone();
304-
Ok((sub_query, column))
299+
let fn_check = |len: usize| {
300+
if sub_query_schema.len() != len {
301+
return Err(DatabaseError::MisMatch(
302+
"expects only one expression to be returned",
303+
"the expression returned by the subquery",
304+
));
305+
}
306+
Ok(())
307+
};
308+
309+
let expr = if let Some(LogicalType::Tuple(tys)) = in_ty {
310+
fn_check(tys.len())?;
311+
312+
let columns = sub_query_schema
313+
.iter()
314+
.map(|column| ScalarExpression::ColumnRef(column.clone()))
315+
.collect::<Vec<_>>();
316+
ScalarExpression::Tuple(columns)
317+
} else {
318+
fn_check(1)?;
319+
320+
ScalarExpression::ColumnRef(sub_query_schema[0].clone())
321+
};
322+
Ok((sub_query, expr))
305323
}
306324

307325
pub fn bind_like(

src/binder/insert.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,12 @@ impl<T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'_, '_, T, A>
7474

7575
ConstantCalculator.visit(&mut expression)?;
7676
match expression {
77-
ScalarExpression::Constant(value) => {
77+
ScalarExpression::Constant(mut value) => {
7878
let ty = schema_ref[i].datatype();
79+
80+
if &value.logical_type() != ty {
81+
value = value.cast(ty)?;
82+
}
7983
// Check if the value length is too long
8084
value.check_len(ty)?;
8185

src/errors.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub enum DatabaseError {
1919
),
2020
#[error("cache size overflow")]
2121
CacheSizeOverFlow,
22-
#[error("cast fail")]
23-
CastFail,
22+
#[error("cast fail: {from} -> {to}")]
23+
CastFail { from: LogicalType, to: LogicalType },
2424
#[error("channel close")]
2525
ChannelClose,
2626
#[error("columns empty")]
@@ -89,8 +89,10 @@ pub enum DatabaseError {
8989
ParametersNotFound(String),
9090
#[error("no transaction begin")]
9191
NoTransactionBegin,
92-
#[error("cannot be Null")]
92+
#[error("cannot be null")]
9393
NotNull,
94+
#[error("over flow")]
95+
OverFlow,
9496
#[error("parser bool: {0}")]
9597
ParseBool(
9698
#[source]

src/execution/dql/aggregate/avg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ impl Accumulator for AvgAccumulator {
5656
value = value.cast(&quantity_ty)?
5757
}
5858
let evaluator = EvaluatorFactory::binary_create(quantity_ty, BinaryOperator::Divide)?;
59-
Ok(evaluator.0.binary_eval(&value, &quantity))
59+
evaluator.0.binary_eval(&value, &quantity)
6060
}
6161
}

src/execution/dql/aggregate/min_max.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Accumulator for MinMaxAccumulator {
2626
if !value.is_null() {
2727
if let Some(inner_value) = &self.inner {
2828
let evaluator = EvaluatorFactory::binary_create(value.logical_type(), self.op)?;
29-
if let DataValue::Boolean(result) = evaluator.0.binary_eval(inner_value, value) {
29+
if let DataValue::Boolean(result) = evaluator.0.binary_eval(inner_value, value)? {
3030
result
3131
} else {
3232
return Err(DatabaseError::InvalidType);

src/execution/dql/aggregate/sum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl Accumulator for SumAccumulator {
2929
if self.result.is_null() {
3030
self.result = value.clone();
3131
} else {
32-
self.result = self.evaluator.0.binary_eval(&self.result, value);
32+
self.result = self.evaluator.0.binary_eval(&self.result, value)?;
3333
}
3434
}
3535

src/expression/evaluator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ impl ScalarExpression {
7676
let left = left_expr.eval(tuple)?;
7777
let right = right_expr.eval(tuple)?;
7878

79-
Ok(evaluator
79+
evaluator
8080
.as_ref()
8181
.ok_or(DatabaseError::EvaluatorNotFound)?
8282
.0
83-
.binary_eval(&left, &right))
83+
.binary_eval(&left, &right)
8484
}
8585
ScalarExpression::IsNull { expr, negated } => {
8686
let mut is_null = expr.eval(tuple)?.is_null();
@@ -340,7 +340,7 @@ impl ScalarExpression {
340340
}
341341
evaluator
342342
.0
343-
.binary_eval(operand_value, &when_value)
343+
.binary_eval(operand_value, &when_value)?
344344
.is_true()?
345345
} else {
346346
when_value.is_true()?

0 commit comments

Comments
 (0)