Skip to content

Commit

Permalink
refactor(ast): eliminate clone when displaying expr (#15773)
Browse files Browse the repository at this point in the history
* refactor(ast): eliminate clone when displaying expr

* fix

* refactor(query): fix clippy

---------

Co-authored-by: andylokandy <[email protected]>
  • Loading branch information
zhang2014 and andylokandy authored Jun 12, 2024
1 parent 498a7f6 commit 0b87c30
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 176 deletions.
5 changes: 0 additions & 5 deletions src/query/ast/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use crate::ast::quote::QuotedString;
use crate::ast::write_comma_separated_list;
use crate::ast::Identifier;
use crate::ast::Query;
use crate::parser::expr::ExprElement;
use crate::span::merge_span;
use crate::ParseError;
use crate::Result;
Expand Down Expand Up @@ -414,10 +413,6 @@ impl Expr {
"DATE_TRUNC",
]
}

fn affix(&self) -> Affix {
ExprElement::from(self.clone()).affix()
}
}

impl Display for Expr {
Expand Down
305 changes: 134 additions & 171 deletions src/query/ast/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ use crate::parser::Error;
use crate::parser::ErrorKind;
use crate::rule;

pub const BETWEEN_PREC: u32 = 20;
pub const NOT_PREC: u32 = 15;

pub fn expr(i: Input) -> IResult<Expr> {
context("expression", subexpr(0))(i)
}
Expand Down Expand Up @@ -311,182 +308,148 @@ pub enum ExprElement {
},
}

pub const BETWEEN_PREC: u32 = 20;
pub const NOT_PREC: u32 = 15;
const CHAIN_FUNCTION_AFFIX: Affix = Affix::Postfix(Precedence(61));
const DOT_ACCESS_AFFIX: Affix = Affix::Postfix(Precedence(60));
const MAP_ACCESS_AFFIX: Affix = Affix::Postfix(Precedence(60));
const IS_NULL_AFFIX: Affix = Affix::Postfix(Precedence(17));
const BETWEEN_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
const IS_DISTINCT_FROM_AFFIX: Affix = Affix::Infix(Precedence(BETWEEN_PREC), Associativity::Left);
const IN_LIST_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
const IN_SUBQUERY_AFFIX: Affix = Affix::Postfix(Precedence(BETWEEN_PREC));
const JSON_OP_AFFIX: Affix = Affix::Infix(Precedence(40), Associativity::Left);
const PG_CAST_AFFIX: Affix = Affix::Postfix(Precedence(60));

const fn unary_affix(op: &UnaryOperator) -> Affix {
match op {
UnaryOperator::Not => Affix::Prefix(Precedence(NOT_PREC)),
UnaryOperator::Plus => Affix::Prefix(Precedence(50)),
UnaryOperator::Minus => Affix::Prefix(Precedence(50)),
UnaryOperator::BitwiseNot => Affix::Prefix(Precedence(50)),
UnaryOperator::SquareRoot => Affix::Prefix(Precedence(60)),
UnaryOperator::CubeRoot => Affix::Prefix(Precedence(60)),
UnaryOperator::Abs => Affix::Prefix(Precedence(60)),
UnaryOperator::Factorial => Affix::Postfix(Precedence(60)),
}
}

const fn binary_affix(op: &BinaryOperator) -> Affix {
match op {
BinaryOperator::Or => Affix::Infix(Precedence(5), Associativity::Left),
BinaryOperator::And => Affix::Infix(Precedence(10), Associativity::Left),
BinaryOperator::Eq => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotEq => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Gt => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Lt => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Gte => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Lte => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Like => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Regexp => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotRegexp => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::RLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotRLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::SoundsLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::BitwiseOr => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::BitwiseAnd => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::BitwiseXor => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::L2Distance => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::BitwiseShiftLeft => Affix::Infix(Precedence(23), Associativity::Left),
BinaryOperator::BitwiseShiftRight => Affix::Infix(Precedence(23), Associativity::Left),
BinaryOperator::Xor => Affix::Infix(Precedence(24), Associativity::Left),
BinaryOperator::Plus => Affix::Infix(Precedence(30), Associativity::Left),
BinaryOperator::Minus => Affix::Infix(Precedence(30), Associativity::Left),
BinaryOperator::Multiply => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Div => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Divide => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::IntDiv => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Modulo => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::StringConcat => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Caret => Affix::Infix(Precedence(40), Associativity::Right),
}
}

impl ExprElement {
pub fn affix(&self) -> Affix {
match &self {
ExprElement::ChainFunctionCall { .. } => Affix::Postfix(Precedence(61)),
ExprElement::DotAccess { .. } => Affix::Postfix(Precedence(60)),
ExprElement::MapAccess { .. } => Affix::Postfix(Precedence(60)),
ExprElement::IsNull { .. } => Affix::Postfix(Precedence(17)),
ExprElement::Between { .. } => Affix::Postfix(Precedence(BETWEEN_PREC)),
ExprElement::IsDistinctFrom { .. } => {
Affix::Infix(Precedence(BETWEEN_PREC), Associativity::Left)
}
ExprElement::InList { .. } => Affix::Postfix(Precedence(BETWEEN_PREC)),
ExprElement::InSubquery { .. } => Affix::Postfix(Precedence(BETWEEN_PREC)),
ExprElement::UnaryOp { op } => match op {
UnaryOperator::Not => Affix::Prefix(Precedence(NOT_PREC)),

UnaryOperator::Plus => Affix::Prefix(Precedence(50)),
UnaryOperator::Minus => Affix::Prefix(Precedence(50)),
UnaryOperator::BitwiseNot => Affix::Prefix(Precedence(50)),
UnaryOperator::SquareRoot => Affix::Prefix(Precedence(60)),
UnaryOperator::CubeRoot => Affix::Prefix(Precedence(60)),
UnaryOperator::Abs => Affix::Prefix(Precedence(60)),
UnaryOperator::Factorial => Affix::Postfix(Precedence(60)),
},
ExprElement::BinaryOp { op } => match op {
BinaryOperator::Or => Affix::Infix(Precedence(5), Associativity::Left),

BinaryOperator::And => Affix::Infix(Precedence(10), Associativity::Left),

BinaryOperator::Eq => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotEq => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Gt => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Lt => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Gte => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Lte => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Like => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::Regexp => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotRegexp => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::RLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::NotRLike => Affix::Infix(Precedence(20), Associativity::Left),
BinaryOperator::SoundsLike => Affix::Infix(Precedence(20), Associativity::Left),

BinaryOperator::BitwiseOr => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::BitwiseAnd => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::BitwiseXor => Affix::Infix(Precedence(22), Associativity::Left),
BinaryOperator::L2Distance => Affix::Infix(Precedence(22), Associativity::Left),

BinaryOperator::BitwiseShiftLeft => {
Affix::Infix(Precedence(23), Associativity::Left)
}
BinaryOperator::BitwiseShiftRight => {
Affix::Infix(Precedence(23), Associativity::Left)
}

BinaryOperator::Xor => Affix::Infix(Precedence(24), Associativity::Left),

BinaryOperator::Plus => Affix::Infix(Precedence(30), Associativity::Left),
BinaryOperator::Minus => Affix::Infix(Precedence(30), Associativity::Left),

BinaryOperator::Multiply => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Div => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Divide => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::IntDiv => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Modulo => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::StringConcat => Affix::Infix(Precedence(40), Associativity::Left),
BinaryOperator::Caret => Affix::Infix(Precedence(40), Associativity::Right),
},
ExprElement::JsonOp { .. } => Affix::Infix(Precedence(40), Associativity::Left),
ExprElement::PgCast { .. } => Affix::Postfix(Precedence(60)),
_ => Affix::Nilfix,
ExprElement::ChainFunctionCall { .. } => CHAIN_FUNCTION_AFFIX,
ExprElement::DotAccess { .. } => DOT_ACCESS_AFFIX,
ExprElement::MapAccess { .. } => MAP_ACCESS_AFFIX,
ExprElement::IsNull { .. } => IS_NULL_AFFIX,
ExprElement::Between { .. } => BETWEEN_AFFIX,
ExprElement::IsDistinctFrom { .. } => IS_DISTINCT_FROM_AFFIX,
ExprElement::InList { .. } => IN_LIST_AFFIX,
ExprElement::InSubquery { .. } => IN_SUBQUERY_AFFIX,
ExprElement::UnaryOp { op } => unary_affix(op),
ExprElement::BinaryOp { op } => binary_affix(op),
ExprElement::JsonOp { .. } => JSON_OP_AFFIX,
ExprElement::PgCast { .. } => PG_CAST_AFFIX,
ExprElement::ColumnRef { .. } => Affix::Nilfix,
ExprElement::Cast { .. } => Affix::Nilfix,
ExprElement::TryCast { .. } => Affix::Nilfix,
ExprElement::Extract { .. } => Affix::Nilfix,
ExprElement::DatePart { .. } => Affix::Nilfix,
ExprElement::Position { .. } => Affix::Nilfix,
ExprElement::SubString { .. } => Affix::Nilfix,
ExprElement::Trim { .. } => Affix::Nilfix,
ExprElement::Literal { .. } => Affix::Nilfix,
ExprElement::CountAll { .. } => Affix::Nilfix,
ExprElement::Tuple { .. } => Affix::Nilfix,
ExprElement::FunctionCall { .. } => Affix::Nilfix,
ExprElement::Case { .. } => Affix::Nilfix,
ExprElement::Exists { .. } => Affix::Nilfix,
ExprElement::Subquery { .. } => Affix::Nilfix,
ExprElement::ListComprehension { .. } => Affix::Nilfix,
ExprElement::Group(_) => Affix::Nilfix,
ExprElement::Array { .. } => Affix::Nilfix,
ExprElement::Map { .. } => Affix::Nilfix,
ExprElement::Interval { .. } => Affix::Nilfix,
ExprElement::DateAdd { .. } => Affix::Nilfix,
ExprElement::DateSub { .. } => Affix::Nilfix,
ExprElement::DateTrunc { .. } => Affix::Nilfix,
ExprElement::Hole { .. } => Affix::Nilfix,
}
}
}

impl From<Expr> for ExprElement {
fn from(expr: Expr) -> Self {
match expr {
Expr::ColumnRef { column, .. } => ExprElement::ColumnRef { column },
Expr::IsNull { not, .. } => ExprElement::IsNull { not },
Expr::IsDistinctFrom { not, .. } => ExprElement::IsDistinctFrom { not },
Expr::InList { list, not, .. } => ExprElement::InList { list, not },
Expr::InSubquery { subquery, not, .. } => ExprElement::InSubquery { subquery, not },
Expr::Between { low, high, not, .. } => ExprElement::Between { low, high, not },
Expr::BinaryOp { op, .. } => ExprElement::BinaryOp { op },
Expr::JsonOp { op, .. } => ExprElement::JsonOp { op },
Expr::UnaryOp { op, .. } => ExprElement::UnaryOp { op },
Expr::Cast {
target_type,
pg_style: true,
..
} => ExprElement::PgCast { target_type },
impl Expr {
pub fn affix(&self) -> Affix {
match self {
Expr::MapAccess { .. } => MAP_ACCESS_AFFIX,
Expr::IsNull { .. } => IS_NULL_AFFIX,
Expr::Between { .. } => BETWEEN_AFFIX,
Expr::IsDistinctFrom { .. } => Affix::Nilfix,
Expr::InList { .. } => IN_LIST_AFFIX,
Expr::InSubquery { .. } => IN_SUBQUERY_AFFIX,
Expr::UnaryOp { op, .. } => unary_affix(op),
Expr::BinaryOp { op, .. } => binary_affix(op),
Expr::JsonOp { .. } => JSON_OP_AFFIX,
Expr::Cast { pg_style: true, .. } => PG_CAST_AFFIX,
Expr::Cast {
expr,
target_type,
pg_style: false,
..
} => ExprElement::Cast { expr, target_type },
Expr::TryCast {
expr, target_type, ..
} => ExprElement::TryCast { expr, target_type },
Expr::Extract { kind, expr, .. } => ExprElement::Extract { field: kind, expr },
Expr::DatePart { kind, expr, .. } => ExprElement::DatePart { field: kind, expr },
Expr::Position {
substr_expr,
str_expr,
..
} => ExprElement::Position {
substr_expr,
str_expr,
},
Expr::Substring {
expr,
substring_from,
substring_for,
..
} => ExprElement::SubString {
expr,
substring_from,
substring_for,
},
Expr::Trim {
expr, trim_where, ..
} => ExprElement::Trim { expr, trim_where },
Expr::Literal { value, .. } => ExprElement::Literal { value },
Expr::CountAll { window, .. } => ExprElement::CountAll { window },
Expr::Tuple { exprs, .. } => ExprElement::Tuple { exprs },
Expr::FunctionCall { func, .. } => ExprElement::FunctionCall { func },
Expr::Case {
operand,
conditions,
results,
else_result,
..
} => ExprElement::Case {
operand,
conditions,
results,
else_result,
},
Expr::Exists { subquery, not, .. } => ExprElement::Exists {
subquery: *subquery,
not,
},
Expr::Subquery {
modifier, subquery, ..
} => ExprElement::Subquery {
modifier,
subquery: *subquery,
},
Expr::MapAccess { accessor, .. } => ExprElement::MapAccess { accessor },
Expr::Array { exprs, .. } => ExprElement::Array { exprs },
Expr::Map { kvs, .. } => ExprElement::Map { kvs },
Expr::Interval { expr, unit, .. } => ExprElement::Interval { expr: *expr, unit },
Expr::DateAdd {
unit,
interval,
date,
..
} => ExprElement::DateAdd {
unit,
interval: *interval,
date: *date,
},
Expr::DateSub {
unit,
interval,
date,
..
} => ExprElement::DateSub {
unit,
interval: *interval,
date: *date,
},
Expr::DateTrunc { unit, date, .. } => ExprElement::DateTrunc { unit, date: *date },
Expr::Hole { name, .. } => ExprElement::Hole { name },
pg_style: false, ..
} => Affix::Nilfix,
Expr::TryCast { .. } => Affix::Nilfix,
Expr::Extract { .. } => Affix::Nilfix,
Expr::DatePart { .. } => Affix::Nilfix,
Expr::Position { .. } => Affix::Nilfix,
Expr::Substring { .. } => Affix::Nilfix,
Expr::ColumnRef { .. } => Affix::Nilfix,
Expr::Trim { .. } => Affix::Nilfix,
Expr::Literal { .. } => Affix::Nilfix,
Expr::CountAll { .. } => Affix::Nilfix,
Expr::Tuple { .. } => Affix::Nilfix,
Expr::FunctionCall { .. } => Affix::Nilfix,
Expr::Case { .. } => Affix::Nilfix,
Expr::Exists { .. } => Affix::Nilfix,
Expr::Subquery { .. } => Affix::Nilfix,
Expr::Array { .. } => Affix::Nilfix,
Expr::Map { .. } => Affix::Nilfix,
Expr::Interval { .. } => Affix::Nilfix,
Expr::DateAdd { .. } => Affix::Nilfix,
Expr::DateSub { .. } => Affix::Nilfix,
Expr::DateTrunc { .. } => Affix::Nilfix,
Expr::Hole { .. } => Affix::Nilfix,
}
}
}
Expand Down

0 comments on commit 0b87c30

Please sign in to comment.