This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new b3d2cb622c Fix ORDER BY positional reference regression with aliased
aggregates (#19412)
b3d2cb622c is described below
commit b3d2cb622c64f6133267ba259ed03f4e8416aebf
Author: Adrian Garcia Badaracco <[email protected]>
AuthorDate: Fri Dec 19 14:47:01 2025 -0600
Fix ORDER BY positional reference regression with aliased aggregates
(#19412)
## Which issue does this PR close?
Closes #19410
## Rationale for this change
This PR fixes a regression introduced in #18831 where queries using
GROUP BY with ORDER BY positional reference to an aliased aggregate fail
with:
```
Error during planning: Column in ORDER BY must be in GROUP BY or an
aggregate function
```
**Failing query (now fixed):**
```sql
with t as (select 'foo' as x)
select x, count(*) as "Count"
from t
group by x
order by 2 desc;
```
## What changes are included in this PR?
**Root cause:** When building the list of valid columns for ORDER BY
validation in `select.rs`, alias names were converted to `Column` using
`.into()`, which calls `from_qualified_name()` and normalizes
identifiers to lowercase. However, ORDER BY positional references
resolve to columns using schema field names, which preserve case. This
caused a mismatch (e.g., `Column("Count")` vs `Column("count")`).
**Fix:** Use `Column::new_unqualified()` instead of `.into()` to
preserve the exact case of alias names, matching how the schema stores
field names.
## Are these changes tested?
Yes, added a regression test to `order.slt`.
## Are there any user-facing changes?
No, this is a bug fix that restores expected behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <[email protected]>
---
datafusion/sql/src/select.rs | 8 +++++---
datafusion/sqllogictest/test_files/order.slt | 11 +++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/datafusion/sql/src/select.rs b/datafusion/sql/src/select.rs
index cbcc6c3e10..1d6ccde6be 100644
--- a/datafusion/sql/src/select.rs
+++ b/datafusion/sql/src/select.rs
@@ -29,8 +29,8 @@ use crate::utils::{
use datafusion_common::error::DataFusionErrorBuilder;
use datafusion_common::tree_node::{TreeNode, TreeNodeRecursion};
+use datafusion_common::{Column, Result, not_impl_err, plan_err};
use datafusion_common::{RecursionUnnestOption, UnnestOptions};
-use datafusion_common::{Result, not_impl_err, plan_err};
use datafusion_expr::expr::{Alias, PlannedReplaceSelectItem, WildcardOptions};
use datafusion_expr::expr_rewriter::{
normalize_col, normalize_col_with_schemas_and_ambiguity_check,
normalize_sorts,
@@ -1054,7 +1054,9 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
&& alias.expr.as_ref() == &rewritten_expr
{
// Use the alias name
- return
Some(Expr::Column(alias.name.clone().into()));
+ return Some(Expr::Column(Column::new_unqualified(
+ alias.name.clone(),
+ )));
}
None
})
@@ -1069,7 +1071,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
.cloned()
.chain(select_exprs_post_aggr.iter().filter_map(|e| {
if let Expr::Alias(alias) = e {
- Some(Expr::Column(alias.name.clone().into()))
+
Some(Expr::Column(Column::new_unqualified(alias.name.clone())))
} else {
None
}
diff --git a/datafusion/sqllogictest/test_files/order.slt
b/datafusion/sqllogictest/test_files/order.slt
index 62579ea1cd..7c857cae36 100644
--- a/datafusion/sqllogictest/test_files/order.slt
+++ b/datafusion/sqllogictest/test_files/order.slt
@@ -444,6 +444,17 @@ select column1 from foo group by column1 order by
min(column2), max(column2);
3
5
+# Test GROUP BY alias with ORDER BY column index
+# Regression test: GROUP BY an aliased column, ORDER BY using column index
+query TI
+with t as (select 'foo' as x)
+select x, count(*) as "Count"
+from t
+group by x
+order by 2 desc;
+----
+foo 1
+
# Test issue: https://github.com/apache/datafusion/issues/11549
query I
select column1 from foo order by log(column2);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]