Commit 707e676c authored by Ramil Kalimullin's avatar Ramil Kalimullin
Browse files

Fix for bug#37526: asymertic operator <=> in trigger

Problem: <=> operator may return wrong results 
comparing NULL and a DATE/DATETIME/TIME value.

Fix: properly check NULLs.
parent 0994c961
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -560,4 +560,27 @@ select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id	cur_date
drop table t1,t2;
SELECT 
CAST('NULL' AS DATE) <=> CAST('2008-01-01' AS DATE) n1, 
CAST('2008-01-01' AS DATE) <=> CAST('NULL' AS DATE) n2,
CAST('NULL' AS DATE) <=> CAST('NULL' AS DATE) n3,
CAST('NULL' AS DATE) <> CAST('2008-01-01' AS DATE) n4, 
CAST('2008-01-01' AS DATE) <> CAST('NULL' AS DATE) n5,
CAST('NULL' AS DATE) <> CAST('NULL' AS DATE) n6,
CAST('NULL' AS DATE) < CAST('2008-01-01' AS DATE) n7, 
CAST('2008-01-01' AS DATE) < CAST('NULL' AS DATE) n8,
CAST('NULL' AS DATE) < CAST('NULL' AS DATE) n9;
n1	n2	n3	n4	n5	n6	n7	n8	n9
0	0	1	NULL	NULL	NULL	NULL	NULL	NULL
Warnings:
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
Warning	1292	Truncated incorrect datetime value: 'NULL'
End of 5.0 tests
+16 −0
Original line number Diff line number Diff line
@@ -388,4 +388,20 @@ where id in (select id from t2 as x1 where (t2.cur_date is null));

drop table t1,t2;


#
# Bug #37526: asymertic operator <=> in trigger
#
SELECT 
  CAST('NULL' AS DATE) <=> CAST('2008-01-01' AS DATE) n1, 
  CAST('2008-01-01' AS DATE) <=> CAST('NULL' AS DATE) n2,
  CAST('NULL' AS DATE) <=> CAST('NULL' AS DATE) n3,
  CAST('NULL' AS DATE) <> CAST('2008-01-01' AS DATE) n4, 
  CAST('2008-01-01' AS DATE) <> CAST('NULL' AS DATE) n5,
  CAST('NULL' AS DATE) <> CAST('NULL' AS DATE) n6,
  CAST('NULL' AS DATE) < CAST('2008-01-01' AS DATE) n7, 
  CAST('2008-01-01' AS DATE) < CAST('NULL' AS DATE) n8,
  CAST('NULL' AS DATE) < CAST('NULL' AS DATE) n9;


--echo End of 5.0 tests
+13 −7
Original line number Diff line number Diff line
@@ -966,19 +966,24 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
       1    if items are equal or both are null
       0    otherwise
    If is_nulls_eq is FALSE:
      -1   a < b or one of items is null
      -1   a < b or at least one item is null
       0   a == b
       1   a > b
    See the table:
    is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
    a_is_null   | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
    b_is_null   | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
    result      | 1 | 0 | 0 |0/1|-1 |-1 |-1 |-1/0/1|
*/

int Arg_comparator::compare_datetime()
{
  bool is_null= FALSE;
  bool a_is_null, b_is_null;
  ulonglong a_value, b_value;

  /* Get DATE/DATETIME/TIME value of the 'a' item. */
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
  if (!is_nulls_eq && is_null)
  a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null);
  if (!is_nulls_eq && a_is_null)
  {
    if (owner)
      owner->null_value= 1;
@@ -986,14 +991,15 @@ int Arg_comparator::compare_datetime()
  }

  /* Get DATE/DATETIME/TIME value of the 'b' item. */
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
  if (is_null)
  b_value= (*get_value_func)(thd, &b, &b_cache, *a, &b_is_null);
  if (a_is_null || b_is_null)
  {
    if (owner)
      owner->null_value= is_nulls_eq ? 0 : 1;
    return is_nulls_eq ? 1 : -1;
    return is_nulls_eq ? (a_is_null == b_is_null) : -1;
  }

  /* Here we have two not-NULL values. */
  if (owner)
    owner->null_value= 0;