Skip to content

Commit d2511b2

Browse files
authored
fix: planning of prepare statement with limit clause (#13088)
* fix: planning of prepare statement with limit clause * Improve test
1 parent 22a242c commit d2511b2

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

datafusion/sql/src/query.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
5353
// so we need to process `SELECT` and `ORDER BY` together.
5454
let oby_exprs = to_order_by_exprs(query.order_by)?;
5555
let plan = self.select_to_plan(*select, oby_exprs, planner_context)?;
56-
let plan = self.limit(plan, query.offset, query.limit)?;
56+
let plan =
57+
self.limit(plan, query.offset, query.limit, planner_context)?;
5758
// Process the `SELECT INTO` after `LIMIT`.
5859
self.select_into(plan, select_into)
5960
}
@@ -68,7 +69,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
6869
None,
6970
)?;
7071
let plan = self.order_by(plan, order_by_rex)?;
71-
self.limit(plan, query.offset, query.limit)
72+
self.limit(plan, query.offset, query.limit, planner_context)
7273
}
7374
}
7475
}
@@ -79,6 +80,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
7980
input: LogicalPlan,
8081
skip: Option<SQLOffset>,
8182
fetch: Option<SQLExpr>,
83+
planner_context: &mut PlannerContext,
8284
) -> Result<LogicalPlan> {
8385
if skip.is_none() && fetch.is_none() {
8486
return Ok(input);
@@ -88,10 +90,10 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
8890
let empty_schema = DFSchema::empty();
8991

9092
let skip = skip
91-
.map(|o| self.sql_to_expr(o.value, &empty_schema, &mut PlannerContext::new()))
93+
.map(|o| self.sql_to_expr(o.value, &empty_schema, planner_context))
9294
.transpose()?;
9395
let fetch = fetch
94-
.map(|e| self.sql_to_expr(e, &empty_schema, &mut PlannerContext::new()))
96+
.map(|e| self.sql_to_expr(e, &empty_schema, planner_context))
9597
.transpose()?;
9698
LogicalPlanBuilder::from(input)
9799
.limit_by_expr(skip, fetch)?

datafusion/sql/tests/sql_integration.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4209,6 +4209,29 @@ fn test_prepare_statement_to_plan_having() {
42094209
prepare_stmt_replace_params_quick_test(plan, param_values, expected_plan);
42104210
}
42114211

4212+
#[test]
4213+
fn test_prepare_statement_to_plan_limit() {
4214+
let sql = "PREPARE my_plan(BIGINT, BIGINT) AS
4215+
SELECT id FROM person \
4216+
OFFSET $1 LIMIT $2";
4217+
4218+
let expected_plan = "Prepare: \"my_plan\" [Int64, Int64] \
4219+
\n Limit: skip=$1, fetch=$2\
4220+
\n Projection: person.id\
4221+
\n TableScan: person";
4222+
4223+
let expected_dt = "[Int64, Int64]";
4224+
4225+
let plan = prepare_stmt_quick_test(sql, expected_plan, expected_dt);
4226+
4227+
// replace params with values
4228+
let param_values = vec![ScalarValue::Int64(Some(10)), ScalarValue::Int64(Some(200))];
4229+
let expected_plan = "Limit: skip=10, fetch=200\
4230+
\n Projection: person.id\
4231+
\n TableScan: person";
4232+
prepare_stmt_replace_params_quick_test(plan, param_values, expected_plan);
4233+
}
4234+
42124235
#[test]
42134236
fn test_prepare_statement_to_plan_value_list() {
42144237
let sql = "PREPARE my_plan(STRING, STRING) AS SELECT * FROM (VALUES(1, $1), (2, $2)) AS t (num, letter);";

0 commit comments

Comments
 (0)