Skip to content
/ server Public

MDEV-38670 Unary minus on empty string returns -0#4632

Open
3titoo wants to merge 1 commit intoMariaDB:10.6from
3titoo:MDEV-38670
Open

MDEV-38670 Unary minus on empty string returns -0#4632
3titoo wants to merge 1 commit intoMariaDB:10.6from
3titoo:MDEV-38670

Conversation

@3titoo
Copy link

@3titoo 3titoo commented Feb 7, 2026

Normalize -0.0 to +0.0 in Item_func_neg::real_op() to match binary subtraction behavior. Add a test case in type_newdecimal.

@CLAassistant
Copy link

CLAassistant commented Feb 7, 2026

CLA assistant check
All committers have signed the CLA.

@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Feb 9, 2026
@gkodinov gkodinov self-assigned this Feb 12, 2026
Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

This is a preliminary review.
Thank you for working on this!
You have pinpointed the problem correctly. But it needs more work to arrive at a complete solution, adequate testing and a solid commit message.

@3titoo 3titoo force-pushed the MDEV-38670 branch 2 times, most recently from 8bd49fe to f1bf275 Compare February 15, 2026 04:24
@3titoo
Copy link
Author

3titoo commented Feb 15, 2026

key changes:

  • I have added a utility in item_func.h (normalize_signed_zero(..))
  • updated every real_op function in Item_func.cc to return normalize_signed_zero(res) which prevent -0.0
  • updated every real_op functions in item_cmpfunc.cc to return normalize_signed_zero(res)
  • added test cases to test every function has been updated

The behavior before is like :
Pasted image

The behavior now is like that:

image

@3titoo 3titoo requested a review from gkodinov February 15, 2026 13:56
Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

Thanks for willing to make this a good and well-rounded database feature. Some further review comments below.

@3titoo
Copy link
Author

3titoo commented Feb 19, 2026

Added classification and normalization criteria to the JIRA.
MDEV-38670

@3titoo
Copy link
Author

3titoo commented Feb 19, 2026

i have edited Item *Item_float::neg(THD *thd)
because these tests:

CREATE TABLE t_signed_zero (a DOUBLE);
INSERT INTO t_signed_zero VALUES (-0e1),(0e1);
SELECT COUNT(DISTINCT a) FROM t_signed_zero;
SELECT a,COUNT(*) FROM t_signed_zero GROUP BY a;

It prints -0 and 0 as distinct numbers while they are equal
now after edits, it prints only 0 as a distinct number

Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

Thanks for working on this. One small nitpick item below.
Please wait for the final review.

sql/item_func.h Outdated
@@ -285,6 +285,12 @@ 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)
Copy link
Member

Choose a reason for hiding this comment

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

Do you really need to define this twice? item_func.cc already includes item.h (indirectly, but still).

@gkodinov
Copy link
Member

Forgot to mention: please re-base on 10.6. This is safe to do and is a bug fix. So let's please assign the proper target version.

@gkodinov gkodinov requested a review from abarkov February 19, 2026 10:14
@vuvova
Copy link
Member

vuvova commented Feb 19, 2026

Wouldn't it be enough to fix it in dtoa? So that it wouldn't print - before 0 ?

@3titoo
Copy link
Author

3titoo commented Feb 19, 2026

Wouldn't it be enough to fix it in dtoa? So that it wouldn't print - before 0?

Fixing this in dtoa would only hide the sign during printing.

The problem is that the server internally treats -0 and +0 differently in some execution paths (e.g., grouping), even though they are numerically equal.
So the fix is applied where values are produced (unary minus, arithmetic functions) to canonicalize the value itself

@abarkov
Copy link
Contributor

abarkov commented Feb 19, 2026

Wouldn't it be enough to fix it in dtoa? So that it wouldn't print - before 0?

Fixing this in dtoa would only hide the sign during printing.

The problem is that the server internally treats -0 and +0 differently in some execution paths (e.g., grouping), even though they are numerically equal. So the fix is applied where values are produced (unary minus, arithmetic functions) to canonicalize the value itself

We discussed this issue with the team and think that double values of 0.0 and -0.0 compare as equal. Your patch also relies on this fact by the way:

return value == 0.0 ? 0.0 : value;

Can you please give examples when grouping or some other execution paths give wrong results?

@3titoo
Copy link
Author

3titoo commented Feb 19, 2026

Wouldn't it be enough to fix it in dtoa? So that it wouldn't print - before 0?

Fixing this in dtoa would only hide the sign during printing.
The problem is that the server internally treats -0 and +0 differently in some execution paths (e.g., grouping), even though they are numerically equal. So the fix is applied where values are produced (unary minus, arithmetic functions) to canonicalize the value itself

We discussed this issue with the team and think that double values of 0.0 and -0.0 compare as equal. Your patch also relies on this fact by the way:

return value == 0.0 ? 0.0 : value;

Can you please give examples when grouping or some other execution paths give wrong results?

image

This should print 1 when they are the same value, and group by should print only 0, not 0 and -0

But now, after edits:

image

@3titoo 3titoo changed the base branch from main to 10.6 February 19, 2026 13:12
Normalize -0.0 to +0.0 in Item_func_neg::real_op() to match
binary subtraction behavior. Add test case in type_newdecimal.

add result for tests

fix tests

Revert whitespace changes in type_newdecimal.result

Revert whitespace changes in type_newdecimal.test

normalize all real_op functions in item_func.cc and item_cmpfunc.cc to convert -0.0 to 0.0

normalize all real_op functions in item_func.cc and item_cmpfunc.cc to convert -0.0 to 0.0

normalize all real_op functions in item_func.cc and item_cmpfunc.cc to convert -0.0 to 0.0

normalize all real_op functions in item_func.cc and item_cmpfunc.cc to convert -0.0 to 0.0

normalize -0.0 to 0.0

normalize -0.0 to 0.0

Revert unintended changes in item_func.h

Revert unintended changes in item_func.h (10.6)
Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

LGTM from a preliminary review standpoint. Please take the alternative approach discussion with the final reviewer (Alexander).

@3titoo
Copy link
Author

3titoo commented Feb 19, 2026

LGTM from a preliminary review standpoint. Please take the alternative approach discussion with the final reviewer (Alexander).

Thanks for the review!

@abarkov — since this involves choosing the overall approach for handling signed zero,
would you prefer normalizing it at the producer level (real_op return sites) or handling it elsewhere in the engine?

I followed approach 2 for consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

6 participants