From 1d62c26c82c9f584f782c258abc9f66acc89e6ac Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Sat, 19 Sep 2026 21:46:51 +0000 Subject: [PATCH] fix: validate trailing free RANGE order types --- datafusion/optimizer/src/analyzer/type_coercion.rs | 9 ++++++++- datafusion/sqllogictest/test_files/window.slt | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/datafusion/optimizer/src/analyzer/type_coercion.rs b/datafusion/optimizer/src/analyzer/type_coercion.rs index bf5767c3ca78b..1b2b2ae14ccef 100644 --- a/datafusion/optimizer/src/analyzer/type_coercion.rs +++ b/datafusion/optimizer/src/analyzer/type_coercion.rs @@ -1200,7 +1200,14 @@ fn coerce_window_frame( .transpose()?; if let Some(col_type) = current_types { let target_type = match extract_window_frame_target_type(&col_type) { - Some(target_type) => target_type, + Some(target_type) => { + if window_frame.free_range() { + // The first key established the target type above, but + // every later key also participates in peer comparison. + check_free_range_order_by_types(&expressions[1..], schema)?; + } + target_type + } // A free range frame has no offsets to coerce, so ORDER BY // types without arithmetic are fine as long as their peer // comparison is sound (see `supports_free_range_frame`). diff --git a/datafusion/sqllogictest/test_files/window.slt b/datafusion/sqllogictest/test_files/window.slt index af12fad670796..22cdf53ce791c 100644 --- a/datafusion/sqllogictest/test_files/window.slt +++ b/datafusion/sqllogictest/test_files/window.slt @@ -7129,6 +7129,12 @@ select count(*) over (order by x) from (values (map(['a'], [1])), (map(['a'], [2 statement error Error during planning: RANGE window frames are not supported for ORDER BY type Map select count(*) over (order by d, m) from (values (arrow_cast(1, 'Duration(Second)'), map(['a'], [1])), (arrow_cast(1, 'Duration(Second)'), map(['a'], [2]))) t(d, m) +# the trailing key check also runs when the first ORDER BY type supports offset +# arithmetic; otherwise these maps are treated as peers because their keys are +# equal even though their values differ +statement error Error during planning: RANGE window frames are not supported for ORDER BY type Map +select count(*) over (order by i, m) from (values (1, map(['a'], [1])), (1, map(['a'], [2]))) t(i, m) + query ??I select d, e, count(*) over (order by d, e) from (values (arrow_cast(1, 'Duration(Second)'), arrow_cast(2, 'Duration(Millisecond)')), (arrow_cast(1, 'Duration(Second)'), arrow_cast(1, 'Duration(Millisecond)'))) t(d, e) order by 3 ----