From 341f82212642e3be70f9237bb9604ab725e6033f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Aug 2005 12:07:14 +0300 Subject: [PATCH 1/4] stop on NULL comparison only if it is allowed (BUG#12509) mysql-test/r/row.result: Correct NULL handling in row comporison mysql-test/t/row.test: Correct NULL handling in row comporison (BUG#12509) sql/item_cmpfunc.cc: stop on NULL comparison only if it is allowed sql/item_cmpfunc.h: support optimisation in case of processing WHERE/HAVING, where NULL and FALSE are equal --- mysql-test/r/row.result | 8 +++++++- mysql-test/t/row.test | 6 ++++++ sql/item_cmpfunc.cc | 26 ++++++++++++++++++++++---- sql/item_cmpfunc.h | 4 +++- 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 c305196615a..67d0ef83e92 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; inull_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; }; From b9314a4f89393097830baa74310c2581acb0dbc1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Aug 2005 09:46:59 +0300 Subject: [PATCH 2/4] changes in row operation --- mysql-test/r/subselect.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bbfdeb970a6..d3ab359702e 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -923,7 +923,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a) 1 1 a 2 0 b -NULL NULL NULL +NULL 0 NULL select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2; a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a) 1 0 a @@ -933,7 +933,7 @@ select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a) 1 0 a 2 0 b -NULL NULL NULL +NULL 0 NULL drop table t1,t2; create table t1 (a int, b real, c varchar(10)); insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b'); From 9e9d610d30f7328f7dc274b4458589fc93462c89 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Aug 2005 11:38:14 +0300 Subject: [PATCH 3/4] fixed test after merge --- mysql-test/r/rpl_delete_all.result | 2 +- mysql-test/t/rpl_delete_all.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/rpl_delete_all.result b/mysql-test/r/rpl_delete_all.result index 5ed221823e8..1aa556270c9 100644 --- a/mysql-test/r/rpl_delete_all.result +++ b/mysql-test/r/rpl_delete_all.result @@ -9,7 +9,7 @@ drop database if exists mysqltest; Warnings: Note 1008 Can't drop database 'mysqltest'; database doesn't exist show tables from mysqltest; -ERROR HY000: Can't read dir of './mysqltest/' (Errcode: X) +ERROR 42000: Unknown database 'mysqltest' create table t1 (a int); drop table if exists t1; Warnings: diff --git a/mysql-test/t/rpl_delete_all.test b/mysql-test/t/rpl_delete_all.test index db33ee3bb86..e0c0757bbc2 100644 --- a/mysql-test/t/rpl_delete_all.test +++ b/mysql-test/t/rpl_delete_all.test @@ -7,7 +7,7 @@ drop database if exists mysqltest; sync_slave_with_master; # can't read dir --replace_result "Errcode: 1" "Errcode: X" "Errcode: 2" "Errcode: X" \\ / ---error 12 +--error 1049 show tables from mysqltest; connection slave; From 1568be583be2a715994967679fe418eec174a311 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Aug 2005 12:54:13 +0300 Subject: [PATCH 4/4] btr0sea.c: Add diagnostic code to track a crash in adaptive hash indexes; the crash may happen if block->index == NULL innobase/btr/btr0sea.c: Add diagnostic code to track a crash in adaptive hash indexes; the crash may happen if block->index == NULL --- innobase/btr/btr0sea.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index f705fee4275..7a4e92a672a 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -964,6 +964,13 @@ btr_search_drop_page_hash_index( heap = NULL; offsets = NULL; + if (block->index == NULL) { + + mem_analyze_corruption((byte*)block); + + ut_a(block->index != NULL); + } + while (!page_rec_is_supremum(rec)) { /* FIXME: in a mixed tree, not all records may have enough ordering fields: */