summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2005-05-30 20:56:11 +0400
committerunknown <konstantin@mysql.com>2005-05-30 20:56:11 +0400
commit5cdac9906945bbe7e7bc459c7e042568574102ab (patch)
tree4ed95e1092af1922457a7c10ddee5b8e88ecc9e8 /sql
parent1c7b61e3aef5227165a9957ead000e67935708b2 (diff)
parent78422442df581b736862bd090ab3c18d92e7d324 (diff)
downloadmariadb-git-5cdac9906945bbe7e7bc459c7e042568574102ab.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/opt/local/work/mysql-5.0-7306-new sql/item_subselect.cc: Auto merged sql/mysql_priv.h: Auto merged sql/opt_range.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_olap.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/item_subselect.cc21
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/opt_range.cc11
-rw-r--r--sql/sp.cc2
-rw-r--r--sql/sql_base.cc19
-rw-r--r--sql/sql_delete.cc5
-rw-r--r--sql/sql_help.cc2
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc8
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_olap.cc3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc32
-rw-r--r--sql/sql_union.cc36
-rw-r--r--sql/sql_update.cc7
16 files changed, 63 insertions, 98 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 29c52e73159..43af7df44e6 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -537,8 +537,6 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
null_value= 0; //can't be NULL
maybe_null= 0; //can't be NULL
value= 0;
- // We need only 1 row to determinate existence
- select_lex->master_unit()->global_parameters->select_limit= 1;
DBUG_VOID_RETURN;
}
@@ -605,6 +603,8 @@ void Item_exists_subselect::fix_length_and_dec()
decimals= 0;
max_length= 1;
max_columns= engine->cols();
+ /* We need only 1 row to determinate existence */
+ unit->global_parameters->select_limit= 1;
}
double Item_exists_subselect::val_real()
@@ -854,9 +854,6 @@ Item_in_subselect::single_value_transformer(JOIN *join,
else
{
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());
if (upper_item)
upper_item->set_sub_test(item);
@@ -1286,13 +1283,10 @@ subselect_single_select_engine(st_select_lex *select,
select_subselect *result,
Item_subselect *item)
: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_UNIT *unit= select_lex->master_unit();
- unit->set_limit(unit->global_parameters, select_lex);
- unit->item= item;
- this->select_lex= select_lex;
+ select_lex->master_unit()->item= item;
}
@@ -1440,7 +1434,10 @@ int subselect_single_select_engine::exec()
thd->lex->current_select= select_lex;
if (!optimized)
{
- optimized=1;
+ SELECT_LEX_UNIT *unit= select_lex->master_unit();
+
+ optimized= 1;
+ unit->set_limit(unit->global_parameters);
if (join->optimize())
{
thd->where= save_where;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 0675bce636d..dbed665d7d9 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -884,8 +884,7 @@ bool insert_fields(THD *thd,TABLE_LIST *tables,
List_iterator<Item> *it, bool any_privileges,
bool allocate_view_names);
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
- TABLE_LIST **leaves, bool refresh_only,
- bool select_insert);
+ TABLE_LIST **leaves, bool select_insert);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 5718ab5e010..c250238eb4b 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7980,8 +7980,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;
++used_key_parts;
}
diff --git a/sql/sp.cc b/sql/sp.cc
index 9a816f277ed..a5b1f062456 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -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
*/
- setup_tables(thd, &tables, 0, &leaves, FALSE, FALSE);
+ setup_tables(thd, &tables, 0, &leaves, FALSE);
for (used_field= &used_fields[0];
used_field->field_name;
used_field++)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9e5ca4453c6..8fbe5bbfcb7 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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,
- TABLE_LIST **leaves, bool refresh, bool select_insert)
+ TABLE_LIST **leaves, bool select_insert)
{
uint tablenr= 0;
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);
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;
- table_list;
- table_list= table_list->next_local)
- {
- if (table_list->ancestor &&
- table_list->setup_ancestor(thd, conds,
- 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);
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 97830f7ec8f..4ec4258f412 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -300,8 +300,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_delete");
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
- FALSE, FALSE) ||
+ if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
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
*/
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);
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 3c8e8e55c1f..0cf8d1e93a7 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -651,7 +651,7 @@ bool mysqld_help(THD *thd, const char *mask)
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));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
goto error;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index ce1a669c91e..5d87a4ca30b 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -699,7 +699,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
DBUG_ENTER("mysql_prepare_insert_check_table");
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
- FALSE, select_insert))
+ select_insert))
DBUG_RETURN(TRUE);
if (insert_into_view && !fields.elements)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index fb23ded414e..574c9966c63 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1369,8 +1369,6 @@ bool st_select_lex::test_limit()
"LIMIT & IN/ALL/ANY/SOME subquery");
return(1);
}
- // We need only 1 row to determinate existence
- select_limit= 1;
// no sense in ORDER BY without LIMIT
order_list.empty();
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::ALL_SUBS))
{
- DBUG_ASSERT(select_limit == 1L && offset_limit == 0L);
+ DBUG_ASSERT(!item->fixed || select_limit == 1L && offset_limit == 0L);
return;
}
@@ -1756,11 +1754,9 @@ bool st_lex::need_correct_ident()
SYNOPSIS
st_select_lex_unit::set_limit()
values - SELECT_LEX with initial values for counters
- sl - SELECT_LEX for options set
*/
-void st_select_lex_unit::set_limit(SELECT_LEX *values,
- SELECT_LEX *sl)
+void st_select_lex_unit::set_limit(SELECT_LEX *values)
{
offset_limit_cnt= values->offset_limit;
select_limit_cnt= values->select_limit+values->offset_limit;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index f563008e4ea..e297d303f3d 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -445,10 +445,10 @@ public:
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; }
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 int subselect_union_engine::exec();
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1545055f475..cc25839bcc9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -150,7 +150,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
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);
if (!table_list->table || // do not suport join view
!table_list->updatable || // and derived tables
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
index 8ac0a36b03f..831b15cf7ef 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -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
- &select_lex->where, &select_lex->leaf_tables,
- FALSE, FALSE) ||
+ &select_lex->where, &select_lex->leaf_tables, FALSE) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
select_lex->item_list, 1, &all_fields,1) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index aaec001f47b..d1d641d1836 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2778,7 +2778,7 @@ mysql_execute_command(THD *thd)
select_result *result;
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)))
{
@@ -3176,7 +3176,7 @@ unsent_create_error:
select_lex->options|= SELECT_NO_UNLOCK;
select_result *result;
- unit->set_limit(select_lex, select_lex);
+ unit->set_limit(select_lex);
if (!(res= open_and_lock_tables(thd, all_tables)))
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9f518232214..e8644d614f6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -233,7 +233,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
else
{
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
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) &&
setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
- FALSE, FALSE)) ||
+ FALSE)) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
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);
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
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;
#ifdef RESTRICTED_GROUP
@@ -550,6 +543,13 @@ JOIN::optimize()
DBUG_RETURN(0);
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
if (thd->lex->ignore)
thd->lex->current_select->no_error= 1;
@@ -1110,18 +1110,7 @@ int
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;
if (exec_tmp_table1)
@@ -1147,6 +1136,7 @@ JOIN::reinit()
if (tmp_join)
restore_tmp();
+ /* Reset of sum functions */
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
@@ -13486,7 +13476,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
else
{
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,
(TABLE_LIST*) first->table_list.first,
first->with_wild, first->item_list,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 00770ba02a2..21549f76350 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -115,27 +115,15 @@ bool select_union::flush()
options of SELECT
*/
-ulong
+void
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;
- 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= &fake_select_lex->ftfunc_list_alloc;
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **)
&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;
thd_arg->lex->current_select= sl;
- set_limit(sl, sl);
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,
(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())
{
/* 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).
*/
@@ -429,12 +416,8 @@ bool st_select_lex_unit::exec()
res= sl->join->reinit();
else
{
- if (sl != global_parameters && !describe)
- {
- offset_limit_cnt= sl->offset_limit;
- select_limit_cnt= sl->select_limit+sl->offset_limit;
- }
- else
+ set_limit(sl);
+ if (sl == global_parameters || describe)
{
offset_limit_cnt= 0;
/*
@@ -443,11 +426,7 @@ bool st_select_lex_unit::exec()
*/
if (sl->order_list.first || describe)
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:
@@ -512,7 +491,8 @@ bool st_select_lex_unit::exec()
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;
if (!join)
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index a19a3e46798..0d00c38f638 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -557,8 +557,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
tables.table= table;
tables.alias= table_list->alias;
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
- FALSE, FALSE) ||
+ if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
select_lex->setup_ref_array(thd, order_num) ||
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,
- &lex->select_lex.leaf_tables, FALSE, FALSE))
+ &lex->select_lex.leaf_tables, FALSE))
DBUG_RETURN(TRUE);
leaves= lex->select_lex.leaf_tables;
@@ -764,7 +763,7 @@ bool mysql_multi_update_prepare(THD *thd)
tbl->cleanup_items();
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,
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
lex->select_lex.no_wrap_view_item= 0,