summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2009-10-13 19:49:32 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2009-10-13 19:49:32 +0400
commitbc9f56a6c2b121e3a5de277585322068afbe1887 (patch)
tree0352cfe65d706d5683e1a8731ff58b2c52369be3 /sql/opt_range.cc
parent505346028f975d26f1353c46bdb3db618b1e306c (diff)
downloadmariadb-git-bc9f56a6c2b121e3a5de277585322068afbe1887.tar.gz
Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
The problem was in incorrect handling of predicates involving NULL as a constant value by the range optimizer. For example, when creating a SEL_ARG node from a condition of the form "field < const" (which would normally result in the "NULL < field < const" SEL_ARG), the special case when "const" is NULL was not taken into account, so "NULL < field < NULL" was produced for the "field < NULL" condition. As a result, SEL_ARG structures of this form could not be further optimized which in turn could lead to incorrectly constructed SEL_ARG trees. In particular, code assuming SEL_ARG structures to always form a sequence of ordered disjoint intervals could enter an infinite loop under some circumstances. Fixed by changing get_mm_leaf() so that for any sargable predicate except "<=>" involving NULL as a constant, "empty" SEL_ARG is returned, since such a predicate is always false. mysql-test/r/range.result: Added a test case for bug #47123. mysql-test/t/range.test: Added a test case for bug #47123. sql/opt_range.cc: Fixed get_mm_leaf() so that for any sargable predicate except "<=>" involving NULL as a constant, "empty" SEL_ARG is returned, since such a predicate is always false.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2239aafbeec..cfaff76b96b 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -5887,6 +5887,17 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
goto end;
}
field->table->in_use->variables.sql_mode= orig_sql_mode;
+
+ /*
+ Any sargable predicate except "<=>" involving NULL as a constant is always
+ FALSE
+ */
+ if (type != Item_func::EQUAL_FUNC && field->is_real_null())
+ {
+ tree= &null_element;
+ goto end;
+ }
+
str= (uchar*) alloc_root(alloc, key_part->store_length+1);
if (!str)
goto end;