Skip to content

Commit d15602b

Browse files
authored
fix(binder): fix explain with parameters; simplify IN expr without consts (#23579)
1 parent be60f7e commit d15602b

File tree

4 files changed

+65
-15
lines changed

4 files changed

+65
-15
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
- id: explain parameters
2+
sql: |
3+
explain select $1
4+
expected_outputs:
5+
- explain_output
6+
- id: explain parameters in in-expr
7+
sql: |
8+
create table t (id int primary key, a int);
9+
explain select * from t where id in($1)
10+
expected_outputs:
11+
- explain_output
12+
- id: explain parameters in in-expr
13+
sql: |
14+
create table t (id int primary key, a int);
15+
explain select * from t where id in($1, 123)
16+
expected_outputs:
17+
- explain_output
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This file is automatically generated. See `src/frontend/planner_test/README.md` for more information.
2+
- id: explain parameters
3+
sql: |
4+
explain select $1
5+
explain_output: |
6+
BatchProject { exprs: [Parameter(index: 1, type: None) as $expr1] }
7+
└─BatchValues { rows: [[]] }
8+
- id: explain parameters in in-expr
9+
sql: |
10+
create table t (id int primary key, a int);
11+
explain select * from t where id in($1)
12+
explain_output: |
13+
BatchExchange { order: [], dist: Single }
14+
└─BatchFilter { predicate: (t.id = Parameter(index: 1, type: Some(Int32))) }
15+
└─BatchScan { table: t, columns: [id, a] }
16+
- id: explain parameters in in-expr
17+
sql: |
18+
create table t (id int primary key, a int);
19+
explain select * from t where id in($1, 123)
20+
explain_output: |
21+
BatchExchange { order: [], dist: Single }
22+
└─BatchFilter { predicate: (In(t.id, 123:Int32) OR (t.id = Parameter(index: 1, type: Some(Int32)))) }
23+
└─BatchScan { table: t, columns: [id, a] }

src/frontend/src/binder/expr/mod.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -278,22 +278,36 @@ impl Binder {
278278
false => non_const_exprs.push(expr),
279279
}
280280
}
281-
let mut ret = FunctionCall::new(ExprType::In, bound_expr_list)?.into();
281+
282+
let mut ret = if bound_expr_list.len() == 1 {
283+
None
284+
} else {
285+
Some(FunctionCall::new(ExprType::In, bound_expr_list)?.into())
286+
};
282287
// Non-const exprs are not part of IN-expr in backend and rewritten into OR-Equal-exprs.
283288
for expr in non_const_exprs {
284-
ret = FunctionCall::new(
285-
ExprType::Or,
286-
vec![
287-
ret,
288-
FunctionCall::new(ExprType::Equal, vec![left.clone(), expr])?.into(),
289-
],
290-
)?
291-
.into();
289+
if let Some(inner_ret) = ret {
290+
ret = Some(
291+
FunctionCall::new(
292+
ExprType::Or,
293+
vec![
294+
inner_ret,
295+
FunctionCall::new(ExprType::Equal, vec![left.clone(), expr])?.into(),
296+
],
297+
)?
298+
.into(),
299+
);
300+
} else {
301+
ret = Some(FunctionCall::new(ExprType::Equal, vec![left.clone(), expr])?.into());
302+
}
292303
}
293304
if negated {
294-
Ok(FunctionCall::new_unchecked(ExprType::Not, vec![ret], DataType::Boolean).into())
305+
Ok(
306+
FunctionCall::new_unchecked(ExprType::Not, vec![ret.unwrap()], DataType::Boolean)
307+
.into(),
308+
)
295309
} else {
296-
Ok(ret)
310+
Ok(ret.unwrap())
297311
}
298312
}
299313

src/frontend/src/optimizer/plan_expr_rewriter/const_eval_rewriter.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ impl ExprRewriter for ConstEvalRewriter {
3131
expr
3232
}
3333
}
34-
} else if let ExprImpl::Parameter(_) = expr {
35-
unreachable!(
36-
"Parameter should not appear here. It will be replaced by a literal before this step."
37-
)
3834
} else {
3935
default_rewrite_expr(self, expr)
4036
}

0 commit comments

Comments
 (0)