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.
This commit is contained in:
parent
0994c961a7
commit
707e676c58
@ -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));
|
|||||||
|
|
||||||
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,
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user