MDEV-18553: MDEV-16327 pre-requisits part 1: isolation of LIMIT/OFFSET handling
This commit is contained in:
parent
8336371441
commit
eb0804ef5e
@ -40,7 +40,7 @@ int Pushdown_query::execute(JOIN *join)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
ha_rows max_limit;
|
ha_rows max_limit;
|
||||||
ha_rows *reset_limit= 0;
|
bool reset_limit= FALSE;
|
||||||
Item **reset_item= 0;
|
Item **reset_item= 0;
|
||||||
THD *thd= handler->thd;
|
THD *thd= handler->thd;
|
||||||
TABLE *table= handler->table;
|
TABLE *table= handler->table;
|
||||||
@ -52,11 +52,11 @@ int Pushdown_query::execute(JOIN *join)
|
|||||||
if (store_data_in_temp_table)
|
if (store_data_in_temp_table)
|
||||||
{
|
{
|
||||||
max_limit= join->tmp_table_param.end_write_records;
|
max_limit= join->tmp_table_param.end_write_records;
|
||||||
reset_limit= &join->unit->select_limit_cnt;
|
reset_limit= TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
max_limit= join->unit->select_limit_cnt;
|
max_limit= join->unit->lim.get_select_limit();
|
||||||
if (join->unit->fake_select_lex)
|
if (join->unit->fake_select_lex)
|
||||||
reset_item= &join->unit->fake_select_lex->select_limit;
|
reset_item= &join->unit->fake_select_lex->select_limit;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ int Pushdown_query::execute(JOIN *join)
|
|||||||
break; // LIMIT reached
|
break; // LIMIT reached
|
||||||
join->do_send_rows= 0; // Calculate FOUND_ROWS()
|
join->do_send_rows= 0; // Calculate FOUND_ROWS()
|
||||||
if (reset_limit)
|
if (reset_limit)
|
||||||
*reset_limit= HA_POS_ERROR;
|
join->unit->lim.set_unlimited();
|
||||||
if (reset_item)
|
if (reset_item)
|
||||||
*reset_item= 0;
|
*reset_item= 0;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ struct Query
|
|||||||
ORDER *order_by;
|
ORDER *order_by;
|
||||||
Item *having;
|
Item *having;
|
||||||
// LIMIT
|
// LIMIT
|
||||||
|
//ha_rows select_limit_cnt, offset_limit_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
class group_by_handler
|
class group_by_handler
|
||||||
|
@ -2744,7 +2744,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
|
|||||||
join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
|
join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
|
||||||
new (thd->mem_root)
|
new (thd->mem_root)
|
||||||
Item_int(thd, (int32) 1));
|
Item_int(thd, (int32) 1));
|
||||||
unit->select_limit_cnt= 1;
|
unit->lim.set_single_row();
|
||||||
|
|
||||||
DBUG_RETURN(false);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
@ -5714,11 +5714,8 @@ int select_value_catcher::send_data(List<Item> &items)
|
|||||||
DBUG_ASSERT(!assigned);
|
DBUG_ASSERT(!assigned);
|
||||||
DBUG_ASSERT(items.elements == n_elements);
|
DBUG_ASSERT(items.elements == n_elements);
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // Using limit offset,count
|
DBUG_RETURN(0); // Using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item *val_item;
|
Item *val_item;
|
||||||
List_iterator_fast<Item> li(items);
|
List_iterator_fast<Item> li(items);
|
||||||
@ -6574,7 +6571,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
|
|||||||
Set the limit of this JOIN object as well, because normally its being
|
Set the limit of this JOIN object as well, because normally its being
|
||||||
set in the beginning of JOIN::optimize, which was already done.
|
set in the beginning of JOIN::optimize, which was already done.
|
||||||
*/
|
*/
|
||||||
select_limit= in_subs->unit->select_limit_cnt;
|
select_limit= in_subs->unit->lim.get_select_limit();
|
||||||
}
|
}
|
||||||
else if (in_subs->test_strategy(SUBS_IN_TO_EXISTS))
|
else if (in_subs->test_strategy(SUBS_IN_TO_EXISTS))
|
||||||
{
|
{
|
||||||
|
@ -3016,11 +3016,8 @@ int select_send::send_data(List<Item> &items)
|
|||||||
DBUG_ENTER("select_send::send_data");
|
DBUG_ENTER("select_send::send_data");
|
||||||
|
|
||||||
/* unit is not set when using 'delete ... returning' */
|
/* unit is not set when using 'delete ... returning' */
|
||||||
if (unit && unit->offset_limit_cnt)
|
if (unit && unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
DBUG_RETURN(FALSE); // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
@ -3285,11 +3282,8 @@ int select_export::send_data(List<Item> &items)
|
|||||||
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
DBUG_RETURN(0); // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
row_count++;
|
row_count++;
|
||||||
@ -3545,11 +3539,8 @@ int select_dump::send_data(List<Item> &items)
|
|||||||
Item *item;
|
Item *item;
|
||||||
DBUG_ENTER("select_dump::send_data");
|
DBUG_ENTER("select_dump::send_data");
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
DBUG_RETURN(0); // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -3588,11 +3579,8 @@ int select_singlerow_subselect::send_data(List<Item> &items)
|
|||||||
MYF(current_thd->lex->ignore ? ME_WARNING : 0));
|
MYF(current_thd->lex->ignore ? ME_WARNING : 0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // Using limit offset,count
|
DBUG_RETURN(0); // Using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
List_iterator_fast<Item> li(items);
|
List_iterator_fast<Item> li(items);
|
||||||
@ -3729,11 +3717,8 @@ int select_exists_subselect::send_data(List<Item> &items)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("select_exists_subselect::send_data");
|
DBUG_ENTER("select_exists_subselect::send_data");
|
||||||
Item_exists_subselect *it= (Item_exists_subselect *)item;
|
Item_exists_subselect *it= (Item_exists_subselect *)item;
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // Using limit offset,count
|
DBUG_RETURN(0); // Using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
it->value= 1;
|
it->value= 1;
|
||||||
@ -4138,12 +4123,9 @@ int select_dumpvar::send_data(List<Item> &items)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("select_dumpvar::send_data");
|
DBUG_ENTER("select_dumpvar::send_data");
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
DBUG_RETURN(0); // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
if (row_count++)
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (row_count++)
|
|
||||||
{
|
{
|
||||||
my_message(ER_TOO_MANY_ROWS, ER_THD(thd, ER_TOO_MANY_ROWS), MYF(0));
|
my_message(ER_TOO_MANY_ROWS, ER_THD(thd, ER_TOO_MANY_ROWS), MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@ -5196,9 +5196,9 @@ public:
|
|||||||
/* this method is called just before the first row of the table can be read */
|
/* this method is called just before the first row of the table can be read */
|
||||||
virtual void prepare_to_read_rows() {}
|
virtual void prepare_to_read_rows() {}
|
||||||
|
|
||||||
void reset_offset_limit()
|
void remove_offset_limit()
|
||||||
{
|
{
|
||||||
unit->offset_limit_cnt= 0;
|
unit->lim.remove_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6009,7 +6009,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(false); /* purecov: inspected */
|
DBUG_ASSERT(false); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
void reset_offset_limit_cnt()
|
void remove_offset_limit()
|
||||||
{
|
{
|
||||||
// EXPLAIN should never output to a select_union_direct
|
// EXPLAIN should never output to a select_union_direct
|
||||||
DBUG_ASSERT(false); /* purecov: inspected */
|
DBUG_ASSERT(false); /* purecov: inspected */
|
||||||
|
@ -1218,7 +1218,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
|
|||||||
{
|
{
|
||||||
SELECT_LEX *first_select= unit->first_select();
|
SELECT_LEX *first_select= unit->first_select();
|
||||||
unit->set_limit(unit->global_parameters());
|
unit->set_limit(unit->global_parameters());
|
||||||
if (unit->select_limit_cnt == HA_POS_ERROR)
|
if (unit->lim.is_unlimited())
|
||||||
first_select->options&= ~OPTION_FOUND_ROWS;
|
first_select->options&= ~OPTION_FOUND_ROWS;
|
||||||
|
|
||||||
lex->current_select= first_select;
|
lex->current_select= first_select;
|
||||||
|
@ -783,7 +783,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||||||
const Sql_condition *err;
|
const Sql_condition *err;
|
||||||
SELECT_LEX *sel= thd->lex->first_select_lex();
|
SELECT_LEX *sel= thd->lex->first_select_lex();
|
||||||
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
||||||
ulonglong idx= 0;
|
ha_rows idx;
|
||||||
Protocol *protocol=thd->protocol;
|
Protocol *protocol=thd->protocol;
|
||||||
DBUG_ENTER("mysqld_show_warnings");
|
DBUG_ENTER("mysqld_show_warnings");
|
||||||
|
|
||||||
@ -808,14 +808,14 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
|
|||||||
|
|
||||||
Diagnostics_area::Sql_condition_iterator it=
|
Diagnostics_area::Sql_condition_iterator it=
|
||||||
thd->get_stmt_da()->sql_conditions();
|
thd->get_stmt_da()->sql_conditions();
|
||||||
while ((err= it++))
|
for (idx= 1; (err= it++) ; idx++)
|
||||||
{
|
{
|
||||||
/* Skip levels that the user is not interested in */
|
/* Skip levels that the user is not interested in */
|
||||||
if (!(levels_to_show & ((ulong) 1 << err->get_level())))
|
if (!(levels_to_show & ((ulong) 1 << err->get_level())))
|
||||||
continue;
|
continue;
|
||||||
if (++idx <= unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
continue;
|
continue; // using limit offset,count
|
||||||
if (idx > unit->select_limit_cnt)
|
if (idx > unit->lim.get_select_limit())
|
||||||
break;
|
break;
|
||||||
protocol->prepare_for_resend();
|
protocol->prepare_for_resend();
|
||||||
protocol->store(warning_level_names[err->get_level()].str,
|
protocol->store(warning_level_names[err->get_level()].str,
|
||||||
|
@ -3857,11 +3857,8 @@ int select_insert::send_data(List<Item> &values)
|
|||||||
DBUG_ENTER("select_insert::send_data");
|
DBUG_ENTER("select_insert::send_data");
|
||||||
bool error=0;
|
bool error=0;
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
DBUG_RETURN(0); // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
|
||||||
if (unlikely(thd->killed == ABORT_QUERY))
|
if (unlikely(thd->killed == ABORT_QUERY))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
@ -2350,8 +2350,7 @@ void st_select_lex_unit::init_query()
|
|||||||
{
|
{
|
||||||
init_query_common();
|
init_query_common();
|
||||||
set_linkage(GLOBAL_OPTIONS_TYPE);
|
set_linkage(GLOBAL_OPTIONS_TYPE);
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
lim.set_unlimited();
|
||||||
offset_limit_cnt= 0;
|
|
||||||
union_distinct= 0;
|
union_distinct= 0;
|
||||||
prepared= optimized= optimized_2= executed= 0;
|
prepared= optimized= optimized_2= executed= 0;
|
||||||
bag_set_op_optimized= 0;
|
bag_set_op_optimized= 0;
|
||||||
@ -3494,12 +3493,7 @@ void st_select_lex_unit::set_limit(st_select_lex *sl)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
|
DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
|
||||||
|
|
||||||
offset_limit_cnt= sl->get_offset();
|
lim.set_limit(sl->get_limit(), sl->get_offset());
|
||||||
select_limit_cnt= sl->get_limit();
|
|
||||||
if (select_limit_cnt + offset_limit_cnt >= select_limit_cnt)
|
|
||||||
select_limit_cnt+= offset_limit_cnt;
|
|
||||||
else
|
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "sp.h" // enum stored_procedure_type
|
#include "sp.h" // enum stored_procedure_type
|
||||||
#include "sql_tvc.h"
|
#include "sql_tvc.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
#include "sql_limit.h" // Select_limit_counters
|
||||||
|
|
||||||
/* Used for flags of nesting constructs */
|
/* Used for flags of nesting constructs */
|
||||||
#define SELECT_NESTING_MAP_SIZE 64
|
#define SELECT_NESTING_MAP_SIZE 64
|
||||||
@ -829,6 +830,8 @@ void create_explain_query(LEX *lex, MEM_ROOT *mem_root);
|
|||||||
void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root);
|
void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root);
|
||||||
bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str);
|
bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class st_select_lex_unit: public st_select_lex_node {
|
class st_select_lex_unit: public st_select_lex_node {
|
||||||
protected:
|
protected:
|
||||||
TABLE_LIST result_table_list;
|
TABLE_LIST result_table_list;
|
||||||
@ -908,7 +911,7 @@ public:
|
|||||||
//node on which we should return current_select pointer after parsing subquery
|
//node on which we should return current_select pointer after parsing subquery
|
||||||
st_select_lex *return_to;
|
st_select_lex *return_to;
|
||||||
/* LIMIT clause runtime counters */
|
/* LIMIT clause runtime counters */
|
||||||
ha_rows select_limit_cnt, offset_limit_cnt;
|
Select_limit_counters lim;
|
||||||
/* not NULL if unit used in subselect, point to subselect item */
|
/* not NULL if unit used in subselect, point to subselect item */
|
||||||
Item_subselect *item;
|
Item_subselect *item;
|
||||||
/*
|
/*
|
||||||
|
80
sql/sql_limit.h
Normal file
80
sql/sql_limit.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* Copyright (c) 2019, MariaDB Corporation.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INCLUDES_MARIADB_SQL_LIMIT_H
|
||||||
|
#define INCLUDES_MARIADB_SQL_LIMIT_H
|
||||||
|
/**
|
||||||
|
LIMIT/OFFSET parameters for execution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Select_limit_counters
|
||||||
|
{
|
||||||
|
ha_rows offset_limit_cnt_start,
|
||||||
|
select_limit_cnt, offset_limit_cnt;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Select_limit_counters():
|
||||||
|
offset_limit_cnt_start(0),
|
||||||
|
select_limit_cnt(0), offset_limit_cnt(0)
|
||||||
|
{};
|
||||||
|
|
||||||
|
void set_limit(ha_rows limit, ha_rows offset)
|
||||||
|
{
|
||||||
|
offset_limit_cnt_start= offset;
|
||||||
|
select_limit_cnt= limit;
|
||||||
|
if (select_limit_cnt + offset_limit_cnt_start >=
|
||||||
|
select_limit_cnt)
|
||||||
|
select_limit_cnt+= offset_limit_cnt_start;
|
||||||
|
else
|
||||||
|
select_limit_cnt= HA_POS_ERROR;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_single_row()
|
||||||
|
{
|
||||||
|
offset_limit_cnt= offset_limit_cnt_start= 0;
|
||||||
|
select_limit_cnt= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
offset_limit_cnt= offset_limit_cnt_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_unlimited()
|
||||||
|
{ return select_limit_cnt == HA_POS_ERROR; }
|
||||||
|
void set_unlimited()
|
||||||
|
{ select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; }
|
||||||
|
|
||||||
|
bool check_and_move_offset()
|
||||||
|
{
|
||||||
|
if (offset_limit_cnt)
|
||||||
|
{
|
||||||
|
offset_limit_cnt--;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
void remove_offset() { offset_limit_cnt= 0; }
|
||||||
|
|
||||||
|
ha_rows get_select_limit()
|
||||||
|
{ return select_limit_cnt; }
|
||||||
|
ha_rows get_offset_limit()
|
||||||
|
{ return offset_limit_cnt; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INCLUDES_MARIADB_SQL_LIMIT_H
|
@ -4350,7 +4350,7 @@ mysql_execute_command(THD *thd)
|
|||||||
select_lex->where,
|
select_lex->where,
|
||||||
select_lex->order_list.elements,
|
select_lex->order_list.elements,
|
||||||
select_lex->order_list.first,
|
select_lex->order_list.first,
|
||||||
unit->select_limit_cnt,
|
unit->lim.get_select_limit(),
|
||||||
lex->ignore, &found, &updated);
|
lex->ignore, &found, &updated);
|
||||||
MYSQL_UPDATE_DONE(res, found, updated);
|
MYSQL_UPDATE_DONE(res, found, updated);
|
||||||
/* mysql_update return 2 if we need to switch to multi-update */
|
/* mysql_update return 2 if we need to switch to multi-update */
|
||||||
@ -4672,7 +4672,7 @@ mysql_execute_command(THD *thd)
|
|||||||
|
|
||||||
res = mysql_delete(thd, all_tables,
|
res = mysql_delete(thd, all_tables,
|
||||||
select_lex->where, &select_lex->order_list,
|
select_lex->where, &select_lex->order_list,
|
||||||
unit->select_limit_cnt, select_lex->options,
|
unit->lim.get_select_limit(), select_lex->options,
|
||||||
lex->result ? lex->result : sel_result);
|
lex->result ? lex->result : sel_result);
|
||||||
|
|
||||||
if (replaced_protocol)
|
if (replaced_protocol)
|
||||||
@ -5518,7 +5518,8 @@ mysql_execute_command(THD *thd)
|
|||||||
|
|
||||||
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
|
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
|
||||||
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
||||||
unit->select_limit_cnt, unit->offset_limit_cnt);
|
unit->lim.get_select_limit(),
|
||||||
|
unit->lim.get_offset_limit());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_BEGIN:
|
case SQLCOM_BEGIN:
|
||||||
@ -6095,8 +6096,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
|
|||||||
/*
|
/*
|
||||||
Do like the original select_describe did: remove OFFSET from the
|
Do like the original select_describe did: remove OFFSET from the
|
||||||
top-level LIMIT
|
top-level LIMIT
|
||||||
*/
|
*/
|
||||||
result->reset_offset_limit();
|
result->remove_offset_limit();
|
||||||
if (lex->explain_json)
|
if (lex->explain_json)
|
||||||
{
|
{
|
||||||
lex->explain->print_explain_json(result, lex->analyze_stmt);
|
lex->explain->print_explain_json(result, lex->analyze_stmt);
|
||||||
@ -7668,7 +7669,7 @@ void mysql_init_multi_delete(LEX *lex)
|
|||||||
lex->sql_command= SQLCOM_DELETE_MULTI;
|
lex->sql_command= SQLCOM_DELETE_MULTI;
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
lex->first_select_lex()->select_limit= 0;
|
lex->first_select_lex()->select_limit= 0;
|
||||||
lex->unit.select_limit_cnt= HA_POS_ERROR;
|
lex->unit.lim.set_unlimited();
|
||||||
lex->first_select_lex()->table_list.
|
lex->first_select_lex()->table_list.
|
||||||
save_and_clear(&lex->auxiliary_table_list);
|
save_and_clear(&lex->auxiliary_table_list);
|
||||||
lex->query_tables= 0;
|
lex->query_tables= 0;
|
||||||
|
@ -402,7 +402,7 @@ bool PROFILING::show_profiles()
|
|||||||
MEM_ROOT *mem_root= thd->mem_root;
|
MEM_ROOT *mem_root= thd->mem_root;
|
||||||
SELECT_LEX *sel= thd->lex->first_select_lex();
|
SELECT_LEX *sel= thd->lex->first_select_lex();
|
||||||
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
||||||
ha_rows idx= 0;
|
ha_rows idx;
|
||||||
Protocol *protocol= thd->protocol;
|
Protocol *protocol= thd->protocol;
|
||||||
void *iterator;
|
void *iterator;
|
||||||
DBUG_ENTER("PROFILING::show_profiles");
|
DBUG_ENTER("PROFILING::show_profiles");
|
||||||
@ -426,9 +426,9 @@ bool PROFILING::show_profiles()
|
|||||||
|
|
||||||
unit->set_limit(sel);
|
unit->set_limit(sel);
|
||||||
|
|
||||||
for (iterator= history.new_iterator();
|
for (iterator= history.new_iterator(), idx= 1;
|
||||||
iterator != NULL;
|
iterator != NULL;
|
||||||
iterator= history.iterator_next(iterator))
|
iterator= history.iterator_next(iterator), idx++)
|
||||||
{
|
{
|
||||||
prof= history.iterator_value(iterator);
|
prof= history.iterator_value(iterator);
|
||||||
|
|
||||||
@ -436,9 +436,9 @@ bool PROFILING::show_profiles()
|
|||||||
|
|
||||||
double query_time_usecs= prof->m_end_time_usecs - prof->m_start_time_usecs;
|
double query_time_usecs= prof->m_end_time_usecs - prof->m_start_time_usecs;
|
||||||
|
|
||||||
if (++idx <= unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
continue;
|
continue;
|
||||||
if (idx > unit->select_limit_cnt)
|
if (idx > unit->lim.get_select_limit())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
protocol->prepare_for_resend();
|
protocol->prepare_for_resend();
|
||||||
|
@ -4013,7 +4013,7 @@ bool mysql_show_binlog_events(THD* thd)
|
|||||||
if (binary_log->is_open())
|
if (binary_log->is_open())
|
||||||
{
|
{
|
||||||
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
SELECT_LEX_UNIT *unit= &thd->lex->unit;
|
||||||
ha_rows event_count, limit_start, limit_end;
|
ha_rows event_count;
|
||||||
my_off_t pos = MY_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
|
my_off_t pos = MY_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
|
||||||
char search_file_name[FN_REFLEN], *name;
|
char search_file_name[FN_REFLEN], *name;
|
||||||
const char *log_file_name = lex_mi->log_file_name;
|
const char *log_file_name = lex_mi->log_file_name;
|
||||||
@ -4028,8 +4028,6 @@ bool mysql_show_binlog_events(THD* thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unit->set_limit(thd->lex->current_select);
|
unit->set_limit(thd->lex->current_select);
|
||||||
limit_start= unit->offset_limit_cnt;
|
|
||||||
limit_end= unit->select_limit_cnt;
|
|
||||||
|
|
||||||
name= search_file_name;
|
name= search_file_name;
|
||||||
if (log_file_name)
|
if (log_file_name)
|
||||||
@ -4108,7 +4106,7 @@ bool mysql_show_binlog_events(THD* thd)
|
|||||||
description_event,
|
description_event,
|
||||||
opt_master_verify_checksum)); )
|
opt_master_verify_checksum)); )
|
||||||
{
|
{
|
||||||
if (event_count >= limit_start &&
|
if (!unit->lim.check_and_move_offset() &&
|
||||||
ev->net_send(protocol, linfo.log_file_name, pos))
|
ev->net_send(protocol, linfo.log_file_name, pos))
|
||||||
{
|
{
|
||||||
errmsg = "Net error";
|
errmsg = "Net error";
|
||||||
@ -4142,11 +4140,11 @@ bool mysql_show_binlog_events(THD* thd)
|
|||||||
|
|
||||||
pos = my_b_tell(&log);
|
pos = my_b_tell(&log);
|
||||||
|
|
||||||
if (++event_count >= limit_end)
|
if (++event_count >= unit->lim.get_select_limit())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(event_count < limit_end && log.error))
|
if (unlikely(event_count < unit->lim.get_select_limit() && log.error))
|
||||||
{
|
{
|
||||||
errmsg = "Wrong offset or I/O error";
|
errmsg = "Wrong offset or I/O error";
|
||||||
mysql_mutex_unlock(log_lock);
|
mysql_mutex_unlock(log_lock);
|
||||||
|
@ -1749,7 +1749,7 @@ JOIN::optimize_inner()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::optimize");
|
DBUG_ENTER("JOIN::optimize");
|
||||||
subq_exit_fl= false;
|
subq_exit_fl= false;
|
||||||
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
do_send_rows = (unit->lim.get_select_limit()) ? 1 : 0;
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "before_join_optimize");
|
DEBUG_SYNC(thd, "before_join_optimize");
|
||||||
|
|
||||||
@ -1824,9 +1824,9 @@ JOIN::optimize_inner()
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
|
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
|
||||||
unit->select_limit_cnt);
|
unit->lim.get_select_limit());
|
||||||
/* select_limit is used to decide if we are likely to scan the whole table */
|
/* select_limit is used to decide if we are likely to scan the whole table */
|
||||||
select_limit= unit->select_limit_cnt;
|
select_limit= unit->lim.get_select_limit();
|
||||||
if (having || (select_options & OPTION_FOUND_ROWS))
|
if (having || (select_options & OPTION_FOUND_ROWS))
|
||||||
select_limit= HA_POS_ERROR;
|
select_limit= HA_POS_ERROR;
|
||||||
#ifdef HAVE_REF_TO_FIELDS // Not done yet
|
#ifdef HAVE_REF_TO_FIELDS // Not done yet
|
||||||
@ -2054,9 +2054,10 @@ JOIN::optimize_inner()
|
|||||||
thd->change_item_tree(&sel->having, having);
|
thd->change_item_tree(&sel->having, having);
|
||||||
}
|
}
|
||||||
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
|
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
|
||||||
(!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
|
(!unit->lim.get_select_limit() &&
|
||||||
|
!(select_options & OPTION_FOUND_ROWS)))
|
||||||
{ /* Impossible cond */
|
{ /* Impossible cond */
|
||||||
if (unit->select_limit_cnt)
|
if (unit->lim.get_select_limit())
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
|
DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
|
||||||
"Impossible HAVING" : "Impossible WHERE"));
|
"Impossible HAVING" : "Impossible WHERE"));
|
||||||
@ -3601,7 +3602,7 @@ bool JOIN::make_aggr_tables_info()
|
|||||||
*/
|
*/
|
||||||
sort_tab->filesort->limit=
|
sort_tab->filesort->limit=
|
||||||
(has_group_by || (join_tab + top_join_tab_count > curr_tab + 1)) ?
|
(has_group_by || (join_tab + top_join_tab_count > curr_tab + 1)) ?
|
||||||
select_limit : unit->select_limit_cnt;
|
select_limit : unit->lim.get_select_limit();
|
||||||
}
|
}
|
||||||
if (!only_const_tables() &&
|
if (!only_const_tables() &&
|
||||||
!join_tab[const_tables].filesort &&
|
!join_tab[const_tables].filesort &&
|
||||||
@ -3986,8 +3987,7 @@ JOIN::reinit()
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("JOIN::reinit");
|
DBUG_ENTER("JOIN::reinit");
|
||||||
|
|
||||||
unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
|
unit->lim.reset();
|
||||||
select_lex->offset_limit->val_uint() : 0);
|
|
||||||
|
|
||||||
first_record= false;
|
first_record= false;
|
||||||
group_sent= false;
|
group_sent= false;
|
||||||
@ -5513,7 +5513,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
if (double rr= join->best_positions[i].records_read)
|
if (double rr= join->best_positions[i].records_read)
|
||||||
records= COST_MULT(records, rr);
|
records= COST_MULT(records, rr);
|
||||||
ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
|
ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
|
||||||
set_if_smaller(rows, unit->select_limit_cnt);
|
set_if_smaller(rows, unit->lim.get_select_limit());
|
||||||
join->select_lex->increase_derived_records(rows);
|
join->select_lex->increase_derived_records(rows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7970,7 +7970,7 @@ best_access_path(JOIN *join,
|
|||||||
if (!best_key &&
|
if (!best_key &&
|
||||||
idx == join->const_tables &&
|
idx == join->const_tables &&
|
||||||
s->table == join->sort_by_table &&
|
s->table == join->sort_by_table &&
|
||||||
join->unit->select_limit_cnt >= records)
|
join->unit->lim.get_select_limit() >= records)
|
||||||
{
|
{
|
||||||
trace_access_scan.add("use_tmp_table", true);
|
trace_access_scan.add("use_tmp_table", true);
|
||||||
join->sort_by_table= (TABLE*) 1; // Must use temporary table
|
join->sort_by_table= (TABLE*) 1; // Must use temporary table
|
||||||
@ -11465,7 +11465,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
!tab->loosescan_match_tab && // (1)
|
!tab->loosescan_match_tab && // (1)
|
||||||
((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
|
((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
|
||||||
(!tab->const_keys.is_clear_all() && i == join->const_tables &&
|
(!tab->const_keys.is_clear_all() && i == join->const_tables &&
|
||||||
join->unit->select_limit_cnt <
|
join->unit->lim.get_select_limit() <
|
||||||
join->best_positions[i].records_read &&
|
join->best_positions[i].records_read &&
|
||||||
!(join->select_options & OPTION_FOUND_ROWS))))
|
!(join->select_options & OPTION_FOUND_ROWS))))
|
||||||
{
|
{
|
||||||
@ -11489,7 +11489,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
(join->select_options &
|
(join->select_options &
|
||||||
OPTION_FOUND_ROWS ?
|
OPTION_FOUND_ROWS ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
join->unit->select_limit_cnt), 0,
|
join->unit->lim.get_select_limit()), 0,
|
||||||
FALSE, FALSE, FALSE) < 0)
|
FALSE, FALSE, FALSE) < 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -11503,7 +11503,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
(join->select_options &
|
(join->select_options &
|
||||||
OPTION_FOUND_ROWS ?
|
OPTION_FOUND_ROWS ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
join->unit->select_limit_cnt),0,
|
join->unit->lim.get_select_limit()),0,
|
||||||
FALSE, FALSE, FALSE) < 0)
|
FALSE, FALSE, FALSE) < 0)
|
||||||
DBUG_RETURN(1); // Impossible WHERE
|
DBUG_RETURN(1); // Impossible WHERE
|
||||||
}
|
}
|
||||||
@ -19791,31 +19791,31 @@ do_select(JOIN *join, Procedure *procedure)
|
|||||||
HAVING will be checked after processing aggregate functions,
|
HAVING will be checked after processing aggregate functions,
|
||||||
But WHERE should checked here (we alredy have read tables).
|
But WHERE should checked here (we alredy have read tables).
|
||||||
Notice that make_join_select() splits all conditions in this case
|
Notice that make_join_select() splits all conditions in this case
|
||||||
into two groups exec_const_cond and outer_ref_cond.
|
into two groups exec_const_cond and outer_ref_cond.
|
||||||
If join->table_count == join->const_tables then it is
|
If join->table_count == join->const_tables then it is
|
||||||
sufficient to check only the condition pseudo_bits_cond.
|
sufficient to check only the condition pseudo_bits_cond.
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(join->outer_ref_cond == NULL);
|
DBUG_ASSERT(join->outer_ref_cond == NULL);
|
||||||
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
|
if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int())
|
||||||
{
|
{
|
||||||
// HAVING will be checked by end_select
|
// HAVING will be checked by end_select
|
||||||
error= (*end_select)(join, 0, 0);
|
error= (*end_select)(join, 0, 0);
|
||||||
if (error >= NESTED_LOOP_OK)
|
if (error >= NESTED_LOOP_OK)
|
||||||
error= (*end_select)(join, 0, 1);
|
error= (*end_select)(join, 0, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we don't go through evaluate_join_record(), do the counting
|
If we don't go through evaluate_join_record(), do the counting
|
||||||
here. join->send_records is increased on success in end_send(),
|
here. join->send_records is increased on success in end_send(),
|
||||||
so we don't touch it here.
|
so we don't touch it here.
|
||||||
*/
|
*/
|
||||||
join->join_examined_rows++;
|
join->join_examined_rows++;
|
||||||
DBUG_ASSERT(join->join_examined_rows <= 1);
|
DBUG_ASSERT(join->join_examined_rows <= 1);
|
||||||
}
|
}
|
||||||
else if (join->send_row_on_empty_set())
|
else if (join->send_row_on_empty_set())
|
||||||
|
{
|
||||||
|
if (!join->having || join->having->val_int())
|
||||||
{
|
{
|
||||||
if (!join->having || join->having->val_int())
|
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
|
||||||
{
|
|
||||||
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
|
|
||||||
join->fields);
|
join->fields);
|
||||||
rc= join->result->send_data(*columns_list) > 0;
|
rc= join->result->send_data(*columns_list) > 0;
|
||||||
}
|
}
|
||||||
@ -21499,7 +21499,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
}
|
}
|
||||||
|
|
||||||
++join->send_records;
|
++join->send_records;
|
||||||
if (join->send_records >= join->unit->select_limit_cnt &&
|
if (join->send_records >= join->unit->lim.get_select_limit() &&
|
||||||
!join->do_send_rows)
|
!join->do_send_rows)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -21517,7 +21517,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
|
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (join->send_records >= join->unit->select_limit_cnt &&
|
if (join->send_records >= join->unit->lim.get_select_limit() &&
|
||||||
join->do_send_rows)
|
join->do_send_rows)
|
||||||
{
|
{
|
||||||
if (join->select_options & OPTION_FOUND_ROWS)
|
if (join->select_options & OPTION_FOUND_ROWS)
|
||||||
@ -21658,13 +21658,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||||
if (end_of_records)
|
if (end_of_records)
|
||||||
DBUG_RETURN(NESTED_LOOP_OK);
|
DBUG_RETURN(NESTED_LOOP_OK);
|
||||||
if (join->send_records >= join->unit->select_limit_cnt &&
|
if (join->send_records >= join->unit->lim.get_select_limit() &&
|
||||||
join->do_send_rows)
|
join->do_send_rows)
|
||||||
{
|
{
|
||||||
if (!(join->select_options & OPTION_FOUND_ROWS))
|
if (!(join->select_options & OPTION_FOUND_ROWS))
|
||||||
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
|
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
|
||||||
join->do_send_rows=0;
|
join->do_send_rows=0;
|
||||||
join->unit->select_limit_cnt = HA_POS_ERROR;
|
join->unit->lim.set_unlimited();
|
||||||
}
|
}
|
||||||
else if (join->send_records >= join->fetch_limit)
|
else if (join->send_records >= join->fetch_limit)
|
||||||
{
|
{
|
||||||
@ -21749,7 +21749,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
if (!(join->select_options & OPTION_FOUND_ROWS))
|
if (!(join->select_options & OPTION_FOUND_ROWS))
|
||||||
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
|
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
|
||||||
join->do_send_rows=0;
|
join->do_send_rows=0;
|
||||||
join->unit->select_limit_cnt = HA_POS_ERROR;
|
join->unit->lim.set_unlimited();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23111,8 +23111,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
(tab->join->select_options &
|
(tab->join->select_options &
|
||||||
OPTION_FOUND_ROWS) ?
|
OPTION_FOUND_ROWS) ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
tab->join->unit->select_limit_cnt,TRUE,
|
tab->join->unit->
|
||||||
TRUE, FALSE, FALSE) <= 0;
|
lim.get_select_limit(),
|
||||||
|
TRUE, TRUE, FALSE, FALSE) <= 0;
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
select->cond= save_cond;
|
select->cond= save_cond;
|
||||||
@ -23213,7 +23214,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
select->test_quick_select(join->thd, tmp_map, 0,
|
select->test_quick_select(join->thd, tmp_map, 0,
|
||||||
join->select_options & OPTION_FOUND_ROWS ?
|
join->select_options & OPTION_FOUND_ROWS ?
|
||||||
HA_POS_ERROR :
|
HA_POS_ERROR :
|
||||||
join->unit->select_limit_cnt,
|
join->unit->lim.get_select_limit(),
|
||||||
TRUE, FALSE, FALSE, FALSE);
|
TRUE, FALSE, FALSE, FALSE);
|
||||||
|
|
||||||
if (cond_saved)
|
if (cond_saved)
|
||||||
@ -23646,7 +23647,7 @@ JOIN_TAB::remove_duplicates()
|
|||||||
|
|
||||||
if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
|
if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
|
||||||
{ // only const items with no OPTION_FOUND_ROWS
|
{ // only const items with no OPTION_FOUND_ROWS
|
||||||
join->unit->select_limit_cnt= 1; // Only send first row
|
join->unit->lim.set_single_row(); // Only send first row
|
||||||
DBUG_RETURN(false);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25845,7 +25846,7 @@ int JOIN::rollup_send_data(uint idx)
|
|||||||
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
|
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
|
||||||
if ((!having || having->val_int()))
|
if ((!having || having->val_int()))
|
||||||
{
|
{
|
||||||
if (send_records < unit->select_limit_cnt && do_send_rows &&
|
if (send_records < unit->lim.get_select_limit() && do_send_rows &&
|
||||||
(res= result->send_data(rollup.fields[i])) > 0)
|
(res= result->send_data(rollup.fields[i])) > 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -386,7 +386,7 @@ bool table_value_constr::exec(SELECT_LEX *sl)
|
|||||||
|
|
||||||
while ((elem= li++))
|
while ((elem= li++))
|
||||||
{
|
{
|
||||||
if (send_records >= sl->master_unit()->select_limit_cnt)
|
if (send_records >= sl->master_unit()->lim.get_select_limit())
|
||||||
break;
|
break;
|
||||||
int rc= result->send_data(*elem);
|
int rc= result->send_data(*elem);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
|
@ -111,11 +111,8 @@ int select_unit::send_data(List<Item> &values)
|
|||||||
{
|
{
|
||||||
int rc= 0;
|
int rc= 0;
|
||||||
int not_reported_error= 0;
|
int not_reported_error= 0;
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{ // using limit offset,count
|
return 0; // using limit offset,count
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
return 0;
|
return 0;
|
||||||
if (table->no_rows_with_nulls)
|
if (table->no_rows_with_nulls)
|
||||||
@ -607,12 +604,8 @@ int select_unit_ext::send_data(List<Item> &values)
|
|||||||
int rc= 0;
|
int rc= 0;
|
||||||
int not_reported_error= 0;
|
int not_reported_error= 0;
|
||||||
int find_res;
|
int find_res;
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->lim.check_and_move_offset())
|
||||||
{
|
|
||||||
/* using limit offset,count */
|
|
||||||
unit->offset_limit_cnt--;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (thd->killed == ABORT_QUERY)
|
if (thd->killed == ABORT_QUERY)
|
||||||
return 0;
|
return 0;
|
||||||
if (table->no_rows_with_nulls)
|
if (table->no_rows_with_nulls)
|
||||||
@ -1358,8 +1351,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sl->join->result= result;
|
sl->join->result= result;
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
lim.set_unlimited();
|
||||||
offset_limit_cnt= 0;
|
|
||||||
if (!sl->join->procedure &&
|
if (!sl->join->procedure &&
|
||||||
result->prepare(sl->join->fields_list, this))
|
result->prepare(sl->join->fields_list, this))
|
||||||
{
|
{
|
||||||
@ -2046,7 +2038,7 @@ bool st_select_lex_unit::optimize()
|
|||||||
if (sl->tvc)
|
if (sl->tvc)
|
||||||
{
|
{
|
||||||
sl->tvc->select_options=
|
sl->tvc->select_options=
|
||||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
(lim.is_unlimited() || sl->braces) ?
|
||||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||||
if (sl->tvc->optimize(thd))
|
if (sl->tvc->optimize(thd))
|
||||||
{
|
{
|
||||||
@ -2066,13 +2058,13 @@ bool st_select_lex_unit::optimize()
|
|||||||
set_limit(sl);
|
set_limit(sl);
|
||||||
if (sl == global_parameters() || describe)
|
if (sl == global_parameters() || describe)
|
||||||
{
|
{
|
||||||
offset_limit_cnt= 0;
|
lim.remove_offset();
|
||||||
/*
|
/*
|
||||||
We can't use LIMIT at this stage if we are using ORDER BY for the
|
We can't use LIMIT at this stage if we are using ORDER BY for the
|
||||||
whole query
|
whole query
|
||||||
*/
|
*/
|
||||||
if (sl->order_list.first || describe)
|
if (sl->order_list.first || describe)
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
lim.set_unlimited();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2081,7 +2073,7 @@ bool st_select_lex_unit::optimize()
|
|||||||
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
||||||
*/
|
*/
|
||||||
sl->join->select_options=
|
sl->join->select_options=
|
||||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
(lim.is_unlimited() || sl->braces) ?
|
||||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||||
|
|
||||||
saved_error= sl->join->optimize();
|
saved_error= sl->join->optimize();
|
||||||
@ -2161,13 +2153,13 @@ bool st_select_lex_unit::exec()
|
|||||||
set_limit(sl);
|
set_limit(sl);
|
||||||
if (sl == global_parameters() || describe)
|
if (sl == global_parameters() || describe)
|
||||||
{
|
{
|
||||||
offset_limit_cnt= 0;
|
lim.remove_offset();
|
||||||
/*
|
/*
|
||||||
We can't use LIMIT at this stage if we are using ORDER BY for the
|
We can't use LIMIT at this stage if we are using ORDER BY for the
|
||||||
whole query
|
whole query
|
||||||
*/
|
*/
|
||||||
if (sl->order_list.first || describe)
|
if (sl->order_list.first || describe)
|
||||||
select_limit_cnt= HA_POS_ERROR;
|
lim.set_unlimited();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2178,14 +2170,14 @@ bool st_select_lex_unit::exec()
|
|||||||
if (sl->tvc)
|
if (sl->tvc)
|
||||||
{
|
{
|
||||||
sl->tvc->select_options=
|
sl->tvc->select_options=
|
||||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
(lim.is_unlimited() || sl->braces) ?
|
||||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||||
saved_error= sl->tvc->optimize(thd);
|
saved_error= sl->tvc->optimize(thd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sl->join->select_options=
|
sl->join->select_options=
|
||||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
(lim.is_unlimited() || sl->braces) ?
|
||||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||||
saved_error= sl->join->optimize();
|
saved_error= sl->join->optimize();
|
||||||
}
|
}
|
||||||
@ -2208,9 +2200,7 @@ bool st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
if (!sl->tvc)
|
if (!sl->tvc)
|
||||||
saved_error= sl->join->error;
|
saved_error= sl->join->error;
|
||||||
offset_limit_cnt= (ha_rows)(sl->offset_limit ?
|
lim.reset();
|
||||||
sl->offset_limit->val_uint() :
|
|
||||||
0);
|
|
||||||
if (likely(!saved_error))
|
if (likely(!saved_error))
|
||||||
{
|
{
|
||||||
examined_rows+= thd->get_examined_row_count();
|
examined_rows+= thd->get_examined_row_count();
|
||||||
@ -2237,8 +2227,8 @@ bool st_select_lex_unit::exec()
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found_rows_for_union && !sl->braces &&
|
if (found_rows_for_union && !sl->braces &&
|
||||||
select_limit_cnt != HA_POS_ERROR)
|
!lim.is_unlimited())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This is a union without braces. Remember the number of rows that
|
This is a union without braces. Remember the number of rows that
|
||||||
|
Loading…
x
Reference in New Issue
Block a user