Commit f7193b92 authored by unknown's avatar unknown
Browse files

Fix for BUG#6825: When calculating Item_func_neg::max_length, add 1 for '-'.

For numeric constants we only need to add, since the parser doesn't produce 
negative numbers. 
For strings we only add (we actually could substract 1 if given string is a constant 
and it has '-number' form but we're not doing that because 
 * we set max_length bigger then necessary in other cases as well.  
 * the current solution is simpler and safer (bigger max_length is better then cutting out)


mysql-test/r/func_concat.result:
  Test for BUG#6825
mysql-test/r/metadata.result:
  Ajusted results according to fix of bug BUG#6825:length(-1) = 2 , not 1
mysql-test/t/func_concat.test:
  Test for BUG#6825
parent ae6f147a
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -32,3 +32,39 @@ select * from t1 where concat(A,C,B,D) = 'AAAA2003-03-011051';
a	b	c	d
AAAA	105	2003-03-01	1
drop table t1;
select 'a' union select concat('a', -4);
a
a
a-4
select 'a' union select concat('a', -4.5);
a
a
a-4.5
select 'a' union select concat('a', -(4 + 1));
a
a
a-5
select 'a' union select concat('a', 4 - 5);
a
a
a-1
select 'a' union select concat('a', -'3');
a
a
a-3
select 'a' union select concat('a', -concat('3',4));
a
a
a-34
select 'a' union select concat('a', -0);
a
a
a0
select 'a' union select concat('a', -0.0);
a
a
a-0.0
select 'a' union select concat('a', -0.0000);
a
a
a-0.0000
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ select 1, 1.0, -1, "hello", NULL;
Catalog	Database	Table	Table_alias	Column	Column_alias	Name	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
def					1	8	1	1	N	32769	0	8
def					1.0	5	3	3	N	32769	1	8
def					-1	8	1	2	N	32769	0	8
def					-1	8	2	2	N	32769	0	8
def					hello	254	5	5	N	1	31	8
def					NULL	6	0	0	Y	32896	0	63
1	1.0	-1	hello	NULL
+16 −0
Original line number Diff line number Diff line
@@ -34,3 +34,19 @@ create table t1 (a char(4), b double, c date, d tinyint(4));
insert into t1 values ('AAAA', 105, '2003-03-01', 1);
select * from t1 where concat(A,C,B,D) = 'AAAA2003-03-011051';
drop table t1;

# BUG#6825 
select 'a' union select concat('a', -4);
select 'a' union select concat('a', -4.5);

select 'a' union select concat('a', -(4 + 1));
select 'a' union select concat('a', 4 - 5);

select 'a' union select concat('a', -'3');
select 'a' union select concat('a', -concat('3',4));

select 'a' union select concat('a', -0);
select 'a' union select concat('a', -0.0);

select 'a' union select concat('a', -0.0000);
+16 −0
Original line number Diff line number Diff line
@@ -775,9 +775,25 @@ longlong Item_func_neg::val_int()

void Item_func_neg::fix_length_and_dec()
{
  enum Item_result arg_result= args[0]->result_type();
  enum Item::Type  arg_type= args[0]->type();
  decimals=args[0]->decimals;
  max_length=args[0]->max_length;
  hybrid_type= REAL_RESULT;
  
  /*
    We need to account for added '-' in the following cases:
    A) argument is a real or integer positive constant - in this case 
    argument's max_length is set to actual number of bytes occupied, and not 
    maximum number of bytes real or integer may require. Note that all 
    constants are non negative so we don't need to account for removed '-'.
    B) argument returns a string.
  */
  if (arg_result == STRING_RESULT || 
      (arg_type == REAL_ITEM && ((Item_real*)args[0])->value >= 0) ||
      (arg_type == INT_ITEM && ((Item_int*)args[0])->value > 0))
    max_length++;

  if (args[0]->result_type() == INT_RESULT)
  {
    /*