Skip to content

Commit

Permalink
fix: inconsistent behaviors when dividing floating numbers by zero (#…
Browse files Browse the repository at this point in the history
…7503)

* fix: inconsistent behaviors when dividing floating numbers by zero

* Add tests from review
  • Loading branch information
jonahgao authored Sep 8, 2023
1 parent c7a93fc commit 495c25f
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -705,12 +705,16 @@ impl<'a, S: SimplifyInfo> TreeNodeRewriter for Simplifier<'a, S> {
op: Divide,
right,
}) if is_null(&right) => *right,
// A / 0 -> DivideByZero Error
// A / 0 -> DivideByZero Error if A is not null and not floating
// (float / 0 -> inf | -inf | NAN)
Expr::BinaryExpr(BinaryExpr {
left,
op: Divide,
right,
}) if !info.nullable(&left)? && is_zero(&right) => {
}) if !info.nullable(&left)?
&& !info.get_data_type(&left)?.is_floating()
&& is_zero(&right) =>
{
return Err(DataFusionError::ArrowError(ArrowError::DivideByZero));
}

Expand Down
178 changes: 178 additions & 0 deletions datafusion/sqllogictest/test_files/math.slt
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,181 @@ query BBBB
SELECT iszero(1.0), iszero(0.0), iszero(-0.0), iszero(NULL)
----
false true true NULL


statement ok
CREATE TABLE test_divide_zero_integer_nullable(
c1 TINYINT,
c2 SMALLINT,
c3 INT,
c4 BIGINT,
c5 TINYINT UNSIGNED,
c6 SMALLINT UNSIGNED,
c7 INT UNSIGNED,
c8 BIGINT UNSIGNED,
)
AS VALUES
(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

query IIIIIIII
SELECT c1/0, c2/0, c3/0, c4/0, c5/0, c6/0, c7/0, c8/0 FROM test_divide_zero_integer_nullable
----
NULL NULL NULL NULL NULL NULL NULL NULL

query IIIIIIII
INSERT INTO test_divide_zero_integer_nullable VALUES(1, 1, 1, 1, 1, 1, 1, 1)
----
1

query error DataFusion error: Arrow error: Divide by zero error
SELECT c1/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c2/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c3/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c4/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c5/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c6/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c7/0 FROM test_divide_zero_integer_nullable

query error DataFusion error: Arrow error: Divide by zero error
SELECT c8/0 FROM test_divide_zero_integer_nullable

statement ok
drop table test_divide_zero_integer_nullable


statement ok
CREATE TABLE test_divide_zero_integer_non_nullable(
c1 TINYINT NOT NULL,
c2 SMALLINT NOT NULL,
c3 INT NOT NULL,
c4 BIGINT NOT NULL,
c5 TINYINT UNSIGNED NOT NULL,
c6 SMALLINT UNSIGNED NOT NULL,
c7 INT UNSIGNED NOT NULL,
c8 BIGINT UNSIGNED NOT NULL,
);

query IIIIIIII
INSERT INTO test_divide_zero_integer_non_nullable VALUES(1, 1, 1, 1, 1, 1, 1, 1)
----
1

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c1/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c2/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c3/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c4/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c5/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c6/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c7/0 FROM test_divide_zero_integer_non_nullable

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c8/0 FROM test_divide_zero_integer_non_nullable

statement ok
drop table test_divide_zero_integer_non_nullable


statement ok
CREATE TABLE test_divide_zero_float_nullable(
c1 float,
c2 double,
) AS VALUES
(-1.0, -1.0),
(1.0, 1.0),
(NULL, NULL),
(0., 0.),
('NaN'::double, 'NaN'::double);

query RR rowsort
SELECT c1/0, c2/0 FROM test_divide_zero_float_nullable
----
-Infinity -Infinity
Infinity Infinity
NULL NULL
NaN NaN
NaN NaN

statement ok
drop table test_divide_zero_float_nullable


statement ok
CREATE TABLE test_divide_zero_float_non_nullable(
c1 float NOT NULL,
c2 double NOT NULL,
);

query RR
INSERT INTO test_divide_zero_float_non_nullable VALUES
(-1.0, -1.0),
(1.0, 1.0),
(0., 0.),
('NaN'::double, 'NaN'::double)
----
4

query RR rowsort
SELECT c1/0, c2/0 FROM test_divide_zero_float_non_nullable
----
-Infinity -Infinity
Infinity Infinity
NaN NaN
NaN NaN

statement ok
drop table test_divide_zero_float_non_nullable


statement ok
CREATE TABLE test_divide_zero_decimal_nullable(c1 DECIMAL(9, 2)) AS VALUES (1), (NULL);

query R rowsort
SELECT c1/0 FROM test_divide_zero_decimal_nullable WHERE c1 IS NULL;
----
NULL

query error DataFusion error: Arrow error: Divide by zero error
SELECT c1/0 FROM test_divide_zero_decimal_nullable WHERE c1 IS NOT NULL;

statement ok
drop table test_divide_zero_decimal_nullable


statement ok
CREATE TABLE test_divide_zero_decimal_non_nullable(c1 DECIMAL(9,2) NOT NULL);

query R
INSERT INTO test_divide_zero_decimal_non_nullable VALUES(1)
----
1

query error DataFusion error: Optimizer rule 'simplify_expressions' failed\ncaused by\nArrow error: Divide by zero error
SELECT c1/0 FROM test_divide_zero_decimal_non_nullable

statement ok
drop table test_divide_zero_decimal_non_nullable

0 comments on commit 495c25f

Please sign in to comment.