Merge 'Fix sorter column deduplication' from Piotr Rżysko

Previously, the added test case failed because the last result column
was missing - a nonexistent column in the sorter was referenced.

Closes #2824
This commit is contained in:
Pekka Enberg
2025-08-28 18:29:44 +03:00
committed by GitHub
2 changed files with 22 additions and 7 deletions

View File

@@ -321,16 +321,15 @@ pub struct OrderByRemapping {
/// In case any of the ORDER BY sort keys are exactly equal to a result column, we can skip emitting that result column.
/// If we skip a result column, we need to keep track what index in the ORDER BY sorter the result columns have,
/// because the result columns should be emitted in the SELECT clause order, not the ORDER BY clause order.
///
/// If any result columns can be skipped, this returns list of 2-tuples of (SkippedResultColumnIndex: usize, ResultColumnIndexInOrderBySorter: usize)
pub fn order_by_deduplicate_result_columns(
order_by: &[(Box<ast::Expr>, SortOrder)],
result_columns: &[ResultSetColumn],
) -> Vec<OrderByRemapping> {
let mut result_column_remapping: Vec<OrderByRemapping> = Vec::new();
let mut independent_order_by_cols_on_the_left = order_by.len();
let order_by_len = order_by.len();
for (i, rc) in result_columns.iter().enumerate() {
let mut i = 0;
for rc in result_columns.iter() {
let found = order_by
.iter()
.enumerate()
@@ -340,13 +339,15 @@ pub fn order_by_deduplicate_result_columns(
orderby_sorter_idx: j,
deduplicated: true,
});
independent_order_by_cols_on_the_left =
independent_order_by_cols_on_the_left.saturating_sub(1);
} else {
// This result column is not a duplicate of any ORDER BY key, so its sorter
// index comes after all ORDER BY entries (hence the +order_by_len). The
// counter `i` tracks how many such non-duplicate result columns we've seen.
result_column_remapping.push(OrderByRemapping {
orderby_sorter_idx: i + independent_order_by_cols_on_the_left,
orderby_sorter_idx: i + order_by_len,
deduplicated: false,
});
i += 1;
}
}

View File

@@ -218,3 +218,17 @@ do_execsql_test_on_specific_db {:memory:} distinct_orderby_regression {
SELECT DISTINCT c,b FROM t ORDER BY d,b;
} {3|2
4|3}
do_execsql_test order_by_column_deduplication {
select name, name, price from products order by name;
} {accessories|accessories|81.0
boots|boots|1.0
cap|cap|82.0
coat|coat|33.0
hat|hat|79.0
jeans|jeans|78.0
shirt|shirt|18.0
shorts|shorts|70.0
sneakers|sneakers|82.0
sweater|sweater|25.0
sweatshirt|sweatshirt|74.0}