diff options
author | unknown <monty@donna.mysql.com> | 2000-10-06 21:18:40 +0300 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2000-10-06 21:18:40 +0300 |
commit | dbde9337c201b7a53357d3904c7f0ac5b046ed85 (patch) | |
tree | 541b2f3507917096c3701506781361a765eaa056 /sql | |
parent | 7e52afcd93f4113cf1a7d47e0d15fde6b3b06485 (diff) | |
parent | 6991b70c87163d3cb3477a19a947b07cbfec9660 (diff) | |
download | mariadb-git-dbde9337c201b7a53357d3904c7f0ac5b046ed85.tar.gz |
Merge work:/home/bk/mysql into donna.mysql.com:/home/my/bk/mysql
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_acl.cc | 10 | ||||
-rw-r--r-- | sql/sql_select.cc | 89 | ||||
-rw-r--r-- | sql/sql_select.h | 36 |
3 files changed, 87 insertions, 48 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f103fce1ad9..85d57914c78 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2004,6 +2004,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables, want_access &= ~table->grant.privilege; goto err; // No grants } + if (show_table) + continue; // We have some priv on this table->grant.grant_table=grant_table; // Remember for column test table->grant.version=grant_version; @@ -2013,8 +2015,6 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables, if (!(~table->grant.privilege & want_access)) continue; - if (show_table && table->grant.privilege) - continue; // Test from show tables if (want_access & ~(grant_table->cols | table->grant.privilege)) { @@ -2457,18 +2457,18 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) !strcmp(lex_user->host.str,host)) { want_access=grant_table->privs; - if (want_access) + if ((want_access | grant_table->cols) != 0) { String global(buff,sizeof(buff)); global.length(0); global.append("GRANT ",6); - if (test_all_bits(want_access,(TABLE_ACLS & ~GRANT_ACL))) + if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL))) global.append("ALL PRIVILEGES",14); else { int found=0; - uint j,test_access= want_access & ~GRANT_ACL; + uint j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL; for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 450efb84e5d..b7eebf80313 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -136,7 +136,8 @@ static void copy_sum_funcs(Item_sum **func_ptr); static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static void init_sum_functions(Item_sum **func); static bool update_sum_func(Item_sum **func); -static void select_describe(JOIN *join, bool need_tmp_table, bool need_order); +static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, + bool distinct); static void describe_info(const char *info); /***************************************************************************** @@ -171,6 +172,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, no_order=0; bzero((char*) &keyuse,sizeof(keyuse)); thd->proc_info="init"; + thd->used_tables=0; // Updated by setup_fields if (setup_fields(thd,tables,fields,1,&all_fields) || setup_conds(thd,tables,&conds) || @@ -261,7 +263,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, join.join_tab=0; join.tmp_table_param.copy_field=0; join.sum_funcs=0; - join.send_records=0L; + join.send_records=join.found_records=0; join.tmp_table_param.end_write_records= HA_POS_ERROR; join.first_record=join.sort_and_group=0; join.select_options=select_options; @@ -506,7 +508,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, order=0; select_describe(&join,need_tmp, (order != 0 && - (!need_tmp || order != group || simple_group))); + (!need_tmp || order != group || simple_group)), + select_distinct); error=0; goto err; } @@ -557,6 +560,26 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, order=0; } } + + /* + Optimize distinct when used on some of the tables + SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b + In this case we can stop scanning t2 when we have found one t1.a + */ + + if (tmp_table->distinct) + { + table_map used_tables= thd->used_tables; + JOIN_TAB *join_tab=join.join_tab+join.tables-1; + do + { + if (used_tables & join_tab->table->map) + break; + join_tab->not_used_in_distinct=1; + } while (join_tab-- != join.join_tab); + } + + /* Copy data to the temporary table */ thd->proc_info="Copying to tmp table"; if (do_select(&join,(List<Item> *) 0,tmp_table,0)) goto err; /* purecov: inspected */ @@ -2122,7 +2145,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join->tmp_table_param.copy_field=0; join->first_record=join->sort_and_group=0; join->sum_funcs=0; - join->send_records=0L; + join->send_records=(ha_rows) 0; join->group=0; join_tab->cache.buff=0; /* No cacheing */ @@ -2130,15 +2153,16 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join_tab->select=0; join_tab->select_cond=0; join_tab->quick=0; - bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); join_tab->type= JT_ALL; /* Map through all records */ join_tab->keys= (uint) ~0; /* test everything in quick */ join_tab->info=0; join_tab->on_expr=0; join_tab->ref.key = -1; + join_tab->not_used_in_distinct=0; + join_tab->read_first_record= join_init_read_record; + bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); tmp_table->status=0; tmp_table->null_row=0; - join_tab->read_first_record= join_init_read_record; return FALSE; } @@ -3256,7 +3280,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || item->const_item()) continue; - if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) { /* Can't calc group yet */ ((Item_sum*) item)->result_field=0; @@ -3913,7 +3936,9 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (!(error=(*join_tab->read_first_record)(join_tab))) { - bool not_exists_optimize=join_tab->table->reginfo.not_exists_optimize; + bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize; + bool not_used_in_distinct=join_tab->not_used_in_distinct; + ha_rows found_records=join->found_records; READ_RECORD *info= &join_tab->read_record; do @@ -3932,6 +3957,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) { if ((error=(*next_select)(join,join_tab+1,0)) < 0) return error; + if (not_used_in_distinct && found_records != join->found_records) + return 0; } } } while (!(error=info->read_record(info))); @@ -4545,23 +4572,21 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } if (!join->having || join->having->val_int()) { + join->found_records++; if ((error=table->file->write_row(table->record[0]))) { - if (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE) - { - if (create_myisam_from_heap(table, &join->tmp_table_param, error,1)) - DBUG_RETURN(1); // Not a table_is_full error - table->uniques=0; // To ensure rows are the same - } - } - else - { + if (error == HA_ERR_FOUND_DUPP_KEY || + error == HA_ERR_FOUND_DUPP_UNIQUE) + goto end; + if (create_myisam_from_heap(table, &join->tmp_table_param, error,1)) + DBUG_RETURN(1); // Not a table_is_full error + table->uniques=0; // To ensure rows are the same if (++join->send_records >= join->tmp_table_param.end_write_records) DBUG_RETURN(-3); } } } +end: DBUG_RETURN(0); } @@ -4585,6 +4610,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(-2); /* purecov: inspected */ } + join->found_records++; copy_fields(&join->tmp_table_param); // Groups are copied twice. /* Make a key of group index */ for (group=table->group ; group ; group=group->next) @@ -6335,12 +6361,13 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) ** Send a description about what how the select will be done to stdout ****************************************************************************/ -static void select_describe(JOIN *join, bool need_tmp_table, bool need_order) +static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, + bool distinct) { - DBUG_ENTER("select_describe"); - List<Item> field_list; Item *item; + THD *thd=join->thd; + DBUG_ENTER("select_describe"); field_list.push_back(new Item_empty_string("table",NAME_LEN)); field_list.push_back(new Item_empty_string("type",10)); @@ -6356,11 +6383,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order) item->maybe_null=1; field_list.push_back(new Item_real("rows",0.0,0,10)); field_list.push_back(new Item_empty_string("Extra",255)); - if (send_fields(join->thd,field_list,1)) + if (send_fields(thd,field_list,1)) return; /* purecov: inspected */ char buff[512],*buff_ptr; - String tmp(buff,sizeof(buff)),*packet= &join->thd->packet; + String tmp(buff,sizeof(buff)),*packet= &thd->packet; + table_map used_tables=0; for (uint i=0 ; i < join->tables ; i++) { JOIN_TAB *tab=join->join_tab+i; @@ -6473,11 +6501,22 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order) } buff_ptr=strmov(buff_ptr,"Using filesort"); } + if (distinct & test_all_bits(used_tables,thd->used_tables)) + { + if (buff != buff_ptr) + { + buff_ptr[0]=';' ; buff_ptr[1]=' '; buff_ptr+=2; + } + buff_ptr=strmov(buff_ptr,"Distinct"); + } net_store_data(packet,buff,(uint) (buff_ptr - buff)); - if (my_net_write(&join->thd->net,(char*) packet->ptr(),packet->length())) + if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_VOID_RETURN; /* purecov: inspected */ + + // For next iteration + used_tables|=table->map; } - send_eof(&join->thd->net); + send_eof(&thd->net); DBUG_VOID_RETURN; } diff --git a/sql/sql_select.h b/sql/sql_select.h index 8daba5b939e..796802c0a50 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -79,36 +79,36 @@ class JOIN; typedef struct st_join_table { TABLE *table; + KEYUSE *keyuse; /* pointer to first used key */ + SQL_SELECT *select; + COND *select_cond; + QUICK_SELECT *quick; + Item *on_expr; + const char *info; int (*read_first_record)(struct st_join_table *tab); int (*next_select)(JOIN *,struct st_join_table *,bool); - bool cached_eq_ref_table,eq_ref_table; READ_RECORD read_record; - uint keys; /* all keys with can be used */ + double worst_seeks; key_map const_keys; /* Keys with constant part */ key_map checked_keys; /* Keys checked in find_best */ key_map needed_reg; ha_rows records,found_records,read_time; table_map dependent,key_dependent; + uint keys; /* all keys with can be used */ uint use_quick,index; uint status; // Save status for cache - enum join_type type; - JOIN_CACHE cache; - KEYUSE *keyuse; /* pointer to first used key */ - SQL_SELECT *select; - COND *select_cond; - QUICK_SELECT *quick; - Item *on_expr; uint used_fields,used_fieldlength,used_blobs; - const char *info; - double worst_seeks; + enum join_type type; + bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct; TABLE_REF ref; + JOIN_CACHE cache; } JOIN_TAB; typedef struct st_position { /* Used in find_best */ + double records_read; JOIN_TAB *table; KEYUSE *key; - double records_read; } POSITION; @@ -116,16 +116,16 @@ typedef struct st_position { /* Used in find_best */ class TMP_TABLE_PARAM { public: - uint copy_field_count,field_count,sum_func_count,func_count; - uint group_parts,group_length; - uint quick_group; + List<Item> copy_funcs; Copy_field *copy_field; byte *group_buff; - ha_rows end_write_records; Item_result_field **funcs; - List<Item> copy_funcs; MI_COLUMNDEF *recinfo,*start_recinfo; KEY *keyinfo; + ha_rows end_write_records; + uint copy_field_count,field_count,sum_func_count,func_count; + uint group_parts,group_length; + uint quick_group; TMP_TABLE_PARAM() :group_parts(0),group_length(0),copy_field(0) {} ~TMP_TABLE_PARAM() @@ -148,7 +148,7 @@ class JOIN { uint send_group_parts; bool sort_and_group,first_record,full_join,group, no_field_update; table_map const_table_map; - ha_rows send_records; + ha_rows send_records,found_records; POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; double best_read; List<Item> *fields; |