1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::convert::TryFrom;
use tidb_query_datatype::builder::FieldTypeBuilder;
use tidb_query_datatype::{EvalType, FieldTypeAccessor, FieldTypeTp};
use tipb::{Expr, FieldType};
use tidb_query_common::Result;
use tidb_query_expr::impl_cast::get_cast_fn_rpn_node;
use tidb_query_expr::{RpnExpression, RpnExpressionBuilder};
pub fn check_aggr_exp_supported_one_child(aggr_def: &Expr) -> Result<()> {
if aggr_def.get_children().len() != 1 {
return Err(other_err!(
"Expect 1 parameter, but got {}",
aggr_def.get_children().len()
));
}
let child = &aggr_def.get_children()[0];
RpnExpressionBuilder::check_expr_tree_supported(child)?;
Ok(())
}
pub fn rewrite_exp_for_sum_avg(schema: &[FieldType], exp: &mut RpnExpression) -> Result<()> {
let ret_field_type = exp.ret_field_type(schema);
let ret_eval_type = box_try!(EvalType::try_from(ret_field_type.as_accessor().tp()));
let new_ret_field_type = match ret_eval_type {
EvalType::Decimal | EvalType::Real => {
return Ok(());
}
EvalType::Int => FieldTypeBuilder::new()
.tp(FieldTypeTp::NewDecimal)
.flen(tidb_query_datatype::MAX_DECIMAL_WIDTH)
.build(),
_ => FieldTypeBuilder::new()
.tp(FieldTypeTp::Double)
.flen(tidb_query_datatype::MAX_REAL_WIDTH)
.decimal(tidb_query_datatype::UNSPECIFIED_LENGTH)
.build(),
};
let node = get_cast_fn_rpn_node(exp.is_last_constant(), ret_field_type, new_ret_field_type)?;
exp.push(node);
Ok(())
}
pub fn rewrite_exp_for_bit_op(schema: &[FieldType], exp: &mut RpnExpression) -> Result<()> {
let ret_field_type = exp.ret_field_type(schema);
let ret_eval_type = box_try!(EvalType::try_from(ret_field_type.as_accessor().tp()));
let new_ret_field_type = match ret_eval_type {
EvalType::Int => {
return Ok(());
}
_ => FieldTypeBuilder::new().tp(FieldTypeTp::LongLong).build(),
};
let node = get_cast_fn_rpn_node(exp.is_last_constant(), ret_field_type, new_ret_field_type)?;
exp.push(node);
Ok(())
}