Skip to content

Commit fc608f1

Browse files
committed
feat: support position column in common sql query
1 parent 3c6a4fe commit fc608f1

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/query/sql/src/planner/binder/bind_context.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,15 @@ impl BindContext {
296296
self.columns.push(column_binding);
297297
}
298298

299+
/// Assigns 1-based column positions for the current result columns.
300+
/// This is mainly used for derived tables/subqueries so that `$n` style
301+
/// ordinal references can resolve against their outputs.
302+
pub fn reset_result_column_positions(&mut self) {
303+
for (idx, column) in self.columns.iter_mut().enumerate() {
304+
column.column_position = Some(idx + 1);
305+
}
306+
}
307+
299308
/// Apply table alias like `SELECT * FROM t AS t1(a, b, c)`.
300309
/// This method will rename column bindings according to table alias.
301310
pub fn apply_table_alias(

src/query/sql/src/planner/binder/bind_query/bind.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ impl Binder {
101101
s_expr = self.bind_materialized_cte(with, s_expr, bind_context.cte_context.clone())?;
102102
}
103103

104+
bind_context.reset_result_column_positions();
105+
104106
Ok((s_expr, bind_context))
105107
}
106108

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Regression coverage for ordinal column references ($n) on derived tables.
2+
3+
statement ok
4+
create or replace database issue_column_position
5+
6+
statement ok
7+
use issue_column_position
8+
9+
query
10+
select $1, $2 from (select 1 as a, 2 as b, 3 as c) as t
11+
----
12+
1 2
13+
14+
query
15+
select t.$1, t.$2 from (select number, number + 10 as n from numbers(3)) as t order by t.$1
16+
----
17+
0 10
18+
1 11
19+
2 12
20+
21+
statement ok
22+
create or replace table monthly_totals(empid int, amount int)
23+
24+
statement ok
25+
insert into monthly_totals values (1, 100), (1, 200), (2, 50), (2, 75)
26+
27+
query
28+
with totals as ( select empid, sum(amount) as total from monthly_totals group by empid ) select totals.$1, totals.$2 from totals order by totals.$1
29+
----
30+
1 300
31+
2 125
32+
33+
statement ok
34+
CREATE OR REPLACE TABLE monthly_sales(empid INT, amount INT, month TEXT);
35+
36+
statement ok
37+
INSERT INTO monthly_sales VALUES (1, 10000, 'JAN'), (1, 400, 'JAN'), (2, 4500, 'JAN'), (2, 35000, 'JAN'), (1, 5000, 'FEB'), (1, 3000, 'FEB'), (2, 200, 'FEB'), (2, 90500, 'FEB'), (1, 6000, 'MAR'), (1, 5000, 'MAR'), (2, 2500, 'MAR'), (2, 9500, 'MAR'), (1, 8000, 'APR'), (1, 10000, 'APR'), (2, 800, 'APR'), (2, 4500, 'APR');
38+
39+
query
40+
SELECT $1, $2, $3 FROM monthly_sales PIVOT(SUM(amount) FOR MONTH IN (SELECT DISTINCT month FROM monthly_sales)) ORDER BY EMPID
41+
----
42+
1 18000 8000
43+
2 5300 90700
44+
45+
statement ok
46+
drop database issue_column_position

0 commit comments

Comments
 (0)