Loading mysql-test/r/row.result +7 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 mysql-test/t/row.test +6 −0 Original line number Diff line number Diff line Loading @@ -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); sql/item_cmpfunc.cc +22 −4 Original line number Diff line number Diff line Loading @@ -614,18 +614,36 @@ 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; } 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() { Loading sql/item_cmpfunc.h +3 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -210,6 +211,7 @@ class Item_bool_func2 :public Item_int_func 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; }; Loading Loading
mysql-test/r/row.result +7 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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
mysql-test/t/row.test +6 −0 Original line number Diff line number Diff line Loading @@ -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);
sql/item_cmpfunc.cc +22 −4 Original line number Diff line number Diff line Loading @@ -614,18 +614,36 @@ 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; } 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() { Loading
sql/item_cmpfunc.h +3 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -210,6 +211,7 @@ class Item_bool_func2 :public Item_int_func 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; }; Loading