Skip to content

refactor: Old Planner Never See Again (Part X) #7593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-legacy-planners = { path = "../legacy-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_legacy_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