Skip to content

Commit 056e2d0

Browse files
committed
Fix Float and Decimal coercion
Before the change, Float* and Decimal* would coerce to a decimal type. However, decimal cannot store all the float values: different range, NaN, and infinity. Coercing to floating point is more desirable and also what other systems typically do.
1 parent 774d3cb commit 056e2d0

File tree

4 files changed

+33
-18
lines changed

4 files changed

+33
-18
lines changed

datafusion/core/tests/parquet/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,13 @@ impl TestOutput {
184184
/// and the appropriate scenario
185185
impl ContextWithParquet {
186186
async fn new(scenario: Scenario, unit: Unit) -> Self {
187-
Self::with_config(scenario, unit, SessionConfig::new()).await
187+
let mut session_config = SessionConfig::new();
188+
// TODO (https://github.com/apache/datafusion/issues/12817) once this is the default behavior, remove from here
189+
session_config
190+
.options_mut()
191+
.sql_parser
192+
.parse_float_as_decimal = true;
193+
Self::with_config(scenario, unit, session_config).await
188194
}
189195

190196
async fn with_config(

datafusion/expr-common/src/type_coercion/binary.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -928,9 +928,6 @@ fn coerce_numeric_type_to_decimal(numeric_type: &DataType) -> Option<DataType> {
928928
Int16 | UInt16 => Some(Decimal128(5, 0)),
929929
Int32 | UInt32 => Some(Decimal128(10, 0)),
930930
Int64 | UInt64 => Some(Decimal128(20, 0)),
931-
// TODO if we convert the floating-point data to the decimal type, it maybe overflow.
932-
Float32 => Some(Decimal128(14, 7)),
933-
Float64 => Some(Decimal128(30, 15)),
934931
_ => None,
935932
}
936933
}
@@ -946,9 +943,6 @@ fn coerce_numeric_type_to_decimal256(numeric_type: &DataType) -> Option<DataType
946943
Int16 | UInt16 => Some(Decimal256(5, 0)),
947944
Int32 | UInt32 => Some(Decimal256(10, 0)),
948945
Int64 | UInt64 => Some(Decimal256(20, 0)),
949-
// TODO if we convert the floating-point data to the decimal type, it maybe overflow.
950-
Float32 => Some(Decimal256(14, 7)),
951-
Float64 => Some(Decimal256(30, 15)),
952946
_ => None,
953947
}
954948
}
@@ -1494,8 +1488,8 @@ mod tests {
14941488
DataType::Decimal128(20, 3),
14951489
DataType::Decimal128(20, 3),
14961490
DataType::Decimal128(23, 3),
1497-
DataType::Decimal128(24, 7),
1498-
DataType::Decimal128(32, 15),
1491+
DataType::Float32,
1492+
DataType::Float64,
14991493
DataType::Decimal128(38, 10),
15001494
DataType::Decimal128(25, 8),
15011495
DataType::Decimal128(20, 3),
@@ -1541,14 +1535,8 @@ mod tests {
15411535
coerce_numeric_type_to_decimal(&DataType::Int64).unwrap(),
15421536
DataType::Decimal128(20, 0)
15431537
);
1544-
assert_eq!(
1545-
coerce_numeric_type_to_decimal(&DataType::Float32).unwrap(),
1546-
DataType::Decimal128(14, 7)
1547-
);
1548-
assert_eq!(
1549-
coerce_numeric_type_to_decimal(&DataType::Float64).unwrap(),
1550-
DataType::Decimal128(30, 15)
1551-
);
1538+
assert_eq!(coerce_numeric_type_to_decimal(&DataType::Float32), None);
1539+
assert_eq!(coerce_numeric_type_to_decimal(&DataType::Float64), None);
15521540
}
15531541

15541542
#[test]
@@ -2013,7 +2001,7 @@ mod tests {
20132001
DataType::Float64,
20142002
DataType::Decimal128(10, 3),
20152003
Operator::Gt,
2016-
DataType::Decimal128(30, 15)
2004+
DataType::Float64
20172005
);
20182006
test_coercion_binary_rule!(
20192007
DataType::Int64,

datafusion/sqllogictest/test_files/math.slt

+6
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,9 @@ select FACTORIAL(350943270);
694694

695695
statement ok
696696
drop table signed_integers
697+
698+
# Should not fail. The operands should coerce to float
699+
query B
700+
SELECT '1'::decimal(10,0) = '1e40'::double;
701+
----
702+
false

datafusion/sqllogictest/test_files/union.slt

+15
Original file line numberDiff line numberDiff line change
@@ -836,3 +836,18 @@ physical_plan
836836
# Clean up after the test
837837
statement ok
838838
drop table aggregate_test_100;
839+
840+
query T
841+
SELECT DISTINCT arrow_typeof(a) FROM (SELECT '1'::float UNION ALL SELECT '1'::decimal(10)) t(a)
842+
----
843+
Float32
844+
845+
query T
846+
SELECT DISTINCT arrow_typeof(a) FROM (SELECT '1'::decimal(10) UNION ALL SELECT '1'::float ) t(a)
847+
----
848+
Float32
849+
850+
query T
851+
SELECT DISTINCT arrow_typeof(a) FROM (SELECT '1'::decimal(10) UNION ALL SELECT '1'::double) t(a)
852+
----
853+
Float64

0 commit comments

Comments
 (0)