Skip to content

Commit 508e85a

Browse files
authoredOct 31, 2022
fix(type): add NULL type and fix type analysis (#721)
* fix type on operations Signed-off-by: Runji Wang <wangrunji0408@163.com> * add a NULL type Signed-off-by: Runji Wang <wangrunji0408@163.com>
1 parent 016f4b6 commit 508e85a

26 files changed

+173
-230
lines changed
 

‎src/array/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ macro_rules! impl_array_builder {
339339
pub fn with_capacity(capacity: usize, ty: &DataType) -> Self {
340340
use DataTypeKind::*;
341341
match ty.kind() {
342+
Null => Self::Int32(I32ArrayBuilder::with_capacity(capacity)),
342343
$(
343344
$Type => Self::$Abc(<$AbcArrayBuilder>::with_capacity(capacity)),
344345
)*

‎src/binder/expression/agg_call.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -99,18 +99,12 @@ impl Binder {
9999
if args.is_empty() {
100100
let first_index_column = BoundExpr::InputRef(BoundInputRef {
101101
index: 0,
102-
return_type: DataType::new(DataTypeKind::Int32, false),
102+
return_type: DataTypeKind::Int32.not_null(),
103103
});
104104
args.push(first_index_column);
105-
(
106-
AggKind::RowCount,
107-
Some(DataType::new(DataTypeKind::Int32, false)),
108-
)
105+
(AggKind::RowCount, DataTypeKind::Int32.not_null())
109106
} else {
110-
(
111-
AggKind::Count,
112-
Some(DataType::new(DataTypeKind::Int32, false)),
113-
)
107+
(AggKind::Count, DataTypeKind::Int32.not_null())
114108
}
115109
}
116110
"max" => (AggKind::Max, args[0].return_type()),
@@ -128,22 +122,22 @@ impl Binder {
128122
left_expr: Box::new(BoundExpr::AggCall(BoundAggCall {
129123
kind: AggKind::Sum,
130124
args: args.clone(),
131-
return_type: args[0].return_type().unwrap(),
125+
return_type: args[0].return_type(),
132126
})),
133127
right_expr: Box::new(BoundExpr::TypeCast(BoundTypeCast {
134-
ty: args[0].return_type().unwrap().kind(),
128+
ty: args[0].return_type().kind(),
135129
expr: Box::new(BoundExpr::AggCall(BoundAggCall {
136130
kind: AggKind::Count,
137131
args,
138-
return_type: DataType::new(DataTypeKind::Int32, false),
132+
return_type: DataTypeKind::Int32.not_null(),
139133
})),
140134
})),
141135
return_type,
142136
})),
143137
_ => Ok(BoundExpr::AggCall(BoundAggCall {
144138
kind,
145139
args,
146-
return_type: return_type.unwrap(),
140+
return_type,
147141
})),
148142
}
149143
}

‎src/binder/expression/binary_op.rs

+35-47
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub struct BoundBinaryOp {
1212
pub op: BinaryOperator,
1313
pub left_expr: Box<BoundExpr>,
1414
pub right_expr: Box<BoundExpr>,
15-
pub return_type: Option<DataType>,
15+
pub return_type: DataType,
1616
}
1717

1818
impl std::fmt::Debug for BoundBinaryOp {
@@ -45,60 +45,48 @@ impl Binder {
4545
let mut right_bound_expr = self.bind_expr(right)?;
4646

4747
// Implicit type cast
48-
let left_data_type_kind = match (
49-
left_bound_expr.return_type(),
50-
right_bound_expr.return_type(),
51-
) {
52-
(Some(left_data_type), Some(right_data_type)) => {
53-
let left_physical_kind = left_data_type.kind();
54-
let right_physical_kind = right_data_type.kind();
55-
let mut return_type_tmp = left_data_type.kind();
56-
// Check if implicit type conversion is needed
57-
if left_physical_kind != right_physical_kind {
58-
// Insert type cast expr
59-
match (left_physical_kind, right_physical_kind) {
60-
(Float64 | Decimal(_, _), Int32 | Int64)
61-
| (Int64, Int32)
62-
| (Date, String)
63-
| (Decimal(_, _), Float64) => {
64-
right_bound_expr = BoundExpr::TypeCast(BoundTypeCast {
65-
expr: Box::new(right_bound_expr),
66-
ty: left_data_type.kind(),
67-
});
68-
}
69-
(Int32 | Int64, Float64 | Decimal(_, _))
70-
| (Int32, Int64)
71-
| (String, Date)
72-
| (Float64, Decimal(_, _)) => {
73-
left_bound_expr = BoundExpr::TypeCast(BoundTypeCast {
74-
expr: Box::new(left_bound_expr),
75-
ty: right_data_type.kind(),
76-
});
77-
return_type_tmp = right_data_type.kind();
78-
}
79-
(Date, Interval) => {}
80-
(left_kind, right_kind) => todo!(
81-
"Support implicit conversion of {:?} and {:?}",
82-
left_kind,
83-
right_kind
84-
),
48+
let left_data_type_kind = {
49+
let left_kind = left_bound_expr.return_type().kind();
50+
let right_kind = right_bound_expr.return_type().kind();
51+
let mut return_type_tmp = left_kind;
52+
// Check if implicit type conversion is needed
53+
if left_kind != right_kind {
54+
// Insert type cast expr
55+
match (left_kind, right_kind) {
56+
(Float64 | Decimal(_, _), Int32 | Int64)
57+
| (Int64, Int32)
58+
| (Date, String)
59+
| (Decimal(_, _), Float64) => {
60+
right_bound_expr = BoundExpr::TypeCast(BoundTypeCast {
61+
expr: Box::new(right_bound_expr),
62+
ty: left_kind,
63+
});
8564
}
65+
(Int32 | Int64, Float64 | Decimal(_, _))
66+
| (Int32, Int64)
67+
| (String, Date)
68+
| (Float64, Decimal(_, _)) => {
69+
left_bound_expr = BoundExpr::TypeCast(BoundTypeCast {
70+
expr: Box::new(left_bound_expr),
71+
ty: right_kind,
72+
});
73+
return_type_tmp = right_kind;
74+
}
75+
(Date, Interval) => {}
76+
_ => todo!(
77+
"Support implicit conversion of {:?} and {:?}",
78+
left_kind,
79+
right_kind
80+
),
8681
}
87-
Some(return_type_tmp.nullable())
88-
}
89-
(None, None) => None,
90-
(left, right) => {
91-
return Err(BindError::BinaryOpTypeMismatch(
92-
format!("{:?}", left),
93-
format!("{:?}", right),
94-
))
9582
}
83+
return_type_tmp.nullable()
9684
};
9785

9886
let return_type = match op {
9987
Op::Plus | Op::Minus | Op::Multiply | Op::Divide | Op::Modulo => left_data_type_kind,
10088
Op::Gt | Op::GtEq | Op::Lt | Op::LtEq | Op::Eq | Op::NotEq | Op::And | Op::Or => {
101-
Some(DataTypeKind::Bool.nullable())
89+
DataTypeKind::Bool.nullable()
10290
}
10391
_ => todo!("Support more binary operators"),
10492
};

‎src/binder/expression/mod.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ pub enum BoundExpr {
4343
}
4444

4545
impl BoundExpr {
46-
pub fn return_type(&self) -> Option<DataType> {
46+
pub fn return_type(&self) -> DataType {
4747
match self {
4848
Self::Constant(v) => v.data_type(),
49-
Self::ColumnRef(expr) => Some(*expr.desc.datatype()),
49+
Self::ColumnRef(expr) => *expr.desc.datatype(),
5050
Self::BinaryOp(expr) => expr.return_type,
5151
Self::UnaryOp(expr) => expr.return_type,
52-
Self::TypeCast(expr) => Some(expr.ty.nullable()),
53-
Self::AggCall(expr) => Some(expr.return_type),
54-
Self::InputRef(expr) => Some(expr.return_type),
55-
Self::IsNull(_) => Some(DataTypeKind::Bool.not_null()),
52+
Self::TypeCast(expr) => expr.ty.nullable(),
53+
Self::AggCall(expr) => expr.return_type,
54+
Self::InputRef(expr) => expr.return_type,
55+
Self::IsNull(_) => DataTypeKind::Bool.not_null(),
5656
Self::ExprWithAlias(expr) => expr.expr.return_type(),
5757
Self::Alias(expr) => expr.expr.return_type(),
5858
}
@@ -207,7 +207,7 @@ impl Binder {
207207
Ok(BoundExpr::UnaryOp(BoundUnaryOp {
208208
op: UnaryOperator::Not,
209209
expr: Box::new(expr),
210-
return_type: Some(DataTypeKind::Bool.not_null()),
210+
return_type: DataTypeKind::Bool.not_null(),
211211
}))
212212
}
213213
Expr::TypedString { data_type, value } => self.bind_typed_string(data_type, value),
@@ -257,7 +257,7 @@ impl Binder {
257257
op: final_op,
258258
left_expr: Box::new(left_expr),
259259
right_expr: Box::new(right_expr),
260-
return_type: Some(DataType::new(DataTypeKind::Bool, false)),
260+
return_type: DataTypeKind::Bool.not_null(),
261261
}))
262262
}
263263
}
@@ -340,7 +340,7 @@ mod tests {
340340
let expr = BoundExpr::UnaryOp(BoundUnaryOp {
341341
op: UnaryOperator::Minus,
342342
expr: Box::new(expr),
343-
return_type: Some(data_type),
343+
return_type: data_type,
344344
});
345345
assert_eq!("-a", expr.format_name(&child_schema));
346346
}
@@ -361,7 +361,7 @@ mod tests {
361361
op: BinaryOperator::Plus,
362362
left_expr: Box::new(left_expr),
363363
right_expr: Box::new(right_expr),
364-
return_type: Some(DataType::new(DataTypeKind::Int32, true)),
364+
return_type: DataTypeKind::Int32.nullable(),
365365
});
366366
assert_eq!("a+1", expr.format_name(&child_schema));
367367
}
@@ -385,7 +385,7 @@ mod tests {
385385
op: BinaryOperator::Plus,
386386
left_expr: Box::new(left_expr),
387387
right_expr: Box::new(right_expr),
388-
return_type: Some(data_type),
388+
return_type: data_type,
389389
});
390390
assert_eq!("a+b", expr.format_name(&child_schema));
391391
}

‎src/binder/expression/unary_op.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::parser::UnaryOperator;
1010
pub struct BoundUnaryOp {
1111
pub op: UnaryOperator,
1212
pub expr: Box<BoundExpr>,
13-
pub return_type: Option<DataType>,
13+
pub return_type: DataType,
1414
}
1515

1616
impl Binder {

‎src/binder/statement/insert.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ impl Binder {
9898
// Bind expression
9999
let mut expr = self.bind_expr(expr)?;
100100

101-
if let Some(data_type) = &expr.return_type() {
101+
if !expr.return_type().kind().is_null() {
102102
// table t1(a float, b float)
103103
// for example: insert into values (1, 1);
104104
// 1 should be casted to float.
105-
let left_kind = data_type.kind();
105+
let left_kind = expr.return_type().kind();
106106
let right_kind = column_types[idx].kind();
107107
if left_kind != right_kind {
108108
expr = BoundExpr::TypeCast(BoundTypeCast {
@@ -143,11 +143,11 @@ impl Binder {
143143
) -> Result<BoundInsert, BindError> {
144144
let mut bound_select_stmt = self.bind_select(select_stmt)?;
145145
for (idx, expr) in bound_select_stmt.select_list.iter_mut().enumerate() {
146-
if let Some(data_type) = &expr.return_type() {
146+
if !expr.return_type().kind().is_null() {
147147
// table t1(a float, b float)
148148
// for example: insert into values (1, 1);
149149
// 1 should be casted to float.
150-
let left_kind = data_type.kind();
150+
let left_kind = expr.return_type().kind();
151151
let right_kind = column_types[idx].kind();
152152
if left_kind != right_kind {
153153
*expr = BoundExpr::TypeCast(BoundTypeCast {

‎src/executor/evaluator.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ impl BoundExpr {
2424
array.unary_op(&op.op)
2525
}
2626
BoundExpr::Constant(v) => {
27-
let mut builder = ArrayBuilderImpl::with_capacity(
28-
chunk.cardinality(),
29-
&self
30-
.return_type()
31-
.unwrap_or_else(|| DataTypeKind::Int32.nullable()),
32-
);
27+
let mut builder =
28+
ArrayBuilderImpl::with_capacity(chunk.cardinality(), &self.return_type());
3329
// TODO: optimize this
3430
for _ in 0..chunk.cardinality() {
3531
builder.push(v);
@@ -78,8 +74,7 @@ impl BoundExpr {
7874
array.unary_op(&op.op)
7975
}
8076
BoundExpr::Constant(v) => {
81-
let mut builder =
82-
ArrayBuilderImpl::with_capacity(cardinality, &self.return_type().unwrap());
77+
let mut builder = ArrayBuilderImpl::with_capacity(cardinality, &self.return_type());
8378
// TODO: optimize this
8479
for _ in 0..cardinality {
8580
builder.push(v);

‎src/executor/hash_agg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl HashAggExecutor {
7171
while let Some(batch) = batches.next() {
7272
let mut key_builders = group_keys
7373
.iter()
74-
.map(|e| ArrayBuilderImpl::new(&e.return_type().unwrap()))
74+
.map(|e| ArrayBuilderImpl::new(&e.return_type()))
7575
.collect::<Vec<ArrayBuilderImpl>>();
7676
let mut res_builders = agg_calls
7777
.iter()

‎src/executor/perfect_hash_agg.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl PerfectHashAggExecutor {
102102
) -> DataChunk {
103103
let mut key_builders = group_keys
104104
.iter()
105-
.map(|e| ArrayBuilderImpl::new(&e.return_type().unwrap()))
105+
.map(|e| ArrayBuilderImpl::new(&e.return_type()))
106106
.collect::<Vec<ArrayBuilderImpl>>();
107107
let mut res_builders = agg_calls
108108
.iter()
@@ -113,7 +113,7 @@ impl PerfectHashAggExecutor {
113113
need_shift_bits_num -= bits[idx];
114114
let mask = (1usize << bits[idx]) - 1;
115115
let key_builder = &mut key_builders[idx];
116-
match group_keys[idx].return_type().unwrap().kind {
116+
match group_keys[idx].return_type().kind {
117117
DataTypeKind::Bool => locations.iter().for_each(|location| {
118118
let value = (location >> need_shift_bits_num) & mask;
119119
if value == 0 {

‎src/executor/simple_agg.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use smallvec::SmallVec;
66
use super::*;
77
use crate::array::{ArrayBuilderImpl, ArrayImpl};
88
use crate::binder::{AggKind, BoundAggCall};
9-
use crate::types::{DataTypeKind, DataValue};
9+
use crate::types::DataValue;
1010

1111
/// The executor of simple aggregation.
1212
pub struct SimpleAggExecutor {
@@ -38,18 +38,9 @@ impl SimpleAggExecutor {
3838
.iter()
3939
.map(|s| {
4040
let result = &s.output();
41-
match &result.data_type() {
42-
Some(r) => {
43-
let mut builder = ArrayBuilderImpl::with_capacity(1, r);
44-
builder.push(result);
45-
builder.finish()
46-
}
47-
None => {
48-
let mut builder = ArrayBuilderImpl::new(&DataTypeKind::Int32.nullable());
49-
builder.push(result);
50-
builder.finish()
51-
}
52-
}
41+
let mut builder = ArrayBuilderImpl::with_capacity(1, &result.data_type());
42+
builder.push(result);
43+
builder.finish()
5344
})
5445
.collect::<DataChunk>()
5546
}

‎src/executor/sort_agg.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use smallvec::SmallVec;
55
use super::*;
66
use crate::array::{ArrayBuilderImpl, ArrayImpl};
77
use crate::binder::BoundAggCall;
8-
use crate::types::DataTypeKind;
98

109
pub struct SortAggExecutor {
1110
pub agg_calls: Vec<BoundAggCall>,
@@ -64,14 +63,9 @@ impl SortAggExecutor {
6463
.iter()
6564
.map(|s| {
6665
let result = &s.output();
67-
match &result.data_type() {
68-
Some(r) => {
69-
let mut builder = ArrayBuilderImpl::with_capacity(1, r);
70-
builder.push(result);
71-
builder.finish()
72-
}
73-
None => ArrayBuilderImpl::new(&DataTypeKind::Int32.nullable()).finish(),
74-
}
66+
let mut builder = ArrayBuilderImpl::with_capacity(1, &result.data_type());
67+
builder.push(result);
68+
builder.finish()
7569
})
7670
.collect::<DataChunk>();
7771
}

0 commit comments

Comments
 (0)
Please sign in to comment.