Skip to content
Permalink
Browse files

MDEV-6859: scalar subqueries in a comparison produced unexpected result

When one evaluates row-based comparison like (X, Y) = (A,B), one should
first call bring_value() for the Item that returns row value. If you
don't do that and just attempt to read values of X and Y, you get stale
values.
Semi-join/Materialization can take a row-based comparison apart and
make ref access from it. In that case, we need to call bring_value()
to get the index lookup components.
  • Loading branch information...
spetrunia committed Feb 8, 2016
1 parent d443d70 commit b17a4350696c646e4bc6154a27eeddf363cd39c7
Showing with 133 additions and 0 deletions.
  1. +39 −0 mysql-test/r/subselect_sj.result
  2. +39 −0 mysql-test/r/subselect_sj_jcl6.result
  3. +44 −0 mysql-test/t/subselect_sj.test
  4. +11 −0 sql/sql_select.cc
@@ -3021,4 +3021,43 @@ f1 f2 f3
1 0 2
drop table t1,t2,t3,t4;
set optimizer_switch= @tmp_mdev7823;
#
# MDEV-6859: scalar subqueries in a comparison produced unexpected result
#
set @tmp_mdev6859=@@optimizer_switch;
set optimizer_switch=default;
CREATE TABLE t1 (
project_number varchar(50) NOT NULL,
PRIMARY KEY (project_number)
) ENGINE=MyISAM;
INSERT INTO t1 (project_number) VALUES ('aaa'),('bbb');
CREATE TABLE t2 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
project_number varchar(50) NOT NULL,
history_date date NOT NULL,
country varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
INSERT INTO t2 (id, project_number, history_date, country) VALUES
(1, 'aaa', '2014-08-09', 'france'),(2, 'aaa', '2014-09-09', 'singapore');
CREATE TABLE t3 (
region varchar(50) NOT NULL,
country varchar(50) NOT NULL
) ENGINE=MyISAM;
INSERT INTO t3 (region, country) VALUES ('apac', 'singapore'),('eame', 'france');
SELECT SQL_NO_CACHE a.project_number
FROM t1 a
WHERE ( SELECT z.country
FROM t2 z
WHERE z.project_number = a.project_number AND z.history_date <= '2014-09-01'
ORDER BY z.id DESC LIMIT 1
) IN (
SELECT r.country
FROM t3 r
WHERE r.region = 'eame'
);
project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
set optimizer_switch=@subselect_sj_tmp;
@@ -3035,6 +3035,45 @@ f1 f2 f3
1 0 2
drop table t1,t2,t3,t4;
set optimizer_switch= @tmp_mdev7823;
#
# MDEV-6859: scalar subqueries in a comparison produced unexpected result
#
set @tmp_mdev6859=@@optimizer_switch;
set optimizer_switch=default;
CREATE TABLE t1 (
project_number varchar(50) NOT NULL,
PRIMARY KEY (project_number)
) ENGINE=MyISAM;
INSERT INTO t1 (project_number) VALUES ('aaa'),('bbb');
CREATE TABLE t2 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
project_number varchar(50) NOT NULL,
history_date date NOT NULL,
country varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
INSERT INTO t2 (id, project_number, history_date, country) VALUES
(1, 'aaa', '2014-08-09', 'france'),(2, 'aaa', '2014-09-09', 'singapore');
CREATE TABLE t3 (
region varchar(50) NOT NULL,
country varchar(50) NOT NULL
) ENGINE=MyISAM;
INSERT INTO t3 (region, country) VALUES ('apac', 'singapore'),('eame', 'france');
SELECT SQL_NO_CACHE a.project_number
FROM t1 a
WHERE ( SELECT z.country
FROM t2 z
WHERE z.project_number = a.project_number AND z.history_date <= '2014-09-01'
ORDER BY z.id DESC LIMIT 1
) IN (
SELECT r.country
FROM t3 r
WHERE r.region = 'eame'
);
project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
@@ -2724,6 +2724,50 @@ SELECT * FROM t1, t2, t3 WHERE f2 IN ( f1 IN ( SELECT f4 FROM t4 ) );
drop table t1,t2,t3,t4;
set optimizer_switch= @tmp_mdev7823;

--echo #
--echo # MDEV-6859: scalar subqueries in a comparison produced unexpected result
--echo #
set @tmp_mdev6859=@@optimizer_switch;
set optimizer_switch=default;
CREATE TABLE t1 (
project_number varchar(50) NOT NULL,
PRIMARY KEY (project_number)
) ENGINE=MyISAM;

INSERT INTO t1 (project_number) VALUES ('aaa'),('bbb');

CREATE TABLE t2 (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
project_number varchar(50) NOT NULL,
history_date date NOT NULL,
country varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;

INSERT INTO t2 (id, project_number, history_date, country) VALUES
(1, 'aaa', '2014-08-09', 'france'),(2, 'aaa', '2014-09-09', 'singapore');

CREATE TABLE t3 (
region varchar(50) NOT NULL,
country varchar(50) NOT NULL
) ENGINE=MyISAM;

INSERT INTO t3 (region, country) VALUES ('apac', 'singapore'),('eame', 'france');

SELECT SQL_NO_CACHE a.project_number
FROM t1 a
WHERE ( SELECT z.country
FROM t2 z
WHERE z.project_number = a.project_number AND z.history_date <= '2014-09-01'
ORDER BY z.id DESC LIMIT 1
) IN (
SELECT r.country
FROM t3 r
WHERE r.region = 'eame'
);

drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;

# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
}
}

/*
The following is needed when one makes ref (or eq_ref) access from row
comparisons: one must call row->bring_value() to get the new values.
*/
if (tab && tab->bush_children)
{
TABLE_LIST *emb_sj_nest= tab->bush_children->start->emb_sj_nest;
emb_sj_nest->sj_subq_pred->left_expr->bring_value();
}

/* TODO: Why don't we do "Late NULLs Filtering" here? */

if (cmp_buffer_with_ref(thd, table, table_ref) ||
(table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
{

0 comments on commit b17a435

Please sign in to comment.
You can’t perform that action at this time.