1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-30828 Prevent pushing down unions with incorrect ORDER BY

Fake_select_lex->join was prepared at the unit execution stage so
the validation of fake_select_lex before the unit pushdown
was incomplete. That caused pushing down of statements having
an incorrect ORDER BY clause.
This commit moves preparation of the fake_select_lex->join to the unit
prepare() method, before initializing of the pushdown handler,
so incorrect clauses error out before being pushed down
This commit is contained in:
Oleg Smirnov
2023-04-03 18:05:44 +07:00
parent 8290a46d50
commit d6c6102cad
7 changed files with 238 additions and 148 deletions

View File

@ -11720,6 +11720,16 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
]
}
},
{
"join_preparation": {
"select_id": "fake",
"steps": [
{
"expanded_query": "select c AS c from dual"
}
]
}
},
{
"join_preparation": {
"select_id": 1,
@ -11967,16 +11977,6 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a {
"steps": []
}
},
{
"join_preparation": {
"select_id": "fake",
"steps": [
{
"expanded_query": "select c AS c from dual"
}
]
}
},
{
"join_optimization": {
"select_id": "fake",

View File

@ -572,8 +572,8 @@ CREATE TABLE federated.t2 (
a varchar(16) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
INSERT INTO federated.t1 VALUES ('abc'), ('bcd'), ('cde');
INSERT INTO federated.t2 VALUES ('abc'), ('bcd'), ('cde'), ('def'), ('efg');
INSERT INTO federated.t1 VALUES ('bcd'), ('abc'), ('cde');
INSERT INTO federated.t2 VALUES ('cde'), ('efg'), ('abc'), ('bcd'), ('def');
connection master;
CREATE TABLE federated.t1 (
a varchar(10)
@ -617,10 +617,10 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
SELECT * from federated.t1 UNION ALL SELECT * from federated.t2;
a
abc
bcd
cde
abc
bcd
bcd
cde
cde
def
efg
@ -730,10 +730,10 @@ SELECT * FROM
(SELECT * FROM federated.t1 UNION ALL SELECT * FROM federated.t2) q;
a
abc
bcd
cde
abc
bcd
bcd
cde
cde
def
efg
@ -861,12 +861,12 @@ SELECT * FROM federated.t1 EXCEPT
SELECT * FROM t4 INTERSECT
SELECT * FROM federated.t2;
a
t3_myisam1
t3_myisam2
t3_myisam3
abc
bcd
cde
t3_myisam1
t3_myisam2
t3_myisam3
EXPLAIN SELECT * FROM t3 UNION ALL
SELECT * FROM federated.t1 EXCEPT
SELECT * FROM t4 INTERSECT
@ -915,13 +915,13 @@ SELECT * FROM federated.t2) UNION ALL
SELECT * FROM federated.t1;
a
abc
abc
bcd
bcd
cde
cde
def
efg
abc
bcd
cde
EXPLAIN (SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2)
UNION ALL (SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2);
id select_type table type possible_keys key key_len ref rows Extra
@ -930,14 +930,14 @@ NULL PUSHED UNION NULL NULL NULL NULL NULL NULL NULL NULL
(SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2);
a
abc
bcd
cde
def
efg
abc
bcd
bcd
cde
cde
def
def
efg
efg
# Union of tables containing different INT data types
connection slave;
@ -955,31 +955,31 @@ CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t12';
# Entire UNION pushdown
SELECT a FROM federated.t12 UNION ALL SELECT a FROM federated.t11;
a
-1
-32678
0
0
1
32767
-32678
-1
0
EXPLAIN SELECT a FROM federated.t12 UNION ALL SELECT a FROM federated.t11;
id select_type table type possible_keys key key_len ref rows Extra
NULL PUSHED UNION NULL NULL NULL NULL NULL NULL NULL NULL
SELECT a FROM federated.t11 UNION SELECT a FROM federated.t12;
a
-32678
-1
-32678
0
1
32767
# Partial pushdown of SELECTs composing the UNION
SELECT a FROM federated.t12 UNION SELECT a FROM federated.t11 UNION SELECT 123;
a
-1
-32678
0
1
32767
-32678
-1
123
32767
EXPLAIN
SELECT a FROM federated.t12 UNION SELECT a FROM federated.t11
UNION SELECT 123;
@ -993,9 +993,9 @@ SELECT 1 UNION ALL
SELECT a FROM federated.t11 EXCEPT
SELECT 0;
a
-1
-32678
32767
-1
# Union of tables containing different string data types
connection slave;
CREATE TABLE federated.t13 (a CHAR(6));
@ -1011,9 +1011,9 @@ ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t14';
SELECT * FROM federated.t13 UNION SELECT * FROM federated.t14;
a
common
t13abc
t13xx
common
t14abcde
t14xyzzz
EXPLAIN SELECT * FROM federated.t13 UNION SELECT * FROM federated.t14;
@ -1021,12 +1021,12 @@ id select_type table type possible_keys key key_len ref rows Extra
NULL PUSHED UNION NULL NULL NULL NULL NULL NULL NULL NULL
SELECT * FROM federated.t14 UNION ALL SELECT * FROM federated.t13;
a
t14abcde
t14xyzzz
common
common
t13abc
t13xx
common
t14abcde
t14xyzzz
SELECT * FROM federated.t14 UNION
SELECT * FROM federated.t13 UNION
SELECT '123456789000';
@ -1049,10 +1049,10 @@ SELECT * FROM federated.t13 UNION
SELECT '123456789000' UNION
SELECT * FROM federated.t14;
a
123456789000
common
t13abc
t13xx
common
123456789000
t14abcde
t14xyzzz
# CREATE TABLE .. AS from a pushed UNION
@ -1084,6 +1084,61 @@ a
-1
-32678
32767
#
# MDEV-30828 ORDER BY clause using an integer (positional argument)
#
SELECT a FROM federated.t1 UNION SELECT a FROM federated.t2 ORDER BY 1;
a
abc
bcd
cde
def
efg
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY a DESC;
a
efg
def
cde
cde
bcd
bcd
abc
abc
# Check handling of incorrect ORDER BY clause
SELECT a FROM federated.t1 UNION SELECT a FROM federated.t2 ORDER BY 2;
ERROR 42S22: Unknown column '2' in 'order clause'
PREPARE stmt FROM
"SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY 2";
ERROR 42S22: Unknown column '2' in 'order clause'
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY 2,1,3;
ERROR 42S22: Unknown column '2' in 'order clause'
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY t1.a;
ERROR 42000: Table 't1' from one of the SELECTs cannot be used in ORDER clause
SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 UNION ALL
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1
ORDER BY 1;
a
def
efg
SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 UNION ALL
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1
ORDER BY 3;
ERROR 42S22: Unknown column '3' in 'order clause'
# UNION of mixed Federated/MyISAM tables, pushing parts of UNIONs
SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY a;
a
abc
bcd
cde
t3_myisam1
t3_myisam2
t3_myisam3
SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY 2;
ERROR 42S22: Unknown column '2' in 'order clause'
connection master;
DROP TABLES federated.t1, federated.t2, t3, t4, t5, t6, federated.t11,
federated.t12, federated.t13, federated.t14;

View File

@ -398,8 +398,8 @@ CREATE TABLE federated.t2 (
)
DEFAULT CHARSET=latin1;
INSERT INTO federated.t1 VALUES ('abc'), ('bcd'), ('cde');
INSERT INTO federated.t2 VALUES ('abc'), ('bcd'), ('cde'), ('def'), ('efg');
INSERT INTO federated.t1 VALUES ('bcd'), ('abc'), ('cde');
INSERT INTO federated.t2 VALUES ('cde'), ('efg'), ('abc'), ('bcd'), ('def');
connection master;
@ -426,13 +426,16 @@ INSERT INTO t3 VALUES ('t3_myisam1'), ('t3_myisam2'), ('t3_myisam3');
INSERT INTO t4 VALUES ('t4_myisam1'), ('t4_myisam2'), ('t4_myisam3');
--echo # Pushdown of the whole UNION
--sorted_result
SELECT * from federated.t1 UNION SELECT * from federated.t2;
EXPLAIN SELECT * from federated.t1 UNION SELECT * from federated.t2;
--echo # Pushdown of a part of the UNION
--sorted_result
SELECT * from federated.t1 UNION SELECT * from t3;
EXPLAIN SELECT * from federated.t1 UNION SELECT * from t3;
--sorted_result
SELECT * from federated.t1 UNION ALL SELECT * from federated.t2;
EXPLAIN SELECT * from federated.t1 UNION ALL SELECT * from federated.t2;
@ -445,6 +448,7 @@ ANALYZE SELECT * from federated.t1 UNION ALL SELECT * from federated.t2;
ANALYZE FORMAT=JSON SELECT * from federated.t1 UNION ALL
SELECT * from federated.t2;
--sorted_result
SELECT * from federated.t1 EXCEPT SELECT * from federated.t2;
EXPLAIN EXTENDED SELECT * from federated.t1 EXCEPT
@ -453,6 +457,7 @@ EXPLAIN EXTENDED SELECT * from federated.t1 EXCEPT
EXPLAIN FORMAT=JSON SELECT * from federated.t1 EXCEPT
SELECT * from federated.t2;
--sorted_result
SELECT * from federated.t1 INTERSECT SELECT * from federated.t2;
EXPLAIN PARTITIONS SELECT * from federated.t1 INTERSECT
@ -462,6 +467,7 @@ EXPLAIN FORMAT=JSON SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2;
--echo # More than two SELECTs in a UNIT:
--sorted_result
SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 UNION ALL
SELECT * from federated.t2 EXCEPT
@ -486,6 +492,7 @@ ANALYZE
SELECT count(*)+5 from federated.t1;
--echo # UNION inside a derived table: the whole derived table must be pushed
--sorted_result
SELECT * FROM
(SELECT * FROM federated.t1 UNION ALL SELECT * FROM federated.t2) q;
@ -499,6 +506,7 @@ EXPLAIN
--echo # at the server side
--disable_warnings
--sorted_result
SELECT count(*) FROM federated.t1 UNION
SELECT count(*) FROM federated.t1 EXCEPT
SELECT count(*)+1 FROM federated.t1
@ -521,8 +529,11 @@ PREPARE stmt FROM "SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1";
--sorted_result
EXECUTE stmt;
--sorted_result
EXECUTE stmt;
--sorted_result
EXECUTE stmt;
PREPARE stmt FROM "EXPLAIN SELECT * from federated.t1 INTERSECT
@ -530,13 +541,17 @@ PREPARE stmt FROM "EXPLAIN SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1";
--sorted_result
EXECUTE stmt;
--sorted_result
EXECUTE stmt;
--echo # UNIONs of mixed Federated/MyISAM tables, pushing parts of UNIONs
--sorted_result
SELECT * FROM federated.t1 UNION SELECT * FROM t3;
EXPLAIN SELECT * FROM federated.t1 UNION SELECT * FROM t3;
--sorted_result
SELECT * FROM federated.t1 UNION ALL
SELECT * FROM t3 EXCEPT
SELECT * FROM federated.t2;
@ -544,6 +559,7 @@ EXPLAIN SELECT * FROM federated.t1 UNION ALL
SELECT * FROM t3 EXCEPT
SELECT * FROM federated.t2;
--sorted_result
SELECT * FROM t3 UNION ALL
SELECT * FROM federated.t1 EXCEPT
SELECT * FROM t4 INTERSECT
@ -553,6 +569,7 @@ EXPLAIN SELECT * FROM t3 UNION ALL
SELECT * FROM t4 INTERSECT
SELECT * FROM federated.t2;
--sorted_result
SELECT * FROM federated.t2 UNION ALL
SELECT * FROM t3 EXCEPT
SELECT * FROM t4 INTERSECT
@ -567,6 +584,7 @@ EXPLAIN (SELECT * FROM federated.t1 UNION
SELECT * FROM federated.t2) UNION ALL
SELECT * FROM federated.t1;
--sorted_result
(SELECT * FROM federated.t1 UNION
SELECT * FROM federated.t2) UNION ALL
SELECT * FROM federated.t1;
@ -574,6 +592,7 @@ EXPLAIN (SELECT * FROM federated.t1 UNION
EXPLAIN (SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2)
UNION ALL (SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2);
--sorted_result
(SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2) UNION ALL
(SELECT * FROM federated.t1 UNION SELECT * FROM federated.t2);
@ -601,17 +620,21 @@ ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t12';
--echo # Entire UNION pushdown
--sorted_result
SELECT a FROM federated.t12 UNION ALL SELECT a FROM federated.t11;
EXPLAIN SELECT a FROM federated.t12 UNION ALL SELECT a FROM federated.t11;
--sorted_result
SELECT a FROM federated.t11 UNION SELECT a FROM federated.t12;
--echo # Partial pushdown of SELECTs composing the UNION
--sorted_result
SELECT a FROM federated.t12 UNION SELECT a FROM federated.t11 UNION SELECT 123;
EXPLAIN
SELECT a FROM federated.t12 UNION SELECT a FROM federated.t11
UNION SELECT 123;
--sorted_result
SELECT a FROM federated.t12 EXCEPT
SELECT 1 UNION ALL
SELECT a FROM federated.t11 EXCEPT
@ -639,9 +662,11 @@ CREATE TABLE federated.t14 (a VARCHAR(8))
ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t14';
--sorted_result
SELECT * FROM federated.t13 UNION SELECT * FROM federated.t14;
EXPLAIN SELECT * FROM federated.t13 UNION SELECT * FROM federated.t14;
--sorted_result
SELECT * FROM federated.t14 UNION ALL SELECT * FROM federated.t13;
SELECT * FROM federated.t14 UNION
@ -652,6 +677,7 @@ EXPLAIN SELECT * FROM federated.t14 UNION
SELECT * FROM federated.t13 UNION
SELECT '123456789000';
--sorted_result
SELECT * FROM federated.t13 UNION
SELECT '123456789000' UNION
SELECT * FROM federated.t14;
@ -671,6 +697,41 @@ SHOW CREATE TABLE t6;
--sorted_result
SELECT * FROM t6;
--echo #
--echo # MDEV-30828 ORDER BY clause using an integer (positional argument)
--echo #
SELECT a FROM federated.t1 UNION SELECT a FROM federated.t2 ORDER BY 1;
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY a DESC;
--echo # Check handling of incorrect ORDER BY clause
--error ER_BAD_FIELD_ERROR
SELECT a FROM federated.t1 UNION SELECT a FROM federated.t2 ORDER BY 2;
--error ER_BAD_FIELD_ERROR
PREPARE stmt FROM
"SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY 2";
--error ER_BAD_FIELD_ERROR
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY 2,1,3;
--error ER_TABLENAME_NOT_ALLOWED_HERE
SELECT a FROM federated.t1 UNION ALL SELECT a FROM federated.t2 ORDER BY t1.a;
SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 UNION ALL
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1
ORDER BY 1;
--error ER_BAD_FIELD_ERROR
SELECT * from federated.t1 INTERSECT
SELECT * from federated.t2 UNION ALL
SELECT * from federated.t2 EXCEPT
SELECT * from federated.t1
ORDER BY 3;
--echo # UNION of mixed Federated/MyISAM tables, pushing parts of UNIONs
SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY a;
--error ER_BAD_FIELD_ERROR
SELECT * FROM federated.t1 UNION SELECT * FROM t3 ORDER BY 2;
# Cleanup
connection master;
DROP TABLES federated.t1, federated.t2, t3, t4, t5, t6, federated.t11,

View File

@ -1057,6 +1057,8 @@ private:
bool exec_inner();
bool is_derived_eliminated() const;
bool set_direct_union_result(select_result *sel_result);
bool prepare_pushdown(bool use_direct_union_result,
select_result *sel_result);
};
typedef class st_select_lex_unit SELECT_LEX_UNIT;

View File

@ -563,6 +563,7 @@ void JOIN::init(THD *thd_arg, List<Item> &fields_arg,
sjm_scan_tables= 0;
is_orig_degenerated= false;
with_ties_order_count= 0;
prepared= false;
};
@ -1816,6 +1817,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
unit= unit_arg;
if (prepare_stage2())
goto err;
prepared= true;
DBUG_RETURN(0); // All OK
@ -5185,7 +5187,8 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
}
else
{
if ((err= join->prepare(tables, conds, og_num, order, false, group,
if (!join->prepared &&
(err= join->prepare(tables, conds, og_num, order, false, group,
having, proc_param, select_lex, unit)))
{
goto err;
@ -5211,7 +5214,8 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
DBUG_RETURN(TRUE);
THD_STAGE_INFO(thd, stage_init);
thd->lex->used_tables=0;
if ((err= join->prepare(tables, conds, og_num, order, false, group, having,
if (!join->prepared &&
(err= join->prepare(tables, conds, og_num, order, false, group, having,
proc_param, select_lex, unit)))
{
goto err;

View File

@ -1596,6 +1596,8 @@ public:
*/
bool impossible_where;
bool prepared;
/*
All fields used in the query processing.

View File

@ -1759,24 +1759,6 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
goto err;
cont:
pushdown_unit= find_unit_handler(thd, this);
if (pushdown_unit)
{
if (unlikely(pushdown_unit->prepare()))
goto err;
/*
Always use select_union_direct result for pushed down units, overwrite
the previous union_result unless select_union_direct is already used
*/
if (!use_direct_union_result)
{
if (unlikely(set_direct_union_result(sel_result)))
goto err;
fake_select_lex= NULL;
instantiate_tmp_table= false;
use_direct_union_result= true;
}
}
/*
If the query is using select_union_direct, we have postponed
preparation of the underlying select_result until column types
@ -1919,18 +1901,22 @@ cont:
if (unlikely(saved_error))
goto err;
if (fake_select_lex != NULL &&
(thd->stmt_arena->is_stmt_prepare() ||
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
}
else
{
/* Validate the global parameters of this union */
/*
We're in execution of a prepared statement or stored procedure:
reset field items to point at fields from the created temporary table.
*/
table->reset_item_list(&item_list, hidden);
}
if (fake_select_lex != NULL)
{
init_prepare_fake_select_lex(thd, TRUE);
/* Should be done only once (the only item_list per statement) */
DBUG_ASSERT(fake_select_lex->join == 0);
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->variables.option_bits,
result)))
if (!(fake_select_lex->join= new JOIN(thd, item_list, options, result)))
{
fake_select_lex->table_list.empty();
DBUG_RETURN(TRUE);
@ -1949,33 +1935,20 @@ cont:
allocation in setup_ref_array().
*/
fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
}
}
else
{
/*
We're in execution of a prepared statement or stored procedure:
reset field items to point at fields from the created temporary table.
*/
table->reset_item_list(&item_list, hidden);
}
if (fake_select_lex != NULL &&
(thd->stmt_arena->is_stmt_prepare() ||
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
{
if (!fake_select_lex->join &&
!(fake_select_lex->join=
new JOIN(thd, item_list, thd->variables.option_bits, result)))
{
fake_select_lex->table_list.empty();
DBUG_RETURN(TRUE);
}
saved_error= fake_select_lex->join->
prepare(fake_select_lex->table_list.first, 0,
fake_select_lex->join->no_const_tables= TRUE;
saved_error= fake_select_lex->join->prepare(
fake_select_lex->table_list.first, 0,
global_parameters()->order_list.elements, // og_num
global_parameters()->order_list.first, // order
false, NULL, NULL, NULL, fake_select_lex, this);
fake_select_lex->table_list.empty();
}
if (!thd->lex->is_view_context_analysis())
pushdown_unit= find_unit_handler(thd, this);
if (pushdown_unit)
{
if (prepare_pushdown(use_direct_union_result, sel_result))
goto err;
}
}
@ -1989,6 +1962,36 @@ err:
DBUG_RETURN(TRUE);
}
/**
@brief
Prepare st_select_lex_unit for the pushdown handler processing
@details
Creates and initializes data structures required for processing of the
pushdown handler. Validates fake_select_lex then discards it and sets
direct union result which is necessary for pushed down statements
@return
false - success
true - failure
*/
bool st_select_lex_unit::prepare_pushdown(bool use_direct_union_result,
select_result *sel_result)
{
if (unlikely(pushdown_unit->prepare()))
return true;
if(!use_direct_union_result)
{
/*
Always use select_union_direct result for pushed down units, overwrite
the previous union_result unless select_union_direct is already used
*/
if (unlikely(set_direct_union_result(sel_result)))
return true;
}
return false;
}
bool st_select_lex_unit::set_direct_union_result(select_result *sel_result)
{
SELECT_LEX *last= first_select();
@ -2466,44 +2469,12 @@ bool st_select_lex_unit::exec_inner()
saved_error= true;
set_limit(global_parameters());
init_prepare_fake_select_lex(thd, first_execution);
JOIN *join= fake_select_lex->join;
saved_error= false;
if (!join)
if (!(thd->stmt_arena->is_stmt_prepare() ||
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)) &&
first_execution)
{
/*
allocate JOIN for fake select only once (prevent
mysql_select automatic allocation)
TODO: The above is nonsense. mysql_select() will not allocate the
join if one already exists. There must be some other reason why we
don't let it allocate the join. Perhaps this is because we need
some special parameter values passed to join constructor?
*/
if (unlikely(!(fake_select_lex->join=
new JOIN(thd, item_list, fake_select_lex->options,
result))))
{
fake_select_lex->table_list.empty();
goto err;
}
fake_select_lex->join->no_const_tables= TRUE;
/*
Fake st_select_lex should have item list for correct ref_array
allocation.
*/
fake_select_lex->item_list= item_list;
/*
We need to add up n_sum_items in order to make the correct
allocation in setup_ref_array().
Don't add more sum_items if we have already done JOIN::prepare
for this (with a different join object)
*/
if (fake_select_lex->ref_pointer_array.is_null())
fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
if (!was_executed)
save_union_explain_part2(thd->lex->explain);
saved_error= mysql_select(thd, &result_table_list,
@ -2527,7 +2498,6 @@ bool st_select_lex_unit::exec_inner()
subquery execution rather than EXPLAIN line production. In order
to reset them back, we re-do all of the actions (yes it is ugly):
*/ // psergey-todo: is the above really necessary anymore??
join->init(thd, item_list, fake_select_lex->options, result);
saved_error= mysql_select(thd, &result_table_list, item_list, NULL,
global_parameters()->order_list.elements,
global_parameters()->order_list.first,
@ -2557,7 +2527,6 @@ bool st_select_lex_unit::exec_inner()
}
}
thd->lex->current_select= lex_select_save;
err:
thd->lex->set_limit_rows_examined();
return saved_error;
}
@ -2822,12 +2791,9 @@ bool st_select_lex_unit::change_result(select_result_interceptor *new_result,
if (sl->join->change_result(new_result, old_result))
return true; /* purecov: inspected */
}
/*
If there were a fake_select_lex->join, we would have to change the
result of that also, but change_result() is called before such an
object is created.
*/
DBUG_ASSERT(fake_select_lex == NULL || fake_select_lex->join == NULL);
if (fake_select_lex && fake_select_lex->join)
fake_select_lex->join->change_result(new_result, old_result);
return false;
}