Skip to content
Closed
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/query/legacy-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ doctest = false
test = false

[dependencies]
common-ast = { path = "../ast" }
common-datavalues = { path = "../datavalues" }
common-exception = { path = "../../common/exception" }
common-functions = { path = "../functions" }
common-planners = { path = "../planners" }

async-trait = "0.1.56"
Expand Down
308 changes: 0 additions & 308 deletions src/query/legacy-parser/src/analyzer/analyzer_expr_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@

use async_trait::async_trait;
use common_datavalues::prelude::*;
use common_datavalues::type_coercion::merge_types;
use common_exception::ErrorCode;
use common_exception::Result;
use common_functions::aggregates::AggregateFunctionFactory;
use common_planners::Expression;
use sqlparser::ast::BinaryOperator;
use sqlparser::ast::DataType as AstDataType;
use sqlparser::ast::DateTimeField;
Expand All @@ -33,312 +30,7 @@ use sqlparser::ast::UnaryOperator;
use sqlparser::ast::Value;
use sqlparser::ast::WindowSpec;

use crate::analyzer_value_expr::ValueExprAnalyzer;
use crate::sql_common::SQLCommon;
use crate::sql_dialect::SQLDialect;

#[derive(Clone)]
pub struct ExpressionSyncAnalyzer {}

impl ExpressionSyncAnalyzer {
pub fn create() -> ExpressionSyncAnalyzer {
ExpressionSyncAnalyzer {}
}

pub fn analyze(&self, expr: &Expr) -> Result<Expression> {
let mut stack = Vec::new();

// Build RPN for expr. Because async function unsupported recursion
for rpn_item in &ExprRPNBuilder::build(expr)? {
match rpn_item {
ExprRPNItem::Value(v) => Self::analyze_value(v, &mut stack, SQLDialect::MySQL)?,
ExprRPNItem::Identifier(v) => self.analyze_identifier(v, &mut stack)?,
ExprRPNItem::QualifiedIdentifier(v) => self.analyze_identifiers(v, &mut stack)?,
ExprRPNItem::Function(v) => self.analyze_function(v, &mut stack)?,
ExprRPNItem::Cast(v, pg_style) => self.analyze_cast(v, *pg_style, &mut stack)?,
ExprRPNItem::Between(negated) => self.analyze_between(*negated, &mut stack)?,
ExprRPNItem::InList(v) => self.analyze_inlist(v, &mut stack)?,
ExprRPNItem::MapAccess(v) => self.analyze_map_access(v, &mut stack)?,
ExprRPNItem::Array(v) => self.analyze_array(*v, &mut stack)?,

_ => {
return Err(ErrorCode::LogicalError(format!(
"Logical error: can't analyze {:?} in sync mode, it's a bug",
expr
)));
}
}
}

match stack.len() {
1 => Ok(stack.remove(0)),
_ => Err(ErrorCode::LogicalError(
"Logical error: this is expr rpn bug.",
)),
}
}

pub fn analyze_function_arg(&self, arg_expr: &FunctionArgExpr) -> Result<Expression> {
match arg_expr {
FunctionArgExpr::Expr(expr) => self.analyze(expr),
FunctionArgExpr::Wildcard => Ok(Expression::Wildcard),
FunctionArgExpr::QualifiedWildcard(_) => Err(ErrorCode::SyntaxException(std::format!(
"Unsupported arg statement: {}",
arg_expr
))),
}
}

fn analyze_value(
value: &Value,
args: &mut Vec<Expression>,
typ: impl Into<SQLDialect>,
) -> Result<()> {
args.push(ValueExprAnalyzer::analyze(value, typ)?);
Ok(())
}

fn analyze_inlist(&self, info: &InListInfo, args: &mut Vec<Expression>) -> Result<()> {
let mut list = Vec::with_capacity(info.list_size);
for _ in 0..info.list_size {
match args.pop() {
None => {
return Err(ErrorCode::LogicalError("It's a bug."));
}
Some(arg) => {
list.insert(0, arg);
}
}
}

let expr = args
.pop()
.ok_or_else(|| ErrorCode::LogicalError("It's a bug."))?;
list.insert(0, expr);

let op = if info.negated {
"NOT_IN".to_string()
} else {
"IN".to_string()
};

args.push(Expression::ScalarFunction { op, args: list });
Ok(())
}

fn analyze_function(&self, info: &FunctionExprInfo, args: &mut Vec<Expression>) -> Result<()> {
let mut arguments = Vec::with_capacity(info.args_count);
for _ in 0..info.args_count {
match args.pop() {
None => {
return Err(ErrorCode::LogicalError("It's a bug."));
}
Some(arg) => {
arguments.insert(0, arg);
}
}
}

args.push(
match AggregateFunctionFactory::instance().check(&info.name) {
true => {
return Err(ErrorCode::LogicalError(
"Unsupport aggregate function, it's a bug.",
));
}
false => match info.kind {
OperatorKind::Unary => Self::unary_function(info, &arguments),
OperatorKind::Binary => Self::binary_function(info, &arguments),
OperatorKind::Other => Self::other_function(info, &arguments),
},
}?,
);
Ok(())
}

fn other_function(info: &FunctionExprInfo, args: &[Expression]) -> Result<Expression> {
let op = info.name.clone();
let arguments = args.to_owned();
Ok(Expression::ScalarFunction {
op,
args: arguments,
})
}

fn unary_function(info: &FunctionExprInfo, args: &[Expression]) -> Result<Expression> {
match args.is_empty() {
true => Err(ErrorCode::LogicalError("Unary operator must be one child.")),
false => Ok(Expression::UnaryExpression {
op: info.name.clone(),
expr: Box::new(args[0].to_owned()),
}),
}
}

fn binary_function(info: &FunctionExprInfo, args: &[Expression]) -> Result<Expression> {
let op = info.name.clone();
match args.len() < 2 {
true => Err(ErrorCode::LogicalError(
"Binary operator must be two children.",
)),
false => Ok(Expression::BinaryExpression {
op,
left: Box::new(args[0].to_owned()),
right: Box::new(args[1].to_owned()),
}),
}
}

fn analyze_identifier(&self, ident: &Ident, arguments: &mut Vec<Expression>) -> Result<()> {
let column_name = ident.clone().value;
arguments.push(Expression::Column(column_name));
Ok(())
}

fn analyze_identifiers(&self, idents: &[Ident], arguments: &mut Vec<Expression>) -> Result<()> {
let mut names = Vec::with_capacity(idents.len());

for ident in idents {
names.push(ident.clone().value);
}

arguments.push(Expression::QualifiedColumn(names));
Ok(())
}

fn analyze_cast(
&self,
data_type: &DataTypeImpl,
pg_style: bool,
args: &mut Vec<Expression>,
) -> Result<()> {
match args.pop() {
None => Err(ErrorCode::LogicalError(
"Cast operator must be one children.",
)),
Some(inner_expr) => {
args.push(Expression::Cast {
expr: Box::new(inner_expr),
data_type: data_type.clone(),
pg_style,
});
Ok(())
}
}
}

fn analyze_between(&self, negated: bool, args: &mut Vec<Expression>) -> Result<()> {
if args.len() < 3 {
return Err(ErrorCode::SyntaxException(
"Between must be a ternary expression.",
));
}

let s_args = args.split_off(args.len() - 3);
let expression = s_args[0].clone();
let low_expression = s_args[1].clone();
let high_expression = s_args[2].clone();

match negated {
false => args.push(
expression
.gt_eq(low_expression)
.and(expression.lt_eq(high_expression)),
),
true => args.push(
expression
.lt(low_expression)
.or(expression.gt(high_expression)),
),
};

Ok(())
}

fn analyze_map_access(&self, keys: &[Value], args: &mut Vec<Expression>) -> Result<()> {
match args.pop() {
None => Err(ErrorCode::LogicalError(
"MapAccess operator must be one children.",
)),
Some(inner_expr) => {
let path_name: String = keys
.iter()
.enumerate()
.map(|(i, k)| match k {
k @ Value::Number(_, _) => format!("[{}]", k),
Value::SingleQuotedString(s) => format!("[\"{}\"]", s),
Value::ColonString(s) => {
if i == 0 {
s.to_string()
} else {
format!(":{}", s)
}
}
Value::PeriodString(s) => format!(".{}", s),
_ => format!("[{}]", k),
})
.collect();

let name = match keys[0] {
Value::ColonString(_) => format!("{}:{}", inner_expr.column_name(), path_name),
_ => format!("{}{}", inner_expr.column_name(), path_name),
};
let path =
Expression::create_literal(DataValue::String(path_name.as_bytes().to_vec()));
let arguments = vec![inner_expr, path];

args.push(Expression::MapAccess {
name,
args: arguments,
});
Ok(())
}
}
}

fn analyze_array(&self, nums: usize, args: &mut Vec<Expression>) -> Result<()> {
let mut values = Vec::with_capacity(nums);
let mut types = Vec::with_capacity(nums);
for _ in 0..nums {
match args.pop() {
None => {
break;
}
Some(inner_expr) => {
if let Expression::Literal {
value, data_type, ..
} = inner_expr
{
values.push(value);
types.push(data_type);
}
}
};
}
if values.len() != nums {
return Err(ErrorCode::LogicalError(format!(
"Array must have {} children.",
nums
)));
}
let inner_type = if types.is_empty() {
NullType::new_impl()
} else {
types
.iter()
.fold(Ok(types[0].clone()), |acc, v| merge_types(&acc?, v))
.map_err(|e| ErrorCode::LogicalError(e.message()))?
};
values.reverse();

let array_value = Expression::create_literal_with_type(
DataValue::Array(values),
ArrayType::new_impl(inner_type),
);
args.push(array_value);
Ok(())
}
}

pub enum OperatorKind {
Unary,
Expand Down
Loading