summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/range.result9
-rw-r--r--mysql-test/t/range.test10
-rw-r--r--sql/opt_range.cc11
3 files changed, 30 insertions, 0 deletions
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index cc5e8d2be96..69ae81982a9 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1219,3 +1219,12 @@ explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref a a 5 const 502 Using where
drop table t1, t2;
+#
+# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+a
+DROP TABLE t1;
+# End of 5.1 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index e1411e7fd46..7b35f69c041 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1046,3 +1046,13 @@ explain select * from t2 where a=1000 and b<11;
drop table t1, t2;
+--echo #
+--echo # Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+--echo #
+
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+DROP TABLE t1;
+
+--echo # End of 5.1 tests
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;