Commit 854c1f0e authored by Oleg Smirnov's avatar Oleg Smirnov

MDEV-31361 WIP: proof-of-concept

parent 8dad5148
...@@ -514,6 +514,54 @@ WHERE id=2) dt2) dt ...@@ -514,6 +514,54 @@ WHERE id=2) dt2) dt
a b a b id name a b a b id name
1 1 NULL NULL NULL NULL 1 1 NULL NULL NULL NULL
2 2 NULL NULL NULL NULL 2 2 NULL NULL NULL NULL
#
# MDEV-31361: Wrong result on second execution of prepared statement
# for engine Federated 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
set global federated_pushdown=0; set global federated_pushdown=0;
connection master; connection master;
DROP TABLE IF EXISTS federated.t1; DROP TABLE IF EXISTS federated.t1;
......
...@@ -94,12 +94,9 @@ DEFAULT CHARSET=latin1; ...@@ -94,12 +94,9 @@ DEFAULT CHARSET=latin1;
INSERT INTO federated.t3 VALUES INSERT INTO federated.t3 VALUES
('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www'); ('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www');
#Enable after fix MDEV-31361
--disable_ps2_protocol
SELECT * SELECT *
FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t
WHERE federated.t3.name=t.name; WHERE federated.t3.name=t.name;
--enable_ps2_protocol
EXPLAIN EXPLAIN
SELECT * SELECT *
...@@ -376,6 +373,54 @@ SELECT * FROM t10 LEFT JOIN ...@@ -376,6 +373,54 @@ SELECT * FROM t10 LEFT JOIN
WHERE id=2) dt2) dt WHERE id=2) dt2) dt
) ON t10.a=t11.a; ) ON t10.a=t11.a;
--echo #
--echo # MDEV-31361: Wrong result on second execution of prepared statement
--echo # for engine Federated 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;
SELECT * FROM
(SELECT * FROM
(SELECT * FROM
(SELECT * FROM t1 where id>3) dt3
WHERE id>3) 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;
set global federated_pushdown=0; set global federated_pushdown=0;
source include/federated_cleanup.inc; source include/federated_cleanup.inc;
......
...@@ -351,13 +351,6 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -351,13 +351,6 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
if (derived->dt_handler)
{
derived->change_refs_to_fields();
derived->set_materialized_derived();
DBUG_RETURN(FALSE);
}
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
if (!derived->merged_for_insert || if (!derived->merged_for_insert ||
...@@ -379,6 +372,12 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -379,6 +372,12 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
goto unconditional_materialization; goto unconditional_materialization;
} }
if (derived->is_pushed_down())
{
cause= "Pushed down derived tables must always be materialized";
goto unconditional_materialization;
}
if (dt_select->options & OPTION_SCHEMA_TABLE) if (dt_select->options & OPTION_SCHEMA_TABLE)
parent_lex->options |= OPTION_SCHEMA_TABLE; parent_lex->options |= OPTION_SCHEMA_TABLE;
...@@ -869,6 +868,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -869,6 +868,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
if (derived->is_derived() && derived->is_merged_derived()) if (derived->is_derived() && derived->is_merged_derived())
first_select->mark_as_belong_to_derived(derived); first_select->mark_as_belong_to_derived(derived);
/*
Choosing an external executor of a derived table (also called the
"pushdown handler") must be the last step in mysql_derived_prepare,
because the external engine requires the preparation of the DT to be
fully completed.
*/
derived->dt_handler= derived->find_derived_handler(thd); derived->dt_handler= derived->find_derived_handler(thd);
if (derived->dt_handler) if (derived->dt_handler)
{ {
......
...@@ -4922,7 +4922,7 @@ void st_select_lex::set_explain_type(bool on_the_fly) ...@@ -4922,7 +4922,7 @@ void st_select_lex::set_explain_type(bool on_the_fly)
if (linkage == DERIVED_TABLE_TYPE) if (linkage == DERIVED_TABLE_TYPE)
{ {
bool is_pushed_master_unit= master_unit()->derived && bool is_pushed_master_unit= master_unit()->derived &&
master_unit()->derived->pushdown_derived; master_unit()->derived->is_pushed_down();
if (is_pushed_master_unit) if (is_pushed_master_unit)
type= pushed_derived_text; type= pushed_derived_text;
else if (is_uncacheable & UNCACHEABLE_DEPENDENT) else if (is_uncacheable & UNCACHEABLE_DEPENDENT)
......
...@@ -2894,6 +2894,11 @@ struct TABLE_LIST ...@@ -2894,6 +2894,11 @@ struct TABLE_LIST
{ {
derived_type|= DTYPE_MULTITABLE; derived_type|= DTYPE_MULTITABLE;
} }
bool is_pushed_down() const
{
return dt_handler != NULL;
}
bool set_as_with_table(THD *thd, With_element *with_elem); bool set_as_with_table(THD *thd, With_element *with_elem);
void reset_const_table(); void reset_const_table();
bool handle_derived(LEX *lex, uint phases); bool handle_derived(LEX *lex, uint phases);
......
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