Skip to content

Commit 6fadbf8

Browse files
committed
MDEV-31361 Wrong result on 2nd execution of PS for query with derived 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>
1 parent 9d0b79c commit 6fadbf8

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

mysql-test/suite/federated/federatedx_create_handlers.result

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,23 @@ use federated;
496496
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
497497
WHERE id=2) dt2) dt;
498498
id name
499+
PREPARE stmt FROM "
500+
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
501+
WHERE id=3) dt2) dt;
502+
";
503+
EXECUTE stmt;
504+
id name
505+
3 xxx
506+
EXECUTE stmt;
507+
id name
508+
3 xxx
509+
DEALLOCATE PREPARE stmt;
510+
EXPLAIN
511+
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
512+
WHERE id=3) dt2) dt;
513+
id select_type table type possible_keys key key_len ref rows Extra
514+
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 5 Using where
515+
4 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
499516
connection slave;
500517
CREATE TABLE federated.t10 (a INT,b INT);
501518
CREATE TABLE federated.t11 (a INT, b INT);
@@ -516,6 +533,54 @@ WHERE id=2) dt2) dt
516533
a b a b id name
517534
1 1 NULL NULL NULL NULL
518535
2 2 NULL NULL NULL NULL
536+
#
537+
# MDEV-31361: Second execution of PS for query with derived table
538+
#
539+
connection slave;
540+
DROP TABLE IF EXISTS federated.t1;
541+
CREATE TABLE federated.t1 (
542+
id int(20) NOT NULL,
543+
name varchar(16) NOT NULL default ''
544+
)
545+
DEFAULT CHARSET=latin1;
546+
INSERT INTO federated.t1 VALUES
547+
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
548+
connection master;
549+
DROP TABLE IF EXISTS federated.t1;
550+
CREATE TABLE federated.t1 (
551+
id int(20) NOT NULL,
552+
name varchar(16) NOT NULL default ''
553+
)
554+
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
555+
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
556+
use federated;
557+
SELECT * FROM
558+
(SELECT * FROM
559+
(SELECT * FROM
560+
(SELECT * FROM t1 where id>3) dt3
561+
WHERE id>3) dt2
562+
) dt;
563+
id name
564+
7 yyy
565+
4 xxx
566+
5 yyy
567+
PREPARE stmt FROM "SELECT * FROM
568+
(SELECT * FROM
569+
(SELECT * FROM
570+
(SELECT * FROM t1 where id>3) dt3
571+
WHERE id>3) dt2
572+
) dt";
573+
EXECUTE stmt;
574+
id name
575+
7 yyy
576+
4 xxx
577+
5 yyy
578+
EXECUTE stmt;
579+
id name
580+
7 yyy
581+
4 xxx
582+
5 yyy
583+
DEALLOCATE PREPARE stmt;
519584
set global federated_pushdown=0;
520585
connection master;
521586
DROP TABLE IF EXISTS federated.t1;

mysql-test/suite/federated/federatedx_create_handlers.test

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,9 @@ DEFAULT CHARSET=latin1;
9494
INSERT INTO federated.t3 VALUES
9595
('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www');
9696

97-
#Enable after fix MDEV-31361
98-
--disable_ps2_protocol
9997
SELECT *
10098
FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t
10199
WHERE federated.t3.name=t.name;
102-
--enable_ps2_protocol
103100

104101
EXPLAIN
105102
SELECT *
@@ -351,6 +348,18 @@ use federated;
351348
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
352349
WHERE id=2) dt2) dt;
353350

351+
PREPARE stmt FROM "
352+
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
353+
WHERE id=3) dt2) dt;
354+
";
355+
EXECUTE stmt;
356+
EXECUTE stmt;
357+
DEALLOCATE PREPARE stmt;
358+
359+
EXPLAIN
360+
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
361+
WHERE id=3) dt2) dt;
362+
354363
connection slave;
355364
CREATE TABLE federated.t10 (a INT,b INT);
356365
CREATE TABLE federated.t11 (a INT, b INT);
@@ -376,6 +385,52 @@ SELECT * FROM t10 LEFT JOIN
376385
WHERE id=2) dt2) dt
377386
) ON t10.a=t11.a;
378387

388+
--echo #
389+
--echo # MDEV-31361: Second execution of PS for query with derived table
390+
--echo #
391+
392+
connection slave;
393+
DROP TABLE IF EXISTS federated.t1;
394+
395+
CREATE TABLE federated.t1 (
396+
id int(20) NOT NULL,
397+
name varchar(16) NOT NULL default ''
398+
)
399+
DEFAULT CHARSET=latin1;
400+
401+
INSERT INTO federated.t1 VALUES
402+
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
403+
404+
connection master;
405+
DROP TABLE IF EXISTS federated.t1;
406+
407+
--replace_result $SLAVE_MYPORT SLAVE_PORT
408+
eval
409+
CREATE TABLE federated.t1 (
410+
id int(20) NOT NULL,
411+
name varchar(16) NOT NULL default ''
412+
)
413+
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
414+
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
415+
416+
use federated;
417+
418+
let $q=
419+
SELECT * FROM
420+
(SELECT * FROM
421+
(SELECT * FROM
422+
(SELECT * FROM t1 where id>3) dt3
423+
WHERE id>3) dt2
424+
) dt;
425+
426+
eval $q;
427+
428+
eval PREPARE stmt FROM "$q";
429+
EXECUTE stmt;
430+
EXECUTE stmt;
431+
DEALLOCATE PREPARE stmt;
432+
433+
379434
set global federated_pushdown=0;
380435

381436
source include/federated_cleanup.inc;

sql/sql_derived.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
12171217
/* Execute the query that specifies the derived table by a foreign engine */
12181218
res= derived->pushdown_derived->execute();
12191219
unit->executed= true;
1220+
if (res)
12201221
DBUG_RETURN(res);
1222+
goto after_exec;
12211223
}
12221224

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

1283+
after_exec:
12811284
if (!res && !derived_is_recursive)
12821285
{
12831286
if (derived_result->flush())

0 commit comments

Comments
 (0)