summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2000-10-06 21:18:40 +0300
committerunknown <monty@donna.mysql.com>2000-10-06 21:18:40 +0300
commitdbde9337c201b7a53357d3904c7f0ac5b046ed85 (patch)
tree541b2f3507917096c3701506781361a765eaa056 /sql
parent7e52afcd93f4113cf1a7d47e0d15fde6b3b06485 (diff)
parent6991b70c87163d3cb3477a19a947b07cbfec9660 (diff)
downloadmariadb-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.cc10
-rw-r--r--sql/sql_select.cc89
-rw-r--r--sql/sql_select.h36
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;