summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2005-08-19 08:55:38 +0300
committerunknown <bell@sanja.is.com.ua>2005-08-19 08:55:38 +0300
commitbba824eb857088269a22fdd408121a5cb78918af (patch)
treeb37d2b55a860f05f612858b544e4cc1840fab561
parentadf56c8c8401ca6040e9f1d6dfb2007ab1bb4b67 (diff)
parent341f82212642e3be70f9237bb9604ab725e6033f (diff)
downloadmariadb-git-bba824eb857088269a22fdd408121a5cb78918af.tar.gz
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-bug2-5.0 sql/item_cmpfunc.cc: Auto merged
-rw-r--r--mysql-test/r/row.result8
-rw-r--r--mysql-test/t/row.test6
-rw-r--r--sql/item_cmpfunc.cc26
-rw-r--r--sql/item_cmpfunc.h4
4 files changed, 38 insertions, 6 deletions
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index f7f7e3e8429..1762587415d 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -58,7 +58,7 @@ SELECT (1,2,3)=(1,NULL,3);
NULL
SELECT (1,2,3)=(1,NULL,0);
(1,2,3)=(1,NULL,0)
-NULL
+0
SELECT ROW(1,2,3)=ROW(1,2,3);
ROW(1,2,3)=ROW(1,2,3)
1
@@ -175,3 +175,9 @@ ROW(2,10) <=> ROW(3,4)
SELECT ROW(NULL,10) <=> ROW(3,NULL);
ROW(NULL,10) <=> ROW(3,NULL)
0
+SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
+1 0 0 0 null
+1 0 0 0 NULL
+select row(NULL,1)=(2,0);
+row(NULL,1)=(2,0)
+0
diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test
index 4becef1c2b7..6301cc0f584 100644
--- a/mysql-test/t/row.test
+++ b/mysql-test/t/row.test
@@ -86,3 +86,9 @@ SELECT ROW(2,10) <=> ROW(3,4);
SELECT ROW(NULL,10) <=> ROW(3,NULL);
# End of 4.1 tests
+
+#
+# Correct NULL handling in row comporison (BUG#12509)
+#
+SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
+select row(NULL,1)=(2,0);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index b513fb26bdb..1bae5f1c9af 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -614,17 +614,35 @@ int Arg_comparator::compare_e_int_diff_signedness()
int Arg_comparator::compare_row()
{
int res= 0;
+ bool was_null= 0;
(*a)->bring_value();
(*b)->bring_value();
uint n= (*a)->cols();
for (uint i= 0; i<n; i++)
{
- if ((res= comparators[i].compare()))
- return res;
+ res= comparators[i].compare();
if (owner->null_value)
- return -1;
+ {
+ // NULL was compared
+ if (owner->abort_on_null)
+ return -1; // We do not need correct NULL returning
+ was_null= 1;
+ owner->null_value= 0;
+ res= 0; // continue comparison (maybe we will meet explicit difference)
+ }
+ if (res)
+ return res;
}
- return res;
+ if (was_null)
+ {
+ /*
+ There was NULL(s) in comparison in some parts, but there was not
+ explicit difference in other parts, so we have to return NULL
+ */
+ owner->null_value= 1;
+ return -1;
+ }
+ return 0;
}
int Arg_comparator::compare_e_row()
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index a4165407159..6b0cf3e80c2 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -193,10 +193,11 @@ class Item_bool_func2 :public Item_int_func
protected:
Arg_comparator cmp;
String tmp_value1,tmp_value2;
+ bool abort_on_null;
public:
Item_bool_func2(Item *a,Item *b)
- :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) {}
+ :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
void fix_length_and_dec();
void set_cmp_func()
{
@@ -210,6 +211,7 @@ public:
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
uint decimal_precision() const { return 1; }
+ void top_level_item() { abort_on_null=1; }
friend class Arg_comparator;
};