Commit d9ea0d0c authored by Alexey Botchkov's avatar Alexey Botchkov

Bug#41371 Select returns 1 row with condition "col is not null and col is null"

    For application compatibility reasons  MySQL converts "<autoincrement_column> IS NULL"
    predicates to "<autoincrement_column> = LAST_INSERT_ID()" in the first SELECT following an
    INSERT regardless of whether they're top level predicates or not. This causes wrong and
    obscure results when these predicates are combined with others on the same columns. Fixed
    by only doing the transformation on a single top-level predicate if a special SQL mode is
    turned on (sql_auto_is_null).
    Also made sql_auto_is_null off by default.

per-file comments:
  mysql-test/r/func_isnull.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
    test result updated

  mysql-test/t/func_isnull.test
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
    test case added

  sql/mysqld.cc
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
    sql_auto_is_null now is OFF by default.

  sql/sql_select.cc
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
    remove_eq_conds() split in two parts - one only checks the upper condition,
    the req_remove_eq_conds() recursively checks all the condition tree.

  mysql-test/extra/rpl_tests/rpl_insert_id.test
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        test fixed (set the sql_auto_is_null variable)

  mysql-test/r/mysqlbinlog.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/r/mysqlbinlog2.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/r/odbc.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/r/query_cache.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/r/user_var-binlog.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/suite/rpl/r/rpl_insert_id.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/suite/rpl/r/rpl_sp.result
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        result updated

  mysql-test/t/odbc.test
Bug#41371      Select returns 1 row with condition "col is not null and col is null"
        test fixed (set the sql_auto_is_null variable)
parent 5c4423c5
...@@ -117,6 +117,7 @@ sync_slave_with_master; ...@@ -117,6 +117,7 @@ sync_slave_with_master;
--echo # --echo #
connection master; connection master;
set @@session.sql_auto_is_null=1;
eval create table t1(a int auto_increment, key(a)) engine=$engine_type; eval create table t1(a int auto_increment, key(a)) engine=$engine_type;
eval create table t2(a int) engine=$engine_type; eval create table t2(a int) engine=$engine_type;
insert into t1 (a) values (null); insert into t1 (a) values (null);
...@@ -548,4 +549,5 @@ connection master; ...@@ -548,4 +549,5 @@ connection master;
drop table t1, t2; drop table t1, t2;
drop procedure foo; drop procedure foo;
SET @@global.concurrent_insert= @old_concurrent_insert; SET @@global.concurrent_insert= @old_concurrent_insert;
set @@session.sql_auto_is_null=default;
sync_slave_with_master; sync_slave_with_master;
...@@ -5,3 +5,8 @@ flush tables; ...@@ -5,3 +5,8 @@ flush tables;
select * from t1 where isnull(to_days(mydate)); select * from t1 where isnull(to_days(mydate));
id mydate id mydate
drop table t1; drop table t1;
CREATE TABLE t1 (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id));
INSERT INTO t1( id ) VALUES ( NULL );
SELECT t1.id FROM t1 WHERE (id is not null and id is null );
id
DROP TABLE t1;
...@@ -21,7 +21,7 @@ ROLLBACK/*!*/; ...@@ -21,7 +21,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -67,7 +67,7 @@ DELIMITER /*!*/; ...@@ -67,7 +67,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -99,7 +99,7 @@ DELIMITER /*!*/; ...@@ -99,7 +99,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -121,7 +121,7 @@ ROLLBACK/*!*/; ...@@ -121,7 +121,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -167,7 +167,7 @@ DELIMITER /*!*/; ...@@ -167,7 +167,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -199,7 +199,7 @@ DELIMITER /*!*/; ...@@ -199,7 +199,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -299,7 +299,7 @@ DELIMITER /*!*/; ...@@ -299,7 +299,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -349,7 +349,7 @@ DELIMITER /*!*/; ...@@ -349,7 +349,7 @@ DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
This diff is collapsed.
drop table if exists t1; drop table if exists t1;
set @@session.sql_auto_is_null=1;
select {fn length("hello")}, { date "1997-10-20" }; select {fn length("hello")}, { date "1997-10-20" };
{fn length("hello")} 1997-10-20 {fn length("hello")} 1997-10-20
5 1997-10-20 5 1997-10-20
...@@ -7,9 +8,9 @@ insert into t1 SET A=NULL,B=1; ...@@ -7,9 +8,9 @@ insert into t1 SET A=NULL,B=1;
insert into t1 SET a=null,b=2; insert into t1 SET a=null,b=2;
select * from t1 where a is null and b=2; select * from t1 where a is null and b=2;
a b a b
2 2
select * from t1 where a is null; select * from t1 where a is null;
a b a b
2 2
explain select * from t1 where b is null; explain select * from t1 where b is null;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
...@@ -25,3 +26,4 @@ SELECT sql_no_cache a, last_insert_id() FROM t1; ...@@ -25,3 +26,4 @@ SELECT sql_no_cache a, last_insert_id() FROM t1;
a last_insert_id() a last_insert_id()
1 1 1 1
DROP TABLE t1; DROP TABLE t1;
set @@session.sql_auto_is_null=default;
...@@ -342,19 +342,18 @@ create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i) ...@@ -342,19 +342,18 @@ create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)
insert into mysqltest.t1 (a) values (1); insert into mysqltest.t1 (a) values (1);
select * from mysqltest.t1 where i is null; select * from mysqltest.t1 where i is null;
i a i a
1 1
create table t1(a int); create table t1(a int);
select * from t1; select * from t1;
a a
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 1 Qcache_queries_in_cache 2
select * from mysqltest.t1; select * from mysqltest.t1;
i a i a
1 1 1 1
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
Qcache_queries_in_cache 2 Qcache_queries_in_cache 3
drop database mysqltest; drop database mysqltest;
show status like "Qcache_queries_in_cache"; show status like "Qcache_queries_in_cache";
Variable_name Value Variable_name Value
......
...@@ -22,7 +22,7 @@ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/; ...@@ -22,7 +22,7 @@ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=10000/*!*/; SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
...@@ -16,7 +16,7 @@ DELIMITER /*!*/; ...@@ -16,7 +16,7 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
SET TIMESTAMP=10000/*!*/; SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
...@@ -16,7 +16,7 @@ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/; ...@@ -16,7 +16,7 @@ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=10000/*!*/; SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
...@@ -97,6 +97,7 @@ drop table t1; ...@@ -97,6 +97,7 @@ drop table t1;
# #
# Bug#14553: NULL in WHERE resets LAST_INSERT_ID # Bug#14553: NULL in WHERE resets LAST_INSERT_ID
# #
set @@session.sql_auto_is_null=1;
create table t1(a int auto_increment, key(a)) engine=myisam; create table t1(a int auto_increment, key(a)) engine=myisam;
create table t2(a int) engine=myisam; create table t2(a int) engine=myisam;
insert into t1 (a) values (null); insert into t1 (a) values (null);
...@@ -531,3 +532,4 @@ id last_id ...@@ -531,3 +532,4 @@ id last_id
drop table t1, t2; drop table t1, t2;
drop procedure foo; drop procedure foo;
SET @@global.concurrent_insert= @old_concurrent_insert; SET @@global.concurrent_insert= @old_concurrent_insert;
set @@session.sql_auto_is_null=default;
...@@ -159,7 +159,7 @@ ROLLBACK/*!*/; ...@@ -159,7 +159,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -181,7 +181,7 @@ ROLLBACK/*!*/; ...@@ -181,7 +181,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -290,7 +290,7 @@ ROLLBACK/*!*/; ...@@ -290,7 +290,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
...@@ -321,7 +321,7 @@ ROLLBACK/*!*/; ...@@ -321,7 +321,7 @@ ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
...@@ -619,7 +619,7 @@ DELIMITER /*!*/; ...@@ -619,7 +619,7 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
SET TIMESTAMP=t/*!*/; SET TIMESTAMP=t/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/; SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
......
...@@ -13,3 +13,15 @@ select * from t1 where isnull(to_days(mydate)); ...@@ -13,3 +13,15 @@ select * from t1 where isnull(to_days(mydate));
drop table t1; drop table t1;
# End of 4.1 tests # End of 4.1 tests
#
# Bug #41371 Select returns 1 row with condition "col is not null and col is null"
#
CREATE TABLE t1 (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY(id));
INSERT INTO t1( id ) VALUES ( NULL );
SELECT t1.id FROM t1 WHERE (id is not null and id is null );
DROP TABLE t1;
# End of 5.1 tests
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
set @@session.sql_auto_is_null=1;
# #
# Test some ODBC compatibility # Test some ODBC compatibility
# #
...@@ -32,3 +34,5 @@ SELECT sql_no_cache a, last_insert_id() FROM t1; ...@@ -32,3 +34,5 @@ SELECT sql_no_cache a, last_insert_id() FROM t1;
DROP TABLE t1; DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
set @@session.sql_auto_is_null=default;
...@@ -7792,7 +7792,7 @@ static int mysql_init_variables(void) ...@@ -7792,7 +7792,7 @@ static int mysql_init_variables(void)
log_error_file_ptr= log_error_file; log_error_file_ptr= log_error_file;
lc_messages_dir_ptr= lc_messages_dir; lc_messages_dir_ptr= lc_messages_dir;
mysql_data_home= mysql_real_data_home; mysql_data_home= mysql_real_data_home;
thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG | thd_startup_options= (OPTION_BIN_LOG |
OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES); OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
protocol_version= PROTOCOL_VERSION; protocol_version= PROTOCOL_VERSION;
what_to_log= ~ (1L << (uint) COM_TIME); what_to_log= ~ (1L << (uint) COM_TIME);
......
...@@ -9119,18 +9119,26 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list, ...@@ -9119,18 +9119,26 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
/** /**
Remove const and eq items. Handles the reqursive job for remove_eq_conds()
@return Remove const and eq items. Return new item, or NULL if no condition
Return new item, or NULL if no condition @n cond_value is set to according:
cond_value is set to according: COND_OK query is possible (field = constant)
- COND_OK : query is possible (field = constant) COND_TRUE always true ( 1 = 1 )
- COND_TRUE : always true ( 1 = 1 ) COND_FALSE always false ( 1 = 2 )
- COND_FALSE : always false ( 1 = 2 )
SYNPOSIS
remove_eq_conds()
thd THD environment
cond the condition to handle
cond_value the resulting value of the condition
RETURN
*COND with the simplified condition
*/ */
COND * static COND *
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{ {
if (cond->type() == Item::COND_ITEM) if (cond->type() == Item::COND_ITEM)
{ {
...@@ -9144,7 +9152,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) ...@@ -9144,7 +9152,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
Item *item; Item *item;
while ((item=li++)) while ((item=li++))
{ {
Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value); Item *new_item=internal_remove_eq_conds(thd, item, &tmp_cond_value);
if (!new_item) if (!new_item)
li.remove(); li.remove();
else if (item != new_item) else if (item != new_item)
...@@ -9192,6 +9200,86 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) ...@@ -9192,6 +9200,86 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
} }
else if (cond->type() == Item::FUNC_ITEM && else if (cond->type() == Item::FUNC_ITEM &&
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC) ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
{
Item_func_isnull *func=(Item_func_isnull*) cond;
Item **args= func->arguments();
if (args[0]->type() == Item::FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
/*
datetime_field IS NULL has to be modified to
datetime_field == 0
*/
if (((field->type() == MYSQL_TYPE_DATE) ||
(field->type() == MYSQL_TYPE_DATETIME)) &&
(field->flags & NOT_NULL_FLAG) && !field->table->maybe_null)
{
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
{
cond=new_cond;
/*
Item_func_eq can't be fixed after creation so we do not check
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
cond->fix_fields(thd, &cond);
}
}
}
if (cond->const_item())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
}
}
else if (cond->const_item())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
}
else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
{ // boolan compare function
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
if (left_item->eq(right_item,1))
{
if (!left_item->maybe_null ||
((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
return (COND*) 0; // Compare of identical items
}
}
*cond_value=Item::COND_OK;
return cond; // Point at next and level
}
/**
Remove const and eq items. Return new item, or NULL if no condition
cond_value is set to according:
COND_OK query is possible (field = constant)
COND_TRUE always true ( 1 = 1 )
COND_FALSE always false ( 1 = 2 )
SYNPOSIS
remove_eq_conds()
thd THD environment
cond the condition to handle
cond_value the resulting value of the condition
NOTES
calls the inner_remove_eq_conds to check all the tree reqursively
RETURN
*COND with the simplified condition
*/
COND *
remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{
if (cond->type() == Item::FUNC_ITEM &&
((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
{ {
/* /*
Handles this special case for some ODBC applications: Handles this special case for some ODBC applications:
...@@ -9235,52 +9323,16 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) ...@@ -9235,52 +9323,16 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
clear for next row clear for next row
*/ */
thd->substitute_null_with_insert_id= FALSE; thd->substitute_null_with_insert_id= FALSE;
*cond_value= Item::COND_OK;
return cond;
} }
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
else if (((field->type() == MYSQL_TYPE_DATE) ||
(field->type() == MYSQL_TYPE_DATETIME)) &&
(field->flags & NOT_NULL_FLAG) &&
!field->table->maybe_null)
{
COND *new_cond;
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
{
cond=new_cond;
/*
Item_func_eq can't be fixed after creation so we do not check
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
cond->fix_fields(thd, &cond);
}
}
}
if (cond->const_item())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
}
}
else if (cond->const_item())
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
}
else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
{ // boolan compare function
Item *left_item= ((Item_func*) cond)->arguments()[0];
Item *right_item= ((Item_func*) cond)->arguments()[1];
if (left_item->eq(right_item,1))
{
if (!left_item->maybe_null ||
((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
return (COND*) 0; // Compare of identical items
} }
} }
*cond_value=Item::COND_OK; return internal_remove_eq_conds(thd, cond, cond_value); // Scan all the condition
return cond; // Point at next and level
} }
/* /*
Check if equality can be used in removing components of GROUP BY/DISTINCT Check if equality can be used in removing components of GROUP BY/DISTINCT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment