This is an automated email from the ASF dual-hosted git repository.

alamb 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 f3975da070 Fix type coercion for unsigned and signed integers (`Int64` 
vs `UInt64`, etc) (#15341)
f3975da070 is described below

commit f3975da0704160c8fff2ab8a847928ec7a19c224
Author: Bruce Ritchie <[email protected]>
AuthorDate: Tue Mar 25 16:42:15 2025 -0400

    Fix type coercion for unsigned and signed integers (`Int64` vs `UInt64`, 
etc) (#15341)
    
    * type coercion fix for uint/int's.
    
    * Refactored common numerical coercion logic into a single function.
    
    * Cargo fmt.
---
 datafusion/expr-common/src/type_coercion/binary.rs | 199 ++++++++++++++-------
 .../optimizer/src/single_distinct_to_groupby.rs    |   8 +-
 .../optimizer/tests/optimizer_integration.rs       |   4 +-
 datafusion/physical-expr/src/expressions/binary.rs |   6 +-
 datafusion/sqllogictest/test_files/math.slt        |  10 +-
 datafusion/sqllogictest/test_files/operator.slt    |   8 +-
 datafusion/sqllogictest/test_files/window.slt      |   8 +-
 7 files changed, 153 insertions(+), 90 deletions(-)

diff --git a/datafusion/expr-common/src/type_coercion/binary.rs 
b/datafusion/expr-common/src/type_coercion/binary.rs
index c8331dfe98..c874067af3 100644
--- a/datafusion/expr-common/src/type_coercion/binary.rs
+++ b/datafusion/expr-common/src/type_coercion/binary.rs
@@ -838,7 +838,6 @@ pub fn binary_numeric_coercion(
     lhs_type: &DataType,
     rhs_type: &DataType,
 ) -> Option<DataType> {
-    use arrow::datatypes::DataType::*;
     if !lhs_type.is_numeric() || !rhs_type.is_numeric() {
         return None;
     };
@@ -852,39 +851,7 @@ pub fn binary_numeric_coercion(
         return Some(t);
     }
 
-    // These are ordered from most informative to least informative so
-    // that the coercion does not lose information via truncation
-    match (lhs_type, rhs_type) {
-        (Float64, _) | (_, Float64) => Some(Float64),
-        (_, Float32) | (Float32, _) => Some(Float32),
-        // The following match arms encode the following logic: Given the two
-        // integral types, we choose the narrowest possible integral type that
-        // accommodates all values of both types. Note that to avoid 
information
-        // loss when combining UInt64 with signed integers we use 
Decimal128(20, 0).
-        (UInt64, Int64 | Int32 | Int16 | Int8)
-        | (Int64 | Int32 | Int16 | Int8, UInt64) => Some(Decimal128(20, 0)),
-        (UInt64, _) | (_, UInt64) => Some(UInt64),
-        (Int64, _)
-        | (_, Int64)
-        | (UInt32, Int8)
-        | (Int8, UInt32)
-        | (UInt32, Int16)
-        | (Int16, UInt32)
-        | (UInt32, Int32)
-        | (Int32, UInt32) => Some(Int64),
-        (Int32, _)
-        | (_, Int32)
-        | (UInt16, Int16)
-        | (Int16, UInt16)
-        | (UInt16, Int8)
-        | (Int8, UInt16) => Some(Int32),
-        (UInt32, _) | (_, UInt32) => Some(UInt32),
-        (Int16, _) | (_, Int16) | (Int8, UInt8) | (UInt8, Int8) => Some(Int16),
-        (UInt16, _) | (_, UInt16) => Some(UInt16),
-        (Int8, _) | (_, Int8) => Some(Int8),
-        (UInt8, _) | (_, UInt8) => Some(UInt8),
-        _ => None,
-    }
+    numerical_coercion(lhs_type, rhs_type)
 }
 
 /// Decimal coercion rules.
@@ -1045,15 +1012,36 @@ fn mathematics_numerical_coercion(
         (_, Dictionary(_, value_type)) => {
             mathematics_numerical_coercion(lhs_type, value_type)
         }
+        _ => numerical_coercion(lhs_type, rhs_type),
+    }
+}
+
+/// A common set of numerical coercions that are applied for mathematical and 
binary ops
+/// to `lhs_type` and `rhs_type`.
+fn numerical_coercion(lhs_type: &DataType, rhs_type: &DataType) -> 
Option<DataType> {
+    use arrow::datatypes::DataType::*;
+
+    match (lhs_type, rhs_type) {
         (Float64, _) | (_, Float64) => Some(Float64),
         (_, Float32) | (Float32, _) => Some(Float32),
-        (Int64, _) | (_, Int64) => Some(Int64),
-        (Int32, _) | (_, Int32) => Some(Int32),
-        (Int16, _) | (_, Int16) => Some(Int16),
-        (Int8, _) | (_, Int8) => Some(Int8),
+        // The following match arms encode the following logic: Given the two
+        // integral types, we choose the narrowest possible integral type that
+        // accommodates all values of both types. Note that to avoid 
information
+        // loss when combining UInt64 with signed integers we use 
Decimal128(20, 0).
+        (UInt64, Int64 | Int32 | Int16 | Int8)
+        | (Int64 | Int32 | Int16 | Int8, UInt64) => Some(Decimal128(20, 0)),
         (UInt64, _) | (_, UInt64) => Some(UInt64),
+        (Int64, _)
+        | (_, Int64)
+        | (UInt32, Int32 | Int16 | Int8)
+        | (Int32 | Int16 | Int8, UInt32) => Some(Int64),
         (UInt32, _) | (_, UInt32) => Some(UInt32),
+        (Int32, _) | (_, Int32) | (UInt16, Int16 | Int8) | (Int16 | Int8, 
UInt16) => {
+            Some(Int32)
+        }
         (UInt16, _) | (_, UInt16) => Some(UInt16),
+        (Int16, _) | (_, Int16) | (Int8, UInt8) | (UInt8, Int8) => Some(Int16),
+        (Int8, _) | (_, Int8) => Some(Int8),
         (UInt8, _) | (_, UInt8) => Some(UInt8),
         _ => None,
     }
@@ -1632,7 +1620,7 @@ mod tests {
 
     /// Test coercion rules for binary operators
     ///
-    /// Applies coercion rules for `$LHS_TYPE $OP $RHS_TYPE` and asserts that 
the
+    /// Applies coercion rules for `$LHS_TYPE $OP $RHS_TYPE` and asserts that
     /// the result type is `$RESULT_TYPE`
     macro_rules! test_coercion_binary_rule {
         ($LHS_TYPE:expr, $RHS_TYPE:expr, $OP:expr, $RESULT_TYPE:expr) => {{
@@ -1643,6 +1631,26 @@ mod tests {
         }};
     }
 
+    /// Test coercion rules for binary operators
+    ///
+    /// Applies coercion rules for each RHS_TYPE in $RHS_TYPES such that
+    /// `$LHS_TYPE $OP RHS_TYPE` and asserts that the result type is 
`$RESULT_TYPE`.
+    /// Also tests that the inverse `RHS_TYPE $OP $LHS_TYPE` is true
+    macro_rules! test_coercion_binary_rule_multiple {
+        ($LHS_TYPE:expr, $RHS_TYPES:expr, $OP:expr, $RESULT_TYPE:expr) => {{
+            for rh_type in $RHS_TYPES {
+                let (lhs, rhs) = BinaryTypeCoercer::new(&$LHS_TYPE, &$OP, 
&rh_type)
+                    .get_input_types()?;
+                assert_eq!(lhs, $RESULT_TYPE);
+                assert_eq!(rhs, $RESULT_TYPE);
+
+                BinaryTypeCoercer::new(&rh_type, &$OP, 
&$LHS_TYPE).get_input_types()?;
+                assert_eq!(lhs, $RESULT_TYPE);
+                assert_eq!(rhs, $RESULT_TYPE);
+            }
+        }};
+    }
+
     /// Test coercion rules for like
     ///
     /// Applies coercion rules for both
@@ -2002,39 +2010,94 @@ mod tests {
 
     #[test]
     fn test_type_coercion_arithmetic() -> Result<()> {
-        // integer
-        test_coercion_binary_rule!(
-            DataType::Int32,
-            DataType::UInt32,
+        use DataType::*;
+
+        // (Float64, _) | (_, Float64) => Some(Float64),
+        test_coercion_binary_rule_multiple!(
+            Float64,
+            [
+                Float64, Float32, Float16, Int64, UInt64, Int32, UInt32, 
Int16, UInt16,
+                Int8, UInt8
+            ],
             Operator::Plus,
-            DataType::Int32
-        );
-        test_coercion_binary_rule!(
-            DataType::Int32,
-            DataType::UInt16,
+            Float64
+        );
+        // (_, Float32) | (Float32, _) => Some(Float32),
+        test_coercion_binary_rule_multiple!(
+            Float32,
+            [
+                Float32, Float16, Int64, UInt64, Int32, UInt32, Int16, UInt16, 
Int8,
+                UInt8
+            ],
+            Operator::Plus,
+            Float32
+        );
+        // (UInt64, Int64 | Int32 | Int16 | Int8) | (Int64 | Int32 | Int16 | 
Int8, UInt64)  => Some(Decimal128(20, 0)),
+        test_coercion_binary_rule_multiple!(
+            UInt64,
+            [Int64, Int32, Int16, Int8],
+            Operator::Divide,
+            Decimal128(20, 0)
+        );
+        // (UInt64, _) | (_, UInt64) => Some(UInt64),
+        test_coercion_binary_rule_multiple!(
+            UInt64,
+            [UInt64, UInt32, UInt16, UInt8],
+            Operator::Modulo,
+            UInt64
+        );
+        // (Int64, _) | (_, Int64) => Some(Int64),
+        test_coercion_binary_rule_multiple!(
+            Int64,
+            [Int64, Int32, UInt32, Int16, UInt16, Int8, UInt8],
+            Operator::Modulo,
+            Int64
+        );
+        // (UInt32, Int32 | Int16 | Int8) | (Int32 | Int16 | Int8, UInt32) => 
Some(Int64)
+        test_coercion_binary_rule_multiple!(
+            UInt32,
+            [Int32, Int16, Int8],
+            Operator::Modulo,
+            Int64
+        );
+        // (UInt32, _) | (_, UInt32) => Some(UInt32),
+        test_coercion_binary_rule_multiple!(
+            UInt32,
+            [UInt32, UInt16, UInt8],
+            Operator::Modulo,
+            UInt32
+        );
+        // (Int32, _) | (_, Int32) => Some(Int32),
+        test_coercion_binary_rule_multiple!(
+            Int32,
+            [Int32, Int16, Int8],
+            Operator::Modulo,
+            Int32
+        );
+        // (UInt16, Int16 | Int8) | (Int16 | Int8, UInt16) => Some(Int32)
+        test_coercion_binary_rule_multiple!(
+            UInt16,
+            [Int16, Int8],
             Operator::Minus,
-            DataType::Int32
+            Int32
         );
-        test_coercion_binary_rule!(
-            DataType::Int8,
-            DataType::Int64,
-            Operator::Multiply,
-            DataType::Int64
-        );
-        // float
-        test_coercion_binary_rule!(
-            DataType::Float32,
-            DataType::Int32,
+        // (UInt16, _) | (_, UInt16) => Some(UInt16),
+        test_coercion_binary_rule_multiple!(
+            UInt16,
+            [UInt16, UInt8, UInt8],
             Operator::Plus,
-            DataType::Float32
-        );
-        test_coercion_binary_rule!(
-            DataType::Float32,
-            DataType::Float64,
-            Operator::Multiply,
-            DataType::Float64
-        );
-        // TODO add other data type
+            UInt16
+        );
+        // (Int16, _) | (_, Int16) => Some(Int16),
+        test_coercion_binary_rule_multiple!(Int16, [Int16, Int8], 
Operator::Plus, Int16);
+        // (UInt8, Int8) | (Int8, UInt8) => Some(Int16)
+        test_coercion_binary_rule!(Int8, UInt8, Operator::Minus, Int16);
+        test_coercion_binary_rule!(UInt8, Int8, Operator::Multiply, Int16);
+        // (UInt8, _) | (_, UInt8) => Some(UInt8),
+        test_coercion_binary_rule!(UInt8, UInt8, Operator::Minus, UInt8);
+        // (Int8, _) | (_, Int8) => Some(Int8),
+        test_coercion_binary_rule!(Int8, Int8, Operator::Plus, Int8);
+
         Ok(())
     }
 
diff --git a/datafusion/optimizer/src/single_distinct_to_groupby.rs 
b/datafusion/optimizer/src/single_distinct_to_groupby.rs
index 191377fc27..7337d2ffce 100644
--- a/datafusion/optimizer/src/single_distinct_to_groupby.rs
+++ b/datafusion/optimizer/src/single_distinct_to_groupby.rs
@@ -410,7 +410,7 @@ mod tests {
 
         let expected = "Projection: count(alias1) AS count(DISTINCT Int32(2) * 
test.b) [count(DISTINCT Int32(2) * test.b):Int64]\
                             \n  Aggregate: groupBy=[[]], 
aggr=[[count(alias1)]] [count(alias1):Int64]\
-                            \n    Aggregate: groupBy=[[Int32(2) * test.b AS 
alias1]], aggr=[[]] [alias1:Int32]\
+                            \n    Aggregate: groupBy=[[Int32(2) * test.b AS 
alias1]], aggr=[[]] [alias1:Int64]\
                             \n      TableScan: test [a:UInt32, b:UInt32, 
c:UInt32]";
 
         assert_optimized_plan_equal(plan, expected)
@@ -497,9 +497,9 @@ mod tests {
             .build()?;
 
         // Should work
-        let expected = "Projection: group_alias_0 AS test.a + Int32(1), 
count(alias1) AS count(DISTINCT test.c) [test.a + Int32(1):Int32, 
count(DISTINCT test.c):Int64]\
-                            \n  Aggregate: groupBy=[[group_alias_0]], 
aggr=[[count(alias1)]] [group_alias_0:Int32, count(alias1):Int64]\
-                            \n    Aggregate: groupBy=[[test.a + Int32(1) AS 
group_alias_0, test.c AS alias1]], aggr=[[]] [group_alias_0:Int32, 
alias1:UInt32]\
+        let expected = "Projection: group_alias_0 AS test.a + Int32(1), 
count(alias1) AS count(DISTINCT test.c) [test.a + Int32(1):Int64, 
count(DISTINCT test.c):Int64]\
+                            \n  Aggregate: groupBy=[[group_alias_0]], 
aggr=[[count(alias1)]] [group_alias_0:Int64, count(alias1):Int64]\
+                            \n    Aggregate: groupBy=[[test.a + Int32(1) AS 
group_alias_0, test.c AS alias1]], aggr=[[]] [group_alias_0:Int64, 
alias1:UInt32]\
                             \n      TableScan: test [a:UInt32, b:UInt32, 
c:UInt32]";
 
         assert_optimized_plan_equal(plan, expected)
diff --git a/datafusion/optimizer/tests/optimizer_integration.rs 
b/datafusion/optimizer/tests/optimizer_integration.rs
index 5e66c7ec03..13d6b8de79 100644
--- a/datafusion/optimizer/tests/optimizer_integration.rs
+++ b/datafusion/optimizer/tests/optimizer_integration.rs
@@ -267,8 +267,8 @@ fn push_down_filter_groupby_expr_contains_alias() {
     let sql = "SELECT * FROM (SELECT (col_int32 + col_uint32) AS c, count(*) 
FROM test GROUP BY 1) where c > 3";
     let plan = test_sql(sql).unwrap();
     let expected = "Projection: test.col_int32 + test.col_uint32 AS c, 
count(Int64(1)) AS count(*)\
-    \n  Aggregate: groupBy=[[test.col_int32 + CAST(test.col_uint32 AS 
Int32)]], aggr=[[count(Int64(1))]]\
-    \n    Filter: test.col_int32 + CAST(test.col_uint32 AS Int32) > Int32(3)\
+    \n  Aggregate: groupBy=[[CAST(test.col_int32 AS Int64) + 
CAST(test.col_uint32 AS Int64)]], aggr=[[count(Int64(1))]]\
+    \n    Filter: CAST(test.col_int32 AS Int64) + CAST(test.col_uint32 AS 
Int64) > Int64(3)\
     \n      TableScan: test projection=[col_int32, col_uint32]";
     assert_eq!(expected, format!("{plan}"));
 }
diff --git a/datafusion/physical-expr/src/expressions/binary.rs 
b/datafusion/physical-expr/src/expressions/binary.rs
index f2c68729c5..f21d3e7652 100644
--- a/datafusion/physical-expr/src/expressions/binary.rs
+++ b/datafusion/physical-expr/src/expressions/binary.rs
@@ -1025,9 +1025,9 @@ mod tests {
             DataType::UInt32,
             vec![1u32, 2u32],
             Operator::Plus,
-            Int32Array,
-            DataType::Int32,
-            [2i32, 4i32],
+            Int64Array,
+            DataType::Int64,
+            [2i64, 4i64],
         );
         test_coercion!(
             Int32Array,
diff --git a/datafusion/sqllogictest/test_files/math.slt 
b/datafusion/sqllogictest/test_files/math.slt
index a49e0a6421..e206aa16b8 100644
--- a/datafusion/sqllogictest/test_files/math.slt
+++ b/datafusion/sqllogictest/test_files/math.slt
@@ -164,22 +164,22 @@ INSERT into test_nullable_integer values(127, 32767, 
2147483647, 922337203685477
 ----
 1
 
-query IIIIIIII
+query IIIIIIIR
 SELECT c1*0, c2*0, c3*0, c4*0, c5*0, c6*0, c7*0, c8*0 FROM 
test_nullable_integer where dataset = 'nulls'
 ----
 NULL NULL NULL NULL NULL NULL NULL NULL
 
-query IIIIIIII
+query IIIIIIIR
 SELECT c1/0, c2/0, c3/0, c4/0, c5/0, c6/0, c7/0, c8/0 FROM 
test_nullable_integer where dataset = 'nulls'
 ----
 NULL NULL NULL NULL NULL NULL NULL NULL
 
-query IIIIIIII
+query IIIIIIIR
 SELECT c1%0, c2%0, c3%0, c4%0, c5%0, c6%0, c7%0, c8%0 FROM 
test_nullable_integer where dataset = 'nulls'
 ----
 NULL NULL NULL NULL NULL NULL NULL NULL
 
-query IIIIIIII rowsort
+query IIIIIIIR rowsort
 select c1*0, c2*0, c3*0, c4*0, c5*0, c6*0, c7*0, c8*0 from 
test_nullable_integer where dataset != 'maxs'
 ----
 0 0 0 0 0 0 0 0
@@ -300,7 +300,7 @@ INSERT INTO test_non_nullable_integer VALUES(1, 1, 1, 1, 1, 
1, 1, 1)
 ----
 1
 
-query IIIIIIII rowsort
+query IIIIIIIR rowsort
 select c1*0, c2*0, c3*0, c4*0, c5*0, c6*0, c7*0, c8*0 from 
test_non_nullable_integer
 ----
 0 0 0 0 0 0 0 0
diff --git a/datafusion/sqllogictest/test_files/operator.slt 
b/datafusion/sqllogictest/test_files/operator.slt
index 8fd0a7a610..a651eda996 100644
--- a/datafusion/sqllogictest/test_files/operator.slt
+++ b/datafusion/sqllogictest/test_files/operator.slt
@@ -70,7 +70,7 @@ select
     arrow_typeof(decimal + 2)
 from numeric_types;
 ----
-Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Float32 Float64 Decimal128(23, 
2)
+Int64 Int64 Int64 Int64 Int64 Int64 Int64 Decimal128(21, 0) Float32 Float64 
Decimal128(23, 2)
 
 # Plus with literal decimal
 query TTTTTTTTTTT
@@ -127,7 +127,7 @@ select
     arrow_typeof(decimal - 2)
 from numeric_types;
 ----
-Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Float32 Float64 Decimal128(23, 
2)
+Int64 Int64 Int64 Int64 Int64 Int64 Int64 Decimal128(21, 0) Float32 Float64 
Decimal128(23, 2)
 
 # Minus with literal decimal
 query TTTTTTTTTTT
@@ -184,7 +184,7 @@ select
     arrow_typeof(decimal * 2)
 from numeric_types;
 ----
-Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Float32 Float64 Decimal128(26, 
2)
+Int64 Int64 Int64 Int64 Int64 Int64 Int64 Decimal128(38, 0) Float32 Float64 
Decimal128(26, 2)
 
 # Multiply with literal decimal
 query TTTTTTTTTTT
@@ -242,7 +242,7 @@ select
     arrow_typeof(decimal / 2)
 from numeric_types;
 ----
-Int64 Int64 Int64 Int64 Int64 Int64 Int64 Int64 Float32 Float64 Decimal128(9, 
6)
+Int64 Int64 Int64 Int64 Int64 Int64 Int64 Decimal128(24, 4) Float32 Float64 
Decimal128(9, 6)
 
 # Divide with literal decimal
 query TTTTTTTTTTT
diff --git a/datafusion/sqllogictest/test_files/window.slt 
b/datafusion/sqllogictest/test_files/window.slt
index fd623b67fe..76e3751e4b 100644
--- a/datafusion/sqllogictest/test_files/window.slt
+++ b/datafusion/sqllogictest/test_files/window.slt
@@ -2448,15 +2448,15 @@ EXPLAIN SELECT c5, c9, rn1 FROM (SELECT c5, c9,
        LIMIT 5
 ----
 logical_plan
-01)Sort: rn1 ASC NULLS LAST, CAST(aggregate_test_100.c9 AS Int32) + 
aggregate_test_100.c5 DESC NULLS FIRST, fetch=5
+01)Sort: rn1 ASC NULLS LAST, CAST(aggregate_test_100.c9 AS Decimal128(20, 0)) 
+ CAST(aggregate_test_100.c5 AS Decimal128(20, 0)) DESC NULLS FIRST, fetch=5
 02)--Projection: aggregate_test_100.c5, aggregate_test_100.c9, row_number() 
ORDER BY [aggregate_test_100.c9 + aggregate_test_100.c5 DESC NULLS FIRST] RANGE 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW AS rn1
-03)----WindowAggr: windowExpr=[[row_number() ORDER BY 
[CAST(aggregate_test_100.c9 AS Int32) + aggregate_test_100.c5 DESC NULLS FIRST] 
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW AS row_number() ORDER BY 
[aggregate_test_100.c9 + aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN 
UNBOUNDED PRECEDING AND CURRENT ROW]]
+03)----WindowAggr: windowExpr=[[row_number() ORDER BY 
[CAST(aggregate_test_100.c9 AS Decimal128(20, 0)) + CAST(aggregate_test_100.c5 
AS Decimal128(20, 0)) DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW AS row_number() ORDER BY [aggregate_test_100.c9 + 
aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW]]
 04)------TableScan: aggregate_test_100 projection=[c5, c9]
 physical_plan
 01)ProjectionExec: expr=[c5@0 as c5, c9@1 as c9, row_number() ORDER BY 
[aggregate_test_100.c9 + aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN 
UNBOUNDED PRECEDING AND CURRENT ROW@2 as rn1]
 02)--GlobalLimitExec: skip=0, fetch=5
-03)----BoundedWindowAggExec: wdw=[row_number() ORDER BY [aggregate_test_100.c9 
+ aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW: Ok(Field { name: "row_number() ORDER BY [aggregate_test_100.c9 + 
aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW", data_type: UInt64, nullable: false, dict_id: 0, dict_is_ordered: 
false, metadata: {} }), frame: WindowFrame { units: Range, start_bound: 
Preceding(Int32(NULL)), en [...]
-04)------SortExec: expr=[CAST(c9@1 AS Int32) + c5@0 DESC], 
preserve_partitioning=[false]
+03)----BoundedWindowAggExec: wdw=[row_number() ORDER BY [aggregate_test_100.c9 
+ aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW: Ok(Field { name: "row_number() ORDER BY [aggregate_test_100.c9 + 
aggregate_test_100.c5 DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND 
CURRENT ROW", data_type: UInt64, nullable: false, dict_id: 0, dict_is_ordered: 
false, metadata: {} }), frame: WindowFrame { units: Range, start_bound: 
Preceding(Decimal128(None, [...]
+04)------SortExec: expr=[CAST(c9@1 AS Decimal128(20, 0)) + CAST(c5@0 AS 
Decimal128(20, 0)) DESC], preserve_partitioning=[false]
 05)--------DataSourceExec: file_groups={1 group: 
[[WORKSPACE_ROOT/testing/data/csv/aggregate_test_100.csv]]}, projection=[c5, 
c9], file_type=csv, has_header=true
 
 # Ordering equivalence should be preserved during cast expression


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to