Skip to content

Commit

Permalink
MDEV-31361 Wrong result on 2nd execution of PS for query with derived…
Browse files Browse the repository at this point in the history
… table

This bug led to wrong result sets returned by the second execution of
prepared statements from selects using mergeable derived tables pushed
into external engine. Such derived tables are always materialized. The
decision that they have to be materialized is taken late in the function
mysql_derived_optimized(). For regular derived tables this decision is
usually taken at the prepare phase. However in some cases for some derived
tables this decision is made in mysql_derived_optimized() too. It can be
seen in the code of mysql_derived_fill() that for such a derived table it's
critical to change its translation table to tune it to the fields of the
temporary table used for materialization of the derived table and this
must be done after each refill of the derived table. The same actions are
needed for derived tables pushed into external engines.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
  • Loading branch information
igorbabaev committed Feb 4, 2024
1 parent 9d0b79c commit 6fadbf8
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 3 deletions.
65 changes: 65 additions & 0 deletions mysql-test/suite/federated/federatedx_create_handlers.result
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,23 @@ use federated;
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt;
id name
PREPARE stmt FROM "
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=3) dt2) dt;
";
EXECUTE stmt;
id name
3 xxx
EXECUTE stmt;
id name
3 xxx
DEALLOCATE PREPARE stmt;
EXPLAIN
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=3) dt2) dt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 5 Using where
4 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
connection slave;
CREATE TABLE federated.t10 (a INT,b INT);
CREATE TABLE federated.t11 (a INT, b INT);
Expand All @@ -516,6 +533,54 @@ WHERE id=2) dt2) dt
a b a b id name
1 1 NULL NULL NULL NULL
2 2 NULL NULL NULL NULL
#
# MDEV-31361: Second execution of PS for query with derived table
#
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
INSERT INTO federated.t1 VALUES
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
connection master;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
use federated;
SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT * FROM t1 where id>3) dt3
WHERE id>3) dt2
) dt;
id name
7 yyy
4 xxx
5 yyy
PREPARE stmt FROM "SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT * FROM t1 where id>3) dt3
WHERE id>3) dt2
) dt";
EXECUTE stmt;
id name
7 yyy
4 xxx
5 yyy
EXECUTE stmt;
id name
7 yyy
4 xxx
5 yyy
DEALLOCATE PREPARE stmt;
set global federated_pushdown=0;
connection master;
DROP TABLE IF EXISTS federated.t1;
Expand Down
61 changes: 58 additions & 3 deletions mysql-test/suite/federated/federatedx_create_handlers.test
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,9 @@ DEFAULT CHARSET=latin1;
INSERT INTO federated.t3 VALUES
('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www');

#Enable after fix MDEV-31361
--disable_ps2_protocol
SELECT *
FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t
WHERE federated.t3.name=t.name;
--enable_ps2_protocol

EXPLAIN
SELECT *
Expand Down Expand Up @@ -351,6 +348,18 @@ use federated;
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=2) dt2) dt;

PREPARE stmt FROM "
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=3) dt2) dt;
";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

EXPLAIN
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
WHERE id=3) dt2) dt;

connection slave;
CREATE TABLE federated.t10 (a INT,b INT);
CREATE TABLE federated.t11 (a INT, b INT);
Expand All @@ -376,6 +385,52 @@ SELECT * FROM t10 LEFT JOIN
WHERE id=2) dt2) dt
) ON t10.a=t11.a;

--echo #
--echo # MDEV-31361: Second execution of PS for query with derived table
--echo #

connection slave;
DROP TABLE IF EXISTS federated.t1;

CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
DEFAULT CHARSET=latin1;

INSERT INTO federated.t1 VALUES
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');

connection master;
DROP TABLE IF EXISTS federated.t1;

--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.t1 (
id int(20) NOT NULL,
name varchar(16) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';

use federated;

let $q=
SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT * FROM t1 where id>3) dt3
WHERE id>3) dt2
) dt;

eval $q;

eval PREPARE stmt FROM "$q";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


set global federated_pushdown=0;

source include/federated_cleanup.inc;
Expand Down
3 changes: 3 additions & 0 deletions sql/sql_derived.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
/* Execute the query that specifies the derived table by a foreign engine */
res= derived->pushdown_derived->execute();
unit->executed= true;
if (res)
DBUG_RETURN(res);
goto after_exec;
}

if (unit->executed && !derived_is_recursive &&
Expand Down Expand Up @@ -1278,6 +1280,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
derived_result, unit, first_select);
}

after_exec:
if (!res && !derived_is_recursive)
{
if (derived_result->flush())
Expand Down

0 comments on commit 6fadbf8

Please sign in to comment.