mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fix for BUG#4488: first portion: sign aware '<' and '>' comparisons.
This commit is contained in:
@ -475,3 +475,80 @@ id name uid id name uid
|
|||||||
1025 Y 25 1025 Y 25
|
1025 Y 25 1025 Y 25
|
||||||
1026 Z 26 1026 Z 26
|
1026 Z 26 1026 Z 26
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
create table t1 (x bigint unsigned not null);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
18446744073709551600
|
||||||
|
18446744073709551601
|
||||||
|
select count(*) from t1 where x>0;
|
||||||
|
count(*)
|
||||||
|
2
|
||||||
|
select count(*) from t1 where x=0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x<0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x < -16;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x = -16;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x > -16;
|
||||||
|
count(*)
|
||||||
|
2
|
||||||
|
create table t2 (x bigint not null);
|
||||||
|
insert into t2(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t2(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t2;
|
||||||
|
x
|
||||||
|
-16
|
||||||
|
-15
|
||||||
|
select count(*) from t2 where x>0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t2 where x=0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t2 where x<0;
|
||||||
|
count(*)
|
||||||
|
2
|
||||||
|
select count(*) from t2 where x < -16;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t2 where x = -16;
|
||||||
|
count(*)
|
||||||
|
1
|
||||||
|
select count(*) from t2 where x > -16;
|
||||||
|
count(*)
|
||||||
|
1
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (x bigint unsigned not null primary key) engine=innodb;
|
||||||
|
insert into t1(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
18446744073709551600
|
||||||
|
18446744073709551601
|
||||||
|
select count(*) from t1 where x>0;
|
||||||
|
count(*)
|
||||||
|
2
|
||||||
|
select count(*) from t1 where x=0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x<0;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x < -16;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x = -16;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1 where x > -16;
|
||||||
|
count(*)
|
||||||
|
1
|
||||||
|
drop table t1;
|
||||||
|
@ -383,3 +383,42 @@ select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
|||||||
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||||
|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
# Fix for bug#4488
|
||||||
|
#
|
||||||
|
create table t1 (x bigint unsigned not null);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t1;
|
||||||
|
select count(*) from t1 where x>0;
|
||||||
|
select count(*) from t1 where x=0;
|
||||||
|
select count(*) from t1 where x<0;
|
||||||
|
select count(*) from t1 where x < -16;
|
||||||
|
select count(*) from t1 where x = -16;
|
||||||
|
select count(*) from t1 where x > -16;
|
||||||
|
|
||||||
|
create table t2 (x bigint not null);
|
||||||
|
insert into t2(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t2(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t2;
|
||||||
|
select count(*) from t2 where x>0;
|
||||||
|
select count(*) from t2 where x=0;
|
||||||
|
select count(*) from t2 where x<0;
|
||||||
|
select count(*) from t2 where x < -16;
|
||||||
|
select count(*) from t2 where x = -16;
|
||||||
|
select count(*) from t2 where x > -16;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (x bigint unsigned not null primary key) engine=innodb;
|
||||||
|
insert into t1(x) values (0xfffffffffffffff0);
|
||||||
|
insert into t1(x) values (0xfffffffffffffff1);
|
||||||
|
select * from t1;
|
||||||
|
select count(*) from t1 where x>0;
|
||||||
|
select count(*) from t1 where x=0;
|
||||||
|
select count(*) from t1 where x<0;
|
||||||
|
select count(*) from t1 where x < -16;
|
||||||
|
select count(*) from t1 where x = -16;
|
||||||
|
select count(*) from t1 where x > -16;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
@ -862,7 +862,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The following class is used to optimize comparing of date columns
|
The following class is used to optimize comparing of date and bigint columns
|
||||||
We need to save the original item, to be able to set the field to the
|
We need to save the original item, to be able to set the field to the
|
||||||
original value in 'opt_range'.
|
original value in 'opt_range'.
|
||||||
*/
|
*/
|
||||||
@ -872,7 +872,9 @@ class Item_int_with_ref :public Item_int
|
|||||||
Item *ref;
|
Item *ref;
|
||||||
public:
|
public:
|
||||||
Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
|
Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
|
||||||
{}
|
{
|
||||||
|
unsigned_flag= ref_arg->unsigned_flag;
|
||||||
|
}
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
int save_in_field(Field *field, bool no_conversions)
|
||||||
{
|
{
|
||||||
return ref->save_in_field(field, no_conversions);
|
return ref->save_in_field(field, no_conversions);
|
||||||
|
@ -315,6 +315,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
|
|||||||
func= &Arg_comparator::compare_e_binary_string;
|
func= &Arg_comparator::compare_e_binary_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type == INT_RESULT)
|
||||||
|
{
|
||||||
|
if (func == &Arg_comparator::compare_int)
|
||||||
|
{
|
||||||
|
if ((*a)->unsigned_flag)
|
||||||
|
func= ((*b)->unsigned_flag)? &Arg_comparator::compare_int_unsigned :
|
||||||
|
&Arg_comparator::compare_int_unsigned_signed;
|
||||||
|
else if ((*b)->unsigned_flag)
|
||||||
|
func= &Arg_comparator::compare_int_signed_unsigned;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,6 +445,82 @@ int Arg_comparator::compare_int()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare values as BIGINT UNSIGNED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Arg_comparator::compare_int_unsigned()
|
||||||
|
{
|
||||||
|
ulonglong val1= (*a)->val_int();
|
||||||
|
if (!(*a)->null_value)
|
||||||
|
{
|
||||||
|
ulonglong val2= (*b)->val_int();
|
||||||
|
if (!(*b)->null_value)
|
||||||
|
{
|
||||||
|
owner->null_value= 0;
|
||||||
|
if (val1 < val2) return -1;
|
||||||
|
if (val1 == val2) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner->null_value= 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare signed (*a) with unsigned (*B)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Arg_comparator::compare_int_signed_unsigned()
|
||||||
|
{
|
||||||
|
longlong sval1= (*a)->val_int();
|
||||||
|
if (!(*a)->null_value)
|
||||||
|
{
|
||||||
|
ulonglong uval2= (ulonglong)(*b)->val_int();
|
||||||
|
if (!(*b)->null_value)
|
||||||
|
{
|
||||||
|
owner->null_value= 0;
|
||||||
|
if (sval1 < 0 || (ulonglong)sval1 < uval2)
|
||||||
|
return -1;
|
||||||
|
if ((ulonglong)sval1 == uval2)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner->null_value= 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare unsigned (*a) with signed (*B)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Arg_comparator::compare_int_unsigned_signed()
|
||||||
|
{
|
||||||
|
ulonglong uval1= (ulonglong)(*a)->val_int();
|
||||||
|
if (!(*a)->null_value)
|
||||||
|
{
|
||||||
|
longlong sval2= (*b)->val_int();
|
||||||
|
if (!(*b)->null_value)
|
||||||
|
{
|
||||||
|
owner->null_value= 0;
|
||||||
|
if (sval2 < 0)
|
||||||
|
return 1;
|
||||||
|
if (uval1 < (ulonglong)sval2)
|
||||||
|
return -1;
|
||||||
|
if (uval1 == (ulonglong)sval2)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner->null_value= 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Arg_comparator::compare_e_int()
|
int Arg_comparator::compare_e_int()
|
||||||
{
|
{
|
||||||
longlong val1= (*a)->val_int();
|
longlong val1= (*a)->val_int();
|
||||||
|
@ -66,6 +66,9 @@ public:
|
|||||||
int compare_binary_string(); // compare args[0] & args[1]
|
int compare_binary_string(); // compare args[0] & args[1]
|
||||||
int compare_real(); // compare args[0] & args[1]
|
int compare_real(); // compare args[0] & args[1]
|
||||||
int compare_int(); // compare args[0] & args[1]
|
int compare_int(); // compare args[0] & args[1]
|
||||||
|
int compare_int_signed_unsigned();
|
||||||
|
int compare_int_unsigned_signed();
|
||||||
|
int compare_int_unsigned();
|
||||||
int compare_row(); // compare args[0] & args[1]
|
int compare_row(); // compare args[0] & args[1]
|
||||||
int compare_e_string(); // compare args[0] & args[1]
|
int compare_e_string(); // compare args[0] & args[1]
|
||||||
int compare_e_binary_string(); // compare args[0] & args[1]
|
int compare_e_binary_string(); // compare args[0] & args[1]
|
||||||
|
Reference in New Issue
Block a user