Bug #8658 UNION, IF control flow function, truncated line
Submitted: 21 Feb 2005 19:20 Modified: 13 Jul 2005 13:16
Reporter: Matthias Leich Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.0 OS:
Assigned to: Alexey Botchkov CPU Architecture:Any

[21 Feb 2005 19:20] Matthias Leich
Description:
It looks like the first result record of 
       IF (<get false>,<expr1>,<expr2>) .. UNION SELECT <expr3>
which should be 
      <expr2> 
is systematically truncated to the 
      maximum of (length(<expr1>),length(<expr3>)) .
This wrong behaviour
- seems to be new, maybe a code push of the last week)
- disappears, when the UNION SELECT is deleted
- is not covered by the manual

BTW: - The control flow function CASE does not show this bug.
        - A fresh pulled+compiled MySQL 4.1 does not show
          this bug.

Please have a look into the attached test case.

My environment:
   - Intel PC with Linux(SuSE 9.1)
   - MySQL compiled from source
        Version 5.0 ChangeSet@1.1878, 2005-02-21

How to repeat:
Please use my attached test file ml28.test , copy it to mysql-test/t

  touch r/ml28.result     # Produce a dummy file with expected results.
  ./mysql-test-run ml28
  inspect r/ml28.reject    # The protocol of the execution.
[21 Feb 2005 19:20] Matthias Leich
test case

Attachment: ml28.test (application/test, text), 1.58 KiB.

[11 Mar 2005 12:35] Alexander Barkov
An easier example of wrong behaviour:

drop table t1;
create table t1
select IF ( 1 = 0 ,
                '<------- 26 CHAR -------->',
                '<####### 26 CHAR #######>aaaaaaaaaaaaaaa')
                as "my_column";
mysql> select * from t1;
+----------------------------+
| my_column                  |
+----------------------------+
| <####### 26 CHAR ########> |
+----------------------------+
1 row in set (0.00 sec)
[11 Mar 2005 13:44] Alexander Barkov
create table t1 
select ifnull(concat(null,'<------- 26 CHAR -------->'),'<####### 26 CHAR ########>012345');

produced wrong result too.
[11 Mar 2005 13:57] Alexander Barkov
The reason of the big is in this code:

max_length= (max(args[0]->max_length - args[0]->decimals,
                 args[1]->max_length - args[1]->decimals) +
                decimals);

If args[x] is Item_string, then decimals is NOT_FIXED_DEC, which is 31.
So (args[x]->max_lengnt - args[x]->decimals) gives negative results.

The problem appears with IF and IFNULL, but perhaps with other functions as well.

Reassigning to HF. I'm not sure how to fix this bug properly.

Perhaps a method in Item should be added to return "real" decimals.
Another option is to add a function:
agg_dec_and_length(Item *res, Item *args, uint nargs)
Or, a combination of both.
[13 Jul 2005 13:16] Alexey Botchkov
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

Fixed with a previous patch