[MDEV-25752] ADD_MONTHS with a non-integer argument gives a different result on Oracle compared to MariaDB Created: 2021-05-21  Updated: 2023-12-21  Resolved: 2023-12-21

Status: Closed
Project: MariaDB Server
Component/s: Server
Affects Version/s: 10.6.1
Fix Version/s: 10.6.1

Type: Bug Priority: Minor
Reporter: Ian Gilfillan Assignee: Dave Gosselin
Resolution: Fixed Votes: 0
Labels: Compatibility, oracle

Issue Links:
Relates
relates to MDEV-20025 ADD_MONTHS() Oracle function Closed

 Description   

MariaDB:

SELECT ADD_MONTHS('1994-07-07', 2);
+-----------------------------+
| ADD_MONTHS('1994-07-07', 2) |
+-----------------------------+
| 1994-09-07                  |
+-----------------------------+
 
SELECT ADD_MONTHS('1994-07-07', 2.6);
+-------------------------------+
| ADD_MONTHS('1994-07-07', 2.6) |
+-------------------------------+
| 1994-10-07                    |
+-------------------------------+

Oracle:

SELECT ADD_MONTHS('07-JUL-1994',2) FROM DUAL
ADD_MONTHS('07-JUL-1994',2.6)
07-SEP-94
	
SELECT ADD_MONTHS('07-JUL-1994',2.6) FROM DUAL	
ADD_MONTHS('07-JUL-1994',2)
07-SEP-94

Is this intentional? Also, no warnings.



 Comments   
Comment by Sergei Golubchik [ 2021-05-21 ]

Not intentional

Comment by Dave Gosselin [ 2023-12-14 ]

The grammar support for ADD_MONTHS allows expr for both arguments, which results in an Item_decimal getting created for the second argument for rational numbers, in this case 2.6. When Func_handler_date_add_interval::add is invoked, it calls get_interval_value which relies on the item argument's val_int() implementation to do the right thing. In the case of Item_decimal, val_int() will return a value rounded to the nearest integer because it relies on my_decimal which in turn relies on my_decimal2int and decimal_round to handle rounding according to a policy flag. That policy flag is set to HALF_UP by default because my_decimal doesn't supply an alternative parameter to my_decimal2int. In the present bug, that causes 2.6 to be rounded to 3 which is returned by Item_decimal::val_int() during get_interval_value, thus resulting in 1994-10-07 instead of the expected 1994-09-07 as otherwise expected.

Comment by Dave Gosselin [ 2023-12-20 ]

After a conversation with serg we decided to document the current behavior and close this as not-a-bug.

Comment by Dave Gosselin [ 2023-12-21 ]

Updated documentation at https://mariadb.com/kb/en/add_months/

Generated at Thu Feb 08 09:40:05 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.