Skip to content

Commit

Permalink
Merge branch 'reduce-functions-code-expand' of github.com:sundy-li/fu…
Browse files Browse the repository at this point in the history
…se-query into reduce-functions-code-expand
  • Loading branch information
sundy-li committed Dec 26, 2024
2 parents 00c9086 + 7e59a20 commit ae54413
Show file tree
Hide file tree
Showing 36 changed files with 1,229 additions and 176 deletions.
30 changes: 30 additions & 0 deletions src/query/ast/src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,18 @@ impl Display for SetExpr {
write!(f, "({query})")?;
}
SetExpr::SetOperation(set_operation) => {
// Check if the left or right expressions are also SetOperations
let left_needs_parentheses = matches!(set_operation.left.as_ref(), SetExpr::SetOperation(left_op) if left_op.op < set_operation.op);
let right_needs_parentheses = matches!(set_operation.right.as_ref(), SetExpr::SetOperation(right_op) if right_op.op < set_operation.op);

if left_needs_parentheses {
write!(f, "(")?;
}
write!(f, "{}", set_operation.left)?;
if left_needs_parentheses {
write!(f, ")")?;
}

match set_operation.op {
SetOperator::Union => {
write!(f, " UNION ")?;
Expand All @@ -316,7 +327,14 @@ impl Display for SetExpr {
if set_operation.all {
write!(f, "ALL ")?;
}
// Add parentheses if necessary
if right_needs_parentheses {
write!(f, "(")?;
}
write!(f, "{}", set_operation.right)?;
if right_needs_parentheses {
write!(f, ")")?;
}
}
SetExpr::Values { values, .. } => {
write!(f, "VALUES")?;
Expand All @@ -341,6 +359,18 @@ pub enum SetOperator {
Intersect,
}

impl PartialOrd for SetOperator {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if self == other {
Some(std::cmp::Ordering::Equal)
} else if self == &SetOperator::Intersect {
Some(std::cmp::Ordering::Greater)
} else {
Some(std::cmp::Ordering::Less)
}
}
}

/// `ORDER BY` clause
#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
pub struct OrderByExpr {
Expand Down
14 changes: 14 additions & 0 deletions src/query/ast/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,19 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
},
);

let interval_expr = map(
rule! {
INTERVAL ~ #consumed(literal_string)
},
|(_, (span, date))| ExprElement::Cast {
expr: Box::new(Expr::Literal {
span: transform_span(span.tokens),
value: Literal::String(date),
}),
target_type: TypeName::Interval,
},
);

let is_distinct_from = map(
rule! {
IS ~ NOT? ~ DISTINCT ~ FROM
Expand Down Expand Up @@ -1360,6 +1373,7 @@ pub fn expr_element(i: Input) -> IResult<WithSpan<ExprElement>> {
| #date_expr : "`DATE <str_literal>`"
| #timestamp_expr : "`TIMESTAMP <str_literal>`"
| #interval : "`INTERVAL ... (YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | DOY | DOW)`"
| #interval_expr : "`INTERVAL <str_literal>`"
| #extract : "`EXTRACT((YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | WEEK) FROM ...)`"
| #date_part : "`DATE_PART((YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | SECOND | WEEK), ...)`"

Expand Down
5 changes: 5 additions & 0 deletions src/query/ast/src/parser/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ impl<'a, I: Iterator<Item = WithSpan<'a, SetOperationElement>>> PrattParser<I>

fn query(&mut self, input: &Self::Input) -> Result<Affix, &'static str> {
let affix = match &input.elem {
// https://learn.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-except-and-intersect-transact-sql?view=sql-server-2017
// If EXCEPT or INTERSECT is used together with other operators in an expression, it's evaluated in the context of the following precedence:
// 1. Expressions in parentheses
// 2. The INTERSECT operator
// 3. EXCEPT and UNION evaluated from left to right based on their position in the expression
SetOperationElement::SetOperation { op, .. } => match op {
SetOperator::Union | SetOperator::Except => {
Affix::Infix(Precedence(10), Associativity::Left)
Expand Down
11 changes: 11 additions & 0 deletions src/query/ast/tests/it/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,17 @@ fn test_query() {
r#"select * from t1 except select * from t2"#,
r#"select * from t1 union select * from t2 union select * from t3"#,
r#"select * from t1 union select * from t2 union all select * from t3"#,
r#"select * from (
(SELECT f, g FROM union_fuzz_result1
EXCEPT
SELECT f, g FROM union_fuzz_result2)
UNION ALL
(SELECT f, g FROM union_fuzz_result2
EXCEPT
SELECT f, g FROM union_fuzz_result1)
)"#,
r#"select * from t1 union select * from t2 intersect select * from t3"#,
r#"(select * from t1 union select * from t2) intersect select * from t3"#,
r#"(select * from t1 union select * from t2) union select * from t3"#,
r#"select * from t1 union (select * from t2 union select * from t3)"#,
r#"SELECT * FROM ((SELECT *) EXCEPT (SELECT *)) foo"#,
Expand Down Expand Up @@ -1244,6 +1254,7 @@ fn test_expr() {
r#"MAP_FILTER({1:1,2:2,3:4}, (k, v) -> k > v)"#,
r#"MAP_TRANSFORM_KEYS({1:10,2:20,3:30}, (k, v) -> k + 1)"#,
r#"MAP_TRANSFORM_VALUES({1:10,2:20,3:30}, (k, v) -> v + 1)"#,
r#"INTERVAL '1 YEAR'"#,
];

for case in cases {
Expand Down
22 changes: 22 additions & 0 deletions src/query/ast/tests/it/testdata/expr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5034,3 +5034,25 @@ FunctionCall {
}


---------- Input ----------
INTERVAL '1 YEAR'
---------- Output ---------
CAST('1 YEAR' AS INTERVAL)
---------- AST ------------
Cast {
span: Some(
0..17,
),
expr: Literal {
span: Some(
9..17,
),
value: String(
"1 YEAR",
),
},
target_type: Interval,
pg_style: false,
}


Loading

0 comments on commit ae54413

Please sign in to comment.