Preparatory (and the most problematic) patch for Bug#7306
"the server side preparedStatement error for LIMIT placeholder", which moves all uses of LIMIT clause from PREPARE to OPTIMIZE and later steps. After-review fixes.
This commit is contained in:
parent
248a6934bb
commit
2d6a70c42a
@ -133,13 +133,13 @@ Table Op Msg_type Msg_text
|
|||||||
test.t3 analyze status Table is already up to date
|
test.t3 analyze status Table is already up to date
|
||||||
explain select a1, min(a2) from t1 group by a1;
|
explain select a1, min(a2) from t1 group by a1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 5 Using index for group-by
|
||||||
explain select a1, max(a2) from t1 group by a1;
|
explain select a1, max(a2) from t1 group by a1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
||||||
explain select a1, min(a2), max(a2) from t1 group by a1;
|
explain select a1, min(a2), max(a2) from t1 group by a1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 5 Using index for group-by
|
||||||
explain select a1, a2, b, min(c), max(c) from t1 group by a1,a2,b;
|
explain select a1, a2, b, min(c), max(c) from t1 group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
||||||
@ -151,13 +151,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t2 range NULL idx_t2_1 # NULL # Using index for group-by
|
1 SIMPLE t2 range NULL idx_t2_1 # NULL # Using index for group-by
|
||||||
explain select min(a2), a1, max(a2), min(a2), a1 from t1 group by a1;
|
explain select min(a2), a1, max(a2), min(a2), a1 from t1 group by a1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 5 Using index for group-by
|
||||||
explain select a1, b, min(c), a1, max(c), b, a2, max(c), max(c) from t1 group by a1, a2, b;
|
explain select a1, b, min(c), a1, max(c), b, a2, max(c), max(c) from t1 group by a1, a2, b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
||||||
explain select min(a2) from t1 group by a1;
|
explain select min(a2) from t1 group by a1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 65 NULL 5 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 5 Using index for group-by
|
||||||
explain select a2, min(c), max(c) from t1 group by a1,a2,b;
|
explain select a2, min(c), max(c) from t1 group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using index for group-by
|
||||||
@ -1404,7 +1404,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 163 NULL # Using where; Using index for group-by
|
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 163 NULL # Using where; Using index for group-by
|
||||||
explain select a1,a2,b,min(c) from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
|
explain select a1,a2,b,min(c) from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c') group by a1,a2,b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by
|
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 163 NULL # Using where; Using index for group-by
|
||||||
select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
|
select a1,a2,b,min(c),max(c) from t1 where (a1 >= 'c' or a2 < 'b') and (b > 'a') group by a1,a2,b;
|
||||||
a1 a2 b min(c) max(c)
|
a1 a2 b min(c) max(c)
|
||||||
a a b e112 h112
|
a a b e112 h112
|
||||||
@ -1838,7 +1838,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 10 Using where; Using index for group-by
|
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 10 Using where; Using index for group-by
|
||||||
explain select concat(ord(min(b)),ord(max(b))),min(b),max(b) from t1 group by a1,a2;
|
explain select concat(ord(min(b)),ord(max(b))),min(b),max(b) from t1 group by a1,a2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 range NULL idx_t1_1 130 NULL 9 Using index for group-by
|
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 9 Using index for group-by
|
||||||
select a1,a2,b, concat(min(c), max(c)) from t1 where a1 < 'd' group by a1,a2,b;
|
select a1,a2,b, concat(min(c), max(c)) from t1 where a1 < 'd' group by a1,a2,b;
|
||||||
a1 a2 b concat(min(c), max(c))
|
a1 a2 b concat(min(c), max(c))
|
||||||
a a a a111d111
|
a a a a111d111
|
||||||
|
@ -537,8 +537,6 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
|
|||||||
null_value= 0; //can't be NULL
|
null_value= 0; //can't be NULL
|
||||||
maybe_null= 0; //can't be NULL
|
maybe_null= 0; //can't be NULL
|
||||||
value= 0;
|
value= 0;
|
||||||
// We need only 1 row to determinate existence
|
|
||||||
select_lex->master_unit()->global_parameters->select_limit= 1;
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,6 +603,8 @@ void Item_exists_subselect::fix_length_and_dec()
|
|||||||
decimals= 0;
|
decimals= 0;
|
||||||
max_length= 1;
|
max_length= 1;
|
||||||
max_columns= engine->cols();
|
max_columns= engine->cols();
|
||||||
|
/* We need only 1 row to determinate existence */
|
||||||
|
unit->global_parameters->select_limit= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Item_exists_subselect::val_real()
|
double Item_exists_subselect::val_real()
|
||||||
@ -854,9 +854,6 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Item_maxmin_subselect *item;
|
Item_maxmin_subselect *item;
|
||||||
// remove LIMIT placed by ALL/ANY subquery
|
|
||||||
select_lex->master_unit()->global_parameters->select_limit=
|
|
||||||
HA_POS_ERROR;
|
|
||||||
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
|
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
|
||||||
if (upper_item)
|
if (upper_item)
|
||||||
upper_item->set_sub_test(item);
|
upper_item->set_sub_test(item);
|
||||||
@ -1286,13 +1283,10 @@ subselect_single_select_engine(st_select_lex *select,
|
|||||||
select_subselect *result,
|
select_subselect *result,
|
||||||
Item_subselect *item)
|
Item_subselect *item)
|
||||||
:subselect_engine(item, result),
|
:subselect_engine(item, result),
|
||||||
prepared(0), optimized(0), executed(0), join(0)
|
prepared(0), optimized(0), executed(0),
|
||||||
|
select_lex(select), join(0)
|
||||||
{
|
{
|
||||||
select_lex= select;
|
select_lex->master_unit()->item= item;
|
||||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
|
||||||
unit->set_limit(unit->global_parameters, select_lex);
|
|
||||||
unit->item= item;
|
|
||||||
this->select_lex= select_lex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1440,7 +1434,10 @@ int subselect_single_select_engine::exec()
|
|||||||
thd->lex->current_select= select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
if (!optimized)
|
if (!optimized)
|
||||||
{
|
{
|
||||||
optimized=1;
|
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||||
|
|
||||||
|
optimized= 1;
|
||||||
|
unit->set_limit(unit->global_parameters);
|
||||||
if (join->optimize())
|
if (join->optimize())
|
||||||
{
|
{
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
|
@ -884,8 +884,7 @@ bool insert_fields(THD *thd,TABLE_LIST *tables,
|
|||||||
List_iterator<Item> *it, bool any_privileges,
|
List_iterator<Item> *it, bool any_privileges,
|
||||||
bool allocate_view_names);
|
bool allocate_view_names);
|
||||||
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
||||||
TABLE_LIST **leaves, bool refresh_only,
|
TABLE_LIST **leaves, bool select_insert);
|
||||||
bool select_insert);
|
|
||||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||||
List<Item> *sum_func_list, uint wild_num);
|
List<Item> *sum_func_list, uint wild_num);
|
||||||
bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
||||||
|
@ -7982,8 +7982,17 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (have_min && min_max_arg_part && min_max_arg_part->field->is_null())
|
else if (have_min && min_max_arg_part &&
|
||||||
|
min_max_arg_part->field->real_maybe_null())
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
If a MIN/MAX argument value is NULL, we can quickly determine
|
||||||
|
that we're in the beginning of the next group, because NULLs
|
||||||
|
are always < any other value. This allows us to quickly
|
||||||
|
determine the end of the current group and jump to the next
|
||||||
|
group (see next_min()) and thus effectively increases the
|
||||||
|
usable key length.
|
||||||
|
*/
|
||||||
max_used_key_length+= min_max_arg_len;
|
max_used_key_length+= min_max_arg_len;
|
||||||
++used_key_parts;
|
++used_key_parts;
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ db_show_routine_status(THD *thd, int type, const char *wild)
|
|||||||
|
|
||||||
tables is not VIEW for sure => we can pass 0 as condition
|
tables is not VIEW for sure => we can pass 0 as condition
|
||||||
*/
|
*/
|
||||||
setup_tables(thd, &tables, 0, &leaves, FALSE, FALSE);
|
setup_tables(thd, &tables, 0, &leaves, FALSE);
|
||||||
for (used_field= &used_fields[0];
|
for (used_field= &used_fields[0];
|
||||||
used_field->field_name;
|
used_field->field_name;
|
||||||
used_field++)
|
used_field++)
|
||||||
|
@ -3208,7 +3208,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
||||||
TABLE_LIST **leaves, bool refresh, bool select_insert)
|
TABLE_LIST **leaves, bool select_insert)
|
||||||
{
|
{
|
||||||
uint tablenr= 0;
|
uint tablenr= 0;
|
||||||
DBUG_ENTER("setup_tables");
|
DBUG_ENTER("setup_tables");
|
||||||
@ -3261,17 +3261,14 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
|||||||
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
|
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (!refresh)
|
for (TABLE_LIST *table_list= tables;
|
||||||
|
table_list;
|
||||||
|
table_list= table_list->next_local)
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *table_list= tables;
|
if (table_list->ancestor &&
|
||||||
table_list;
|
table_list->setup_ancestor(thd, conds,
|
||||||
table_list= table_list->next_local)
|
table_list->effective_with_check))
|
||||||
{
|
DBUG_RETURN(1);
|
||||||
if (table_list->ancestor &&
|
|
||||||
table_list->setup_ancestor(thd, conds,
|
|
||||||
table_list->effective_with_check))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@ -300,8 +300,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
|
|||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
DBUG_ENTER("mysql_prepare_delete");
|
DBUG_ENTER("mysql_prepare_delete");
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
|
if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
|
||||||
FALSE, FALSE) ||
|
|
||||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
setup_ftfuncs(select_lex))
|
setup_ftfuncs(select_lex))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -358,7 +357,7 @@ bool mysql_multi_delete_prepare(THD *thd)
|
|||||||
lex->query_tables also point on local list of DELETE SELECT_LEX
|
lex->query_tables also point on local list of DELETE SELECT_LEX
|
||||||
*/
|
*/
|
||||||
if (setup_tables(thd, lex->query_tables, &lex->select_lex.where,
|
if (setup_tables(thd, lex->query_tables, &lex->select_lex.where,
|
||||||
&lex->select_lex.leaf_tables, FALSE, FALSE))
|
&lex->select_lex.leaf_tables, FALSE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ bool mysqld_help(THD *thd, const char *mask)
|
|||||||
|
|
||||||
tables do not contain VIEWs => we can pass 0 as conds
|
tables do not contain VIEWs => we can pass 0 as conds
|
||||||
*/
|
*/
|
||||||
setup_tables(thd, tables, 0, &leaves, FALSE, FALSE);
|
setup_tables(thd, tables, 0, &leaves, FALSE);
|
||||||
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
|
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
|
||||||
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -699,7 +699,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
|||||||
DBUG_ENTER("mysql_prepare_insert_check_table");
|
DBUG_ENTER("mysql_prepare_insert_check_table");
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
|
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
|
||||||
FALSE, select_insert))
|
select_insert))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (insert_into_view && !fields.elements)
|
if (insert_into_view && !fields.elements)
|
||||||
|
@ -1369,8 +1369,6 @@ bool st_select_lex::test_limit()
|
|||||||
"LIMIT & IN/ALL/ANY/SOME subquery");
|
"LIMIT & IN/ALL/ANY/SOME subquery");
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
// We need only 1 row to determinate existence
|
|
||||||
select_limit= 1;
|
|
||||||
// no sense in ORDER BY without LIMIT
|
// no sense in ORDER BY without LIMIT
|
||||||
order_list.empty();
|
order_list.empty();
|
||||||
return(0);
|
return(0);
|
||||||
@ -1553,7 +1551,7 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
|||||||
item->substype() == Item_subselect::IN_SUBS ||
|
item->substype() == Item_subselect::IN_SUBS ||
|
||||||
item->substype() == Item_subselect::ALL_SUBS))
|
item->substype() == Item_subselect::ALL_SUBS))
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(select_limit == 1L && offset_limit == 0L);
|
DBUG_ASSERT(!item->fixed || select_limit == 1L && offset_limit == 0L);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1756,11 +1754,9 @@ bool st_lex::need_correct_ident()
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
st_select_lex_unit::set_limit()
|
st_select_lex_unit::set_limit()
|
||||||
values - SELECT_LEX with initial values for counters
|
values - SELECT_LEX with initial values for counters
|
||||||
sl - SELECT_LEX for options set
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void st_select_lex_unit::set_limit(SELECT_LEX *values,
|
void st_select_lex_unit::set_limit(SELECT_LEX *values)
|
||||||
SELECT_LEX *sl)
|
|
||||||
{
|
{
|
||||||
offset_limit_cnt= values->offset_limit;
|
offset_limit_cnt= values->offset_limit;
|
||||||
select_limit_cnt= values->select_limit+values->offset_limit;
|
select_limit_cnt= values->select_limit+values->offset_limit;
|
||||||
|
@ -445,10 +445,10 @@ public:
|
|||||||
|
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
|
|
||||||
ulong init_prepare_fake_select_lex(THD *thd);
|
void init_prepare_fake_select_lex(THD *thd);
|
||||||
inline bool is_prepared() { return prepared; }
|
inline bool is_prepared() { return prepared; }
|
||||||
bool change_result(select_subselect *result, select_subselect *old_result);
|
bool change_result(select_subselect *result, select_subselect *old_result);
|
||||||
void set_limit(st_select_lex *values, st_select_lex *sl);
|
void set_limit(st_select_lex *values);
|
||||||
|
|
||||||
friend void lex_start(THD *thd, uchar *buf, uint length);
|
friend void lex_start(THD *thd, uchar *buf, uint length);
|
||||||
friend int subselect_union_engine::exec();
|
friend int subselect_union_engine::exec();
|
||||||
|
@ -150,7 +150,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (setup_tables(thd, table_list, &unused_conds,
|
if (setup_tables(thd, table_list, &unused_conds,
|
||||||
&thd->lex->select_lex.leaf_tables, FALSE, FALSE))
|
&thd->lex->select_lex.leaf_tables, FALSE))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (!table_list->table || // do not suport join view
|
if (!table_list->table || // do not suport join view
|
||||||
!table_list->updatable || // and derived tables
|
!table_list->updatable || // and derived tables
|
||||||
|
@ -153,8 +153,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
|
|||||||
|
|
||||||
|
|
||||||
if (setup_tables(lex->thd, (TABLE_LIST *)select_lex->table_list.first
|
if (setup_tables(lex->thd, (TABLE_LIST *)select_lex->table_list.first
|
||||||
&select_lex->where, &select_lex->leaf_tables,
|
&select_lex->where, &select_lex->leaf_tables, FALSE) ||
|
||||||
FALSE, FALSE) ||
|
|
||||||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||||
select_lex->item_list, 1, &all_fields,1) ||
|
select_lex->item_list, 1, &all_fields,1) ||
|
||||||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||||
|
@ -2777,7 +2777,7 @@ mysql_execute_command(THD *thd)
|
|||||||
select_result *result;
|
select_result *result;
|
||||||
|
|
||||||
select_lex->options|= SELECT_NO_UNLOCK;
|
select_lex->options|= SELECT_NO_UNLOCK;
|
||||||
unit->set_limit(select_lex, select_lex);
|
unit->set_limit(select_lex);
|
||||||
|
|
||||||
if (!(res= open_and_lock_tables(thd, select_tables)))
|
if (!(res= open_and_lock_tables(thd, select_tables)))
|
||||||
{
|
{
|
||||||
@ -3175,7 +3175,7 @@ unsent_create_error:
|
|||||||
select_lex->options|= SELECT_NO_UNLOCK;
|
select_lex->options|= SELECT_NO_UNLOCK;
|
||||||
|
|
||||||
select_result *result;
|
select_result *result;
|
||||||
unit->set_limit(select_lex, select_lex);
|
unit->set_limit(select_lex);
|
||||||
|
|
||||||
if (!(res= open_and_lock_tables(thd, all_tables)))
|
if (!(res= open_and_lock_tables(thd, all_tables)))
|
||||||
{
|
{
|
||||||
|
@ -233,7 +233,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
SELECT_LEX_UNIT *unit= &lex->unit;
|
SELECT_LEX_UNIT *unit= &lex->unit;
|
||||||
unit->set_limit(unit->global_parameters, select_lex);
|
unit->set_limit(unit->global_parameters);
|
||||||
/*
|
/*
|
||||||
'options' of mysql_select will be set in JOIN, as far as JOIN for
|
'options' of mysql_select will be set in JOIN, as far as JOIN for
|
||||||
every PS/SP execution new, we will not need reset this flag if
|
every PS/SP execution new, we will not need reset this flag if
|
||||||
@ -342,7 +342,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
|
|
||||||
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
|
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
|
||||||
setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
|
setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
|
||||||
FALSE, FALSE)) ||
|
FALSE)) ||
|
||||||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
||||||
select_lex->setup_ref_array(thd, og_num) ||
|
select_lex->setup_ref_array(thd, og_num) ||
|
||||||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
||||||
@ -465,13 +465,6 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
count_field_types(&tmp_table_param, all_fields, 0);
|
count_field_types(&tmp_table_param, all_fields, 0);
|
||||||
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
|
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
|
||||||
this->group= group_list != 0;
|
this->group= group_list != 0;
|
||||||
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
|
|
||||||
unit_arg->select_limit_cnt);
|
|
||||||
/* select_limit is used to decide if we are likely to scan the whole table */
|
|
||||||
select_limit= unit_arg->select_limit_cnt;
|
|
||||||
if (having || (select_options & OPTION_FOUND_ROWS))
|
|
||||||
select_limit= HA_POS_ERROR;
|
|
||||||
do_send_rows = (unit_arg->select_limit_cnt) ? 1 : 0;
|
|
||||||
unit= unit_arg;
|
unit= unit_arg;
|
||||||
|
|
||||||
#ifdef RESTRICTED_GROUP
|
#ifdef RESTRICTED_GROUP
|
||||||
@ -550,6 +543,13 @@ JOIN::optimize()
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
optimized= 1;
|
optimized= 1;
|
||||||
|
|
||||||
|
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
|
||||||
|
unit->select_limit_cnt);
|
||||||
|
/* select_limit is used to decide if we are likely to scan the whole table */
|
||||||
|
select_limit= unit->select_limit_cnt;
|
||||||
|
if (having || (select_options & OPTION_FOUND_ROWS))
|
||||||
|
select_limit= HA_POS_ERROR;
|
||||||
|
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
||||||
// Ignore errors of execution if option IGNORE present
|
// Ignore errors of execution if option IGNORE present
|
||||||
if (thd->lex->ignore)
|
if (thd->lex->ignore)
|
||||||
thd->lex->current_select->no_error= 1;
|
thd->lex->current_select->no_error= 1;
|
||||||
@ -1110,18 +1110,7 @@ int
|
|||||||
JOIN::reinit()
|
JOIN::reinit()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::reinit");
|
DBUG_ENTER("JOIN::reinit");
|
||||||
/* TODO move to unit reinit */
|
|
||||||
unit->set_limit(select_lex, select_lex);
|
|
||||||
|
|
||||||
/* conds should not be used here, it is added just for safety */
|
|
||||||
if (tables_list)
|
|
||||||
{
|
|
||||||
if (setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
|
|
||||||
TRUE, FALSE))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset of sum functions */
|
|
||||||
first_record= 0;
|
first_record= 0;
|
||||||
|
|
||||||
if (exec_tmp_table1)
|
if (exec_tmp_table1)
|
||||||
@ -1147,6 +1136,7 @@ JOIN::reinit()
|
|||||||
if (tmp_join)
|
if (tmp_join)
|
||||||
restore_tmp();
|
restore_tmp();
|
||||||
|
|
||||||
|
/* Reset of sum functions */
|
||||||
if (sum_funcs)
|
if (sum_funcs)
|
||||||
{
|
{
|
||||||
Item_sum *func, **func_ptr= sum_funcs;
|
Item_sum *func, **func_ptr= sum_funcs;
|
||||||
@ -13485,7 +13475,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
thd->lex->current_select= first;
|
thd->lex->current_select= first;
|
||||||
unit->set_limit(unit->global_parameters, first);
|
unit->set_limit(unit->global_parameters);
|
||||||
res= mysql_select(thd, &first->ref_pointer_array,
|
res= mysql_select(thd, &first->ref_pointer_array,
|
||||||
(TABLE_LIST*) first->table_list.first,
|
(TABLE_LIST*) first->table_list.first,
|
||||||
first->with_wild, first->item_list,
|
first->with_wild, first->item_list,
|
||||||
|
@ -115,27 +115,15 @@ bool select_union::flush()
|
|||||||
options of SELECT
|
options of SELECT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulong
|
void
|
||||||
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
|
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
|
||||||
{
|
{
|
||||||
ulong options_tmp= thd->options | fake_select_lex->options;
|
|
||||||
thd->lex->current_select= fake_select_lex;
|
thd->lex->current_select= fake_select_lex;
|
||||||
offset_limit_cnt= global_parameters->offset_limit;
|
|
||||||
select_limit_cnt= global_parameters->select_limit +
|
|
||||||
global_parameters->offset_limit;
|
|
||||||
|
|
||||||
if (select_limit_cnt < global_parameters->select_limit)
|
|
||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
|
||||||
if (select_limit_cnt == HA_POS_ERROR)
|
|
||||||
options_tmp&= ~OPTION_FOUND_ROWS;
|
|
||||||
else if (found_rows_for_union && !thd->lex->describe)
|
|
||||||
options_tmp|= OPTION_FOUND_ROWS;
|
|
||||||
fake_select_lex->ftfunc_list_alloc.empty();
|
fake_select_lex->ftfunc_list_alloc.empty();
|
||||||
fake_select_lex->ftfunc_list= &fake_select_lex->ftfunc_list_alloc;
|
fake_select_lex->ftfunc_list= &fake_select_lex->ftfunc_list_alloc;
|
||||||
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
|
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
|
||||||
(byte **)
|
(byte **)
|
||||||
&result_table_list.next_local);
|
&result_table_list.next_local);
|
||||||
return options_tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,10 +205,9 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
thd_arg->lex->current_select= sl;
|
thd_arg->lex->current_select= sl;
|
||||||
set_limit(sl, sl);
|
|
||||||
|
|
||||||
can_skip_order_by= is_union &&
|
can_skip_order_by= is_union &&
|
||||||
(!sl->braces || select_limit_cnt == HA_POS_ERROR);
|
(!sl->braces || sl->select_limit == HA_POS_ERROR);
|
||||||
|
|
||||||
res= join->prepare(&sl->ref_pointer_array,
|
res= join->prepare(&sl->ref_pointer_array,
|
||||||
(TABLE_LIST*) sl->table_list.first, sl->with_wild,
|
(TABLE_LIST*) sl->table_list.first, sl->with_wild,
|
||||||
@ -340,7 +327,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
if (arena->is_stmt_prepare())
|
if (arena->is_stmt_prepare())
|
||||||
{
|
{
|
||||||
/* prepare fake select to initialize it correctly */
|
/* prepare fake select to initialize it correctly */
|
||||||
(void) init_prepare_fake_select_lex(thd);
|
init_prepare_fake_select_lex(thd);
|
||||||
/*
|
/*
|
||||||
Should be done only once (the only item_list per statement).
|
Should be done only once (the only item_list per statement).
|
||||||
*/
|
*/
|
||||||
@ -429,12 +416,8 @@ bool st_select_lex_unit::exec()
|
|||||||
res= sl->join->reinit();
|
res= sl->join->reinit();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sl != global_parameters && !describe)
|
set_limit(sl);
|
||||||
{
|
if (sl == global_parameters || describe)
|
||||||
offset_limit_cnt= sl->offset_limit;
|
|
||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
offset_limit_cnt= 0;
|
offset_limit_cnt= 0;
|
||||||
/*
|
/*
|
||||||
@ -443,11 +426,7 @@ bool st_select_lex_unit::exec()
|
|||||||
*/
|
*/
|
||||||
if (sl->order_list.first || describe)
|
if (sl->order_list.first || describe)
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
select_limit_cnt= HA_POS_ERROR;
|
||||||
else
|
}
|
||||||
select_limit_cnt= sl->select_limit+sl->offset_limit;
|
|
||||||
}
|
|
||||||
if (select_limit_cnt < sl->select_limit)
|
|
||||||
select_limit_cnt= HA_POS_ERROR; // no limit
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
||||||
@ -512,7 +491,8 @@ bool st_select_lex_unit::exec()
|
|||||||
|
|
||||||
if (!thd->is_fatal_error) // Check if EOM
|
if (!thd->is_fatal_error) // Check if EOM
|
||||||
{
|
{
|
||||||
ulong options_tmp= init_prepare_fake_select_lex(thd);
|
set_limit(global_parameters);
|
||||||
|
init_prepare_fake_select_lex(thd);
|
||||||
JOIN *join= fake_select_lex->join;
|
JOIN *join= fake_select_lex->join;
|
||||||
if (!join)
|
if (!join)
|
||||||
{
|
{
|
||||||
|
@ -557,8 +557,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
tables.table= table;
|
tables.table= table;
|
||||||
tables.alias= table_list->alias;
|
tables.alias= table_list->alias;
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
|
if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
|
||||||
FALSE, FALSE) ||
|
|
||||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
select_lex->setup_ref_array(thd, order_num) ||
|
select_lex->setup_ref_array(thd, order_num) ||
|
||||||
setup_order(thd, select_lex->ref_pointer_array,
|
setup_order(thd, select_lex->ref_pointer_array,
|
||||||
@ -644,7 +643,7 @@ bool mysql_multi_update_prepare(THD *thd)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, &lex->select_lex.where,
|
if (setup_tables(thd, table_list, &lex->select_lex.where,
|
||||||
&lex->select_lex.leaf_tables, FALSE, FALSE))
|
&lex->select_lex.leaf_tables, FALSE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
leaves= lex->select_lex.leaf_tables;
|
leaves= lex->select_lex.leaf_tables;
|
||||||
|
|
||||||
@ -764,7 +763,7 @@ bool mysql_multi_update_prepare(THD *thd)
|
|||||||
tbl->cleanup_items();
|
tbl->cleanup_items();
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, &lex->select_lex.where,
|
if (setup_tables(thd, table_list, &lex->select_lex.where,
|
||||||
&lex->select_lex.leaf_tables, FALSE, FALSE) ||
|
&lex->select_lex.leaf_tables, FALSE) ||
|
||||||
(lex->select_lex.no_wrap_view_item= 1,
|
(lex->select_lex.no_wrap_view_item= 1,
|
||||||
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
|
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
|
||||||
lex->select_lex.no_wrap_view_item= 0,
|
lex->select_lex.no_wrap_view_item= 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user