diff options
author | unknown <konstantin@mysql.com> | 2005-05-30 20:56:11 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2005-05-30 20:56:11 +0400 |
commit | 5cdac9906945bbe7e7bc459c7e042568574102ab (patch) | |
tree | 4ed95e1092af1922457a7c10ddee5b8e88ecc9e8 /sql | |
parent | 1c7b61e3aef5227165a9957ead000e67935708b2 (diff) | |
parent | 78422442df581b736862bd090ab3c18d92e7d324 (diff) | |
download | mariadb-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.cc | 21 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/opt_range.cc | 11 | ||||
-rw-r--r-- | sql/sp.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 19 | ||||
-rw-r--r-- | sql/sql_delete.cc | 5 | ||||
-rw-r--r-- | sql/sql_help.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 8 | ||||
-rw-r--r-- | sql/sql_lex.h | 4 | ||||
-rw-r--r-- | sql/sql_load.cc | 2 | ||||
-rw-r--r-- | sql/sql_olap.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 32 | ||||
-rw-r--r-- | sql/sql_union.cc | 36 | ||||
-rw-r--r-- | sql/sql_update.cc | 7 |
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, |