|
1 | 1 | use crate::binder::BindError; |
2 | 2 | use anyhow::Result; |
3 | 3 | use itertools::Itertools; |
4 | | -use sqlparser::ast::{Expr, Ident}; |
| 4 | +use sqlparser::ast::{BinaryOperator, Expr, Function, FunctionArg, FunctionArgExpr, Ident}; |
5 | 5 | use std::slice; |
| 6 | +use crate::expression::agg::AggKind; |
6 | 7 |
|
7 | 8 | use super::Binder; |
8 | 9 | use crate::expression::ScalarExpression; |
| 10 | +use crate::types::LogicalType; |
9 | 11 |
|
10 | 12 | impl Binder { |
11 | 13 | pub(crate) fn bind_expr(&mut self, expr: &Expr) -> Result<ScalarExpression> { |
12 | 14 | match expr { |
13 | 15 | Expr::Identifier(ident) => { |
14 | 16 | self.bind_column_ref_from_identifiers(slice::from_ref(ident)) |
15 | 17 | } |
| 18 | + Expr::CompoundIdentifier(idents) => { |
| 19 | + self.bind_column_ref_from_identifiers(idents) |
| 20 | + } |
| 21 | + Expr::BinaryOp { left, right, op} => { |
| 22 | + self.bind_binary_op_internal(left, right, op) |
| 23 | + } |
| 24 | + Expr::Value(v) => Ok(ScalarExpression::Constant(v.into())), |
| 25 | + Expr::Function(func) => self.bind_agg_call(func), |
| 26 | + Expr::Nested(expr) => self.bind_expr(expr), |
16 | 27 | _ => { |
17 | 28 | todo!() |
18 | 29 | } |
@@ -75,4 +86,71 @@ impl Binder { |
75 | 86 | Ok(ScalarExpression::ColumnRef(column_catalog.clone())) |
76 | 87 | } |
77 | 88 | } |
| 89 | + |
| 90 | + fn bind_binary_op_internal( |
| 91 | + &mut self, |
| 92 | + left: &Expr, |
| 93 | + right: &Expr, |
| 94 | + op: &BinaryOperator, |
| 95 | + ) -> Result<ScalarExpression> { |
| 96 | + let left_expr = Box::new(self.bind_expr(left)?); |
| 97 | + let right_expr = Box::new(self.bind_expr(right)?); |
| 98 | + let ty = LogicalType::max_logical_type( |
| 99 | + &left_expr.return_type(), |
| 100 | + &right_expr.return_type() |
| 101 | + )?; |
| 102 | + |
| 103 | + Ok(ScalarExpression::Binary { |
| 104 | + op: (op.clone()).into(), |
| 105 | + left_expr, |
| 106 | + right_expr, |
| 107 | + ty, |
| 108 | + }) |
| 109 | + } |
| 110 | + |
| 111 | + fn bind_agg_call(&mut self, func: &Function) -> Result<ScalarExpression> { |
| 112 | + let args: Vec<ScalarExpression> = func.args |
| 113 | + .iter() |
| 114 | + .map(|arg| { |
| 115 | + let arg_expr = match arg { |
| 116 | + FunctionArg::Named { arg, .. } => arg, |
| 117 | + FunctionArg::Unnamed(arg) => arg, |
| 118 | + }; |
| 119 | + match arg_expr { |
| 120 | + FunctionArgExpr::Expr(expr) => self.bind_expr(expr), |
| 121 | + _ => todo!() |
| 122 | + } |
| 123 | + }) |
| 124 | + .try_collect()?; |
| 125 | + let ty = args[0].return_type(); |
| 126 | + |
| 127 | + Ok(match func.name.to_string().to_lowercase().as_str() { |
| 128 | + "count" => ScalarExpression::AggCall{ |
| 129 | + kind: AggKind::Count, |
| 130 | + args, |
| 131 | + ty: LogicalType::UInteger, |
| 132 | + }, |
| 133 | + "sum" => ScalarExpression::AggCall{ |
| 134 | + kind: AggKind::Sum, |
| 135 | + args, |
| 136 | + ty, |
| 137 | + }, |
| 138 | + "min" => ScalarExpression::AggCall{ |
| 139 | + kind: AggKind::Min, |
| 140 | + args, |
| 141 | + ty, |
| 142 | + }, |
| 143 | + "max" => ScalarExpression::AggCall{ |
| 144 | + kind: AggKind::Max, |
| 145 | + args, |
| 146 | + ty, |
| 147 | + }, |
| 148 | + "avg" => ScalarExpression::AggCall{ |
| 149 | + kind: AggKind::Avg, |
| 150 | + args, |
| 151 | + ty, |
| 152 | + }, |
| 153 | + _ => todo!(), |
| 154 | + }) |
| 155 | + } |
78 | 156 | } |
0 commit comments