summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gshchepa.loc>2007-04-20 15:14:09 +0500
committerunknown <gshchepa/uchum@gshchepa.loc>2007-04-20 15:14:09 +0500
commita8f639fccc19ef80d67c52e698bf6366fdcf6f94 (patch)
tree6383a76b0ed8fd01a6c60da7807976b0f22d3f6f /sql/item_cmpfunc.cc
parent78c734b0132fbd53ff033eada5a9664919370739 (diff)
downloadmariadb-git-a8f639fccc19ef80d67c52e698bf6366fdcf6f94.tar.gz
Bug#27704: incorrect comparison of rows with NULL components
Support for NULL components was incomplete for row comparison, fixed. Added support for abort_on_null at compare_row() like in 5.x sql/item_cmpfunc.h: Bug#27704: incorrect comparison of rows with NULL components Added support for abort_on_null at Item_bool_func2 like in 5.x sql/item_cmpfunc.cc: Bug#27704: incorrect comparison of rows with NULL components Support for NULL components was incomplete for row comparison, fixed. Added support for abort_on_null at compare_row() like in 5.x mysql-test/t/row.test: Test case updated for Bug#27704 (incorrect comparison of rows with NULL components) mysql-test/r/row.result: Test case updated for Bug#27704 (incorrect comparison of rows with NULL components) mysql-test/r/subselect.result: Test case updated for Bug#27704 (incorrect comparison of rows with NULL components)
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc36
1 files changed, 32 insertions, 4 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ce3096da778..be44d490415 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -680,17 +680,45 @@ 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
+ switch (owner->functype()) {
+ case Item_func::NE_FUNC:
+ break; // NE never aborts on NULL even if abort_on_null is set
+ case Item_func::LT_FUNC:
+ case Item_func::LE_FUNC:
+ case Item_func::GT_FUNC:
+ case Item_func::GE_FUNC:
+ return -1; // <, <=, > and >= always fail on NULL
+ default: // EQ_FUNC
+ 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)
+ }
+ else if (res)
+ return res;
}
- return res;
+ if (was_null)
+ {
+ /*
+ There was NULL(s) in comparison in some parts, but there was no
+ 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()