Skip to content
/ server Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions mysql-test/main/func_math.result
Original file line number Diff line number Diff line change
Expand Up @@ -3739,3 +3739,99 @@ cast(1 as unsigned) - cast(2 as unsigned)
-1
set sql_mode=default;
# End of 10.5 tests
#
# MDEV-38670 Minus string is converted to -0
#
# Testing arithmetic operations with signed zero
SELECT -0.0 + 0.0;
-0.0 + 0.0
0.0
SELECT 0.0 + -0.0;
0.0 + -0.0
0.0
SELECT -0.0 + -0.0;
-0.0 + -0.0
0.0
SELECT -0.0 - 0.0;
-0.0 - 0.0
0.0
SELECT 0.0 - '';
0.0 - ''
0
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: ''
SELECT -0.0;
-0.0
0.0
SELECT 0.0 * -1.0;
0.0 * -1.0
0.00
SELECT 0e0*-1e0;
0e0*-1e0
0
SELECT -'';
-''
0
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: ''
SELECT ABS(-0.0);
ABS(-0.0)
0.0
SELECT -0.0 % 1.0;
-0.0 % 1.0
0.0
# Testing comparison functions with signed zero
SELECT CASE WHEN -0.0=0.0 THEN 1.0 ELSE 0.0 END;
CASE WHEN -0.0=0.0 THEN 1.0 ELSE 0.0 END
1.0
SELECT CASE WHEN -''=0.0 THEN 1.0 ELSE 0.0 END;
CASE WHEN -''=0.0 THEN 1.0 ELSE 0.0 END
1.0
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: ''
SELECT CASE WHEN 0e0*-1e0=0.0 THEN 1.0 ELSE 0.0 END;
CASE WHEN 0e0*-1e0=0.0 THEN 1.0 ELSE 0.0 END
1.0
# Testing with table data
CREATE TABLE t1 (a DOUBLE, b DOUBLE);
INSERT INTO t1 VALUES
(0.0, 1.0),
(-0.0, 1.0),
(1.0, 0.0),
(1.0, -0.0),
(0.0, 0.0),
(-0.0, -0.0);
SELECT a, b, a + b AS sum_ab, a - b AS diff_ab, a * b AS mul_ab FROM t1;
a b sum_ab diff_ab mul_ab
0 1 1 -1 0
0 1 1 -1 0
1 0 1 1 0
1 0 1 1 0
0 0 0 0 0
0 0 0 0 0
SELECT a, b, IFNULL(a, b) AS ifnull_ab, NULLIF(a, b) AS nullif_ab FROM t1;
a b ifnull_ab nullif_ab
0 1 0 0
0 1 0 0
1 0 1 1
1 0 1 1
0 0 0 NULL
0 0 0 NULL
SELECT a, b, CASE WHEN a > 0 THEN a ELSE b END AS case_ab FROM t1;
a b case_ab
0 1 1
0 1 1
1 0 1
1 0 1
0 0 0
0 0 0
SELECT a, b, COALESCE(a, b) AS coalesce_ab FROM t1;
a b coalesce_ab
0 1 0
0 1 0
1 0 1
1 0 1
0 0 0
0 0 0
DROP TABLE t1;
# End of 13 tests
54 changes: 54 additions & 0 deletions mysql-test/main/func_math.test
Original file line number Diff line number Diff line change
Expand Up @@ -1998,3 +1998,57 @@ select cast(1 as unsigned) - cast(2 as unsigned);
set sql_mode=default;

--echo # End of 10.5 tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is customary to end a test file with a version test end echo command. Please add one for the target version: 13 in your case I believe, unless the final reviewer requests otherwise.


--echo #
--echo # MDEV-38670 Minus string is converted to -0
--echo #

--source include/have_innodb.inc

# Test arithmetic operations
--echo # Testing arithmetic operations with signed zero

SELECT -0.0 + 0.0;
SELECT 0.0 + -0.0;
SELECT -0.0 + -0.0;

SELECT -0.0 - 0.0;
SELECT 0.0 - '';

SELECT -0.0;
SELECT 0.0 * -1.0;
SELECT 0e0*-1e0;
SELECT -'';


SELECT ABS(-0.0);

SELECT -0.0 % 1.0;

# Test comparison functions
--echo # Testing comparison functions with signed zero

SELECT CASE WHEN -0.0=0.0 THEN 1.0 ELSE 0.0 END;
SELECT CASE WHEN -''=0.0 THEN 1.0 ELSE 0.0 END;
SELECT CASE WHEN 0e0*-1e0=0.0 THEN 1.0 ELSE 0.0 END;


# Test with table data
--echo # Testing with table data

CREATE TABLE t1 (a DOUBLE, b DOUBLE);
INSERT INTO t1 VALUES
(0.0, 1.0),
(-0.0, 1.0),
(1.0, 0.0),
(1.0, -0.0),
(0.0, 0.0),
(-0.0, -0.0);

SELECT a, b, a + b AS sum_ab, a - b AS diff_ab, a * b AS mul_ab FROM t1;
SELECT a, b, IFNULL(a, b) AS ifnull_ab, NULLIF(a, b) AS nullif_ab FROM t1;
SELECT a, b, CASE WHEN a > 0 THEN a ELSE b END AS case_ab FROM t1;
SELECT a, b, COALESCE(a, b) AS coalesce_ab FROM t1;

DROP TABLE t1;
--echo # End of 13 tests
8 changes: 4 additions & 4 deletions sql/item_cmpfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2496,7 +2496,7 @@ Item_func_ifnull::real_op()
value= args[1]->val_real();
if ((null_value=args[1]->null_value))
return 0.0;
return value;
return normalize_signed_zero(value);
}

longlong
Expand Down Expand Up @@ -3036,7 +3036,7 @@ Item_func_nullif::real_op()
}
value= args[2]->val_real();
null_value= args[2]->null_value;
return value;
return normalize_signed_zero(value);
}

longlong
Expand Down Expand Up @@ -3250,7 +3250,7 @@ double Item_func_case::real_op()
}
res= item->val_real();
null_value=item->null_value;
return res;
return normalize_signed_zero(res);
}


Expand Down Expand Up @@ -3649,7 +3649,7 @@ double Item_func_coalesce::real_op()
{
double res= args[i]->val_real();
if (!args[i]->null_value)
return res;
return normalize_signed_zero(res);
}
null_value=1;
return 0;
Expand Down
20 changes: 10 additions & 10 deletions sql/item_func.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ double Item_func_plus::real_op()
double value= args[0]->val_real() + args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0;
return check_float_overflow(value);
return normalize_signed_zero(check_float_overflow(value));
}

#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
Expand Down Expand Up @@ -1338,7 +1338,7 @@ double Item_func_minus::real_op()
double value= args[0]->val_real() - args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0;
return check_float_overflow(value);
return normalize_signed_zero(check_float_overflow(value));
}


Expand Down Expand Up @@ -1440,7 +1440,7 @@ double Item_func_mul::real_op()
double value= args[0]->val_real() * args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0;
return check_float_overflow(value);
return normalize_signed_zero(check_float_overflow(value));
}


Expand Down Expand Up @@ -1522,7 +1522,7 @@ double Item_func_div::real_op()
signal_divide_by_null();
return 0.0;
}
return check_float_overflow(value/val2);
return normalize_signed_zero(check_float_overflow(value/val2));
}


Expand Down Expand Up @@ -1712,7 +1712,7 @@ double Item_func_mod::real_op()
signal_divide_by_null();
return 0.0;
}
return fmod(value,val2);
return normalize_signed_zero(fmod(value,val2));
}


Expand Down Expand Up @@ -1825,7 +1825,7 @@ double Item_func_neg::real_op()
{
double value= args[0]->val_real();
null_value= args[0]->null_value;
return -value;
return normalize_signed_zero(-value);
}


Expand Down Expand Up @@ -1931,7 +1931,7 @@ double Item_func_abs::real_op()
{
double value= args[0]->val_real();
null_value= args[0]->null_value;
return fabs(value);
return normalize_signed_zero(fabs(value));
}


Expand Down Expand Up @@ -2409,7 +2409,7 @@ double Item_func_ceiling::real_op()
*/
volatile double value= args[0]->val_real();
null_value= args[0]->null_value;
return ceil(value);
return normalize_signed_zero(ceil(value));
}


Expand Down Expand Up @@ -2473,7 +2473,7 @@ double Item_func_floor::real_op()
*/
volatile double value= args[0]->val_real();
null_value= args[0]->null_value;
return floor(value);
return normalize_signed_zero(floor(value));
}


Expand Down Expand Up @@ -2741,7 +2741,7 @@ double Item_func_round::real_op()
{
longlong dec= args[1]->val_int();
if (!(null_value= args[1]->null_value))
return my_double_round(value, dec, args[1]->unsigned_flag, truncate);
return normalize_signed_zero(my_double_round(value, dec, args[1]->unsigned_flag, truncate));
}
return 0.0;
}
Expand Down
5 changes: 5 additions & 0 deletions sql/item_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ class Item_func :public Item_func_or_sum
print(&str, QT_NO_DATA_EXPANSION);
my_error(ER_DATA_OUT_OF_RANGE, MYF(0), type_name, str.c_ptr_safe());
}
inline double normalize_signed_zero(double value)
{
return value == 0.0 ? 0.0 : value; // Converts -0.0 to +0.0
}
inline double raise_float_overflow()
{
raise_numeric_overflow("DOUBLE");
Expand All @@ -308,6 +312,7 @@ class Item_func :public Item_func_or_sum
{
return std::isfinite(value) ? value : raise_float_overflow();
}

/**
Throw an error if the input BIGINT value represented by the
(longlong value, bool unsigned flag) pair cannot be returned by the
Expand Down