Commit 776793a9 authored by Ramil Kalimullin's avatar Ramil Kalimullin

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.


mysql-test/r/type_datetime.result:
  Fix for bug#37526: asymertic operator <=> in trigger
    - test result.
mysql-test/t/type_datetime.test:
  Fix for bug#37526: asymertic operator <=> in trigger
    - test case.
sql/item_cmpfunc.cc:
  Fix for bug#37526: asymertic operator <=> in trigger
    - if is_nulls_eq is TRUE Arg_comparator::compare_datetime() 
  should return 1 only if both arguments are NULL.
parent 788be2ae
...@@ -560,4 +560,27 @@ select * from t2 ...@@ -560,4 +560,27 @@ select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null)); where id in (select id from t2 as x1 where (t2.cur_date is null));
id cur_date id cur_date
drop table t1,t2; 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 End of 5.0 tests
...@@ -388,4 +388,20 @@ where id in (select id from t2 as x1 where (t2.cur_date is null)); ...@@ -388,4 +388,20 @@ where id in (select id from t2 as x1 where (t2.cur_date is null));
drop table t1,t2; 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 --echo End of 5.0 tests
...@@ -966,19 +966,24 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, ...@@ -966,19 +966,24 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
1 if items are equal or both are null 1 if items are equal or both are null
0 otherwise 0 otherwise
If is_nulls_eq is FALSE: 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 0 a == b
1 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() int Arg_comparator::compare_datetime()
{ {
bool is_null= FALSE; bool a_is_null, b_is_null;
ulonglong a_value, b_value; ulonglong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */ /* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null); a_value= (*get_value_func)(thd, &a, &a_cache, *b, &a_is_null);
if (!is_nulls_eq && is_null) if (!is_nulls_eq && a_is_null)
{ {
if (owner) if (owner)
owner->null_value= 1; owner->null_value= 1;
...@@ -986,14 +991,15 @@ int Arg_comparator::compare_datetime() ...@@ -986,14 +991,15 @@ int Arg_comparator::compare_datetime()
} }
/* Get DATE/DATETIME/TIME value of the 'b' item. */ /* Get DATE/DATETIME/TIME value of the 'b' item. */
b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null); b_value= (*get_value_func)(thd, &b, &b_cache, *a, &b_is_null);
if (is_null) if (a_is_null || b_is_null)
{ {
if (owner) if (owner)
owner->null_value= is_nulls_eq ? 0 : 1; 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) if (owner)
owner->null_value= 0; owner->null_value= 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment