Commit ce226058 authored by monty@donna.mysql.com's avatar monty@donna.mysql.com

Fixed ALTER TABLE on MERGE tables

Fixed bug in DISTINCT
parent 6b9a8a92
This diff is collapsed.
...@@ -62,7 +62,7 @@ int handle_locking; ...@@ -62,7 +62,7 @@ int handle_locking;
{ {
if ((end=buff+length)[-1] == '\n') if ((end=buff+length)[-1] == '\n')
end[-1]='\0'; end[-1]='\0';
if (buff[0]) /* Skipp empty lines */ if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */
{ {
last_isam=isam; last_isam=isam;
if (!test_if_hard_path(buff)) if (!test_if_hard_path(buff))
......
...@@ -1462,6 +1462,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1462,6 +1462,8 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
reg1 MI_KEYDEF *keyinfo; reg1 MI_KEYDEF *keyinfo;
File new_file; File new_file;
my_off_t index_pos[MI_MAX_POSSIBLE_KEY]; my_off_t index_pos[MI_MAX_POSSIBLE_KEY];
uint r_locks,w_locks;
MYISAM_SHARE *share=info->s;
DBUG_ENTER("sort_index"); DBUG_ENTER("sort_index");
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
...@@ -1475,21 +1477,21 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1475,21 +1477,21 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
param->temp_filename); param->temp_filename);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (filecopy(param, new_file,info->s->kfile,0L, if (filecopy(param, new_file,share->kfile,0L,
(ulong) info->s->base.keystart, "headerblock")) (ulong) share->base.keystart, "headerblock"))
goto err; goto err;
param->new_file_pos=info->s->base.keystart; param->new_file_pos=share->base.keystart;
for (key= 0,keyinfo= &info->s->keyinfo[0]; key < info->s->base.keys ; for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
key++,keyinfo++) key++,keyinfo++)
{ {
if (!(((ulonglong) 1 << key) & info->s->state.key_map)) if (!(((ulonglong) 1 << key) & share->state.key_map))
continue; continue;
if (info->s->state.key_root[key] != HA_OFFSET_ERROR) if (share->state.key_root[key] != HA_OFFSET_ERROR)
{ {
index_pos[key]=param->new_file_pos; /* Write first block here */ index_pos[key]=param->new_file_pos; /* Write first block here */
if (sort_one_index(param,info,keyinfo,info->s->state.key_root[key], if (sort_one_index(param,info,keyinfo,share->state.key_root[key],
new_file)) new_file))
goto err; goto err;
} }
...@@ -1498,19 +1500,24 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) ...@@ -1498,19 +1500,24 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
} }
/* Flush key cache for this file if we are calling this outside myisamchk */ /* Flush key cache for this file if we are calling this outside myisamchk */
flush_key_blocks(info->s->kfile, FLUSH_IGNORE_CHANGED); flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
/* Put same locks as old file */ /* Put same locks as old file */
info->s->state.version=(ulong) time((time_t*) 0); share->state.version=(ulong) time((time_t*) 0);
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); r_locks=share->r_locks; w_locks=share->w_locks;
VOID(my_close(info->s->kfile,MYF(MY_WME))); share->r_locks=share->w_locks=0;
info->s->kfile = -1; (void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
VOID(my_close(share->kfile,MYF(MY_WME)));
share->kfile = -1;
VOID(my_close(new_file,MYF(MY_WME))); VOID(my_close(new_file,MYF(MY_WME)));
if (change_to_newfile(info->s->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, if (change_to_newfile(share->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
MYF(0)) || MYF(0)) ||
mi_open_keyfile(info->s)) mi_open_keyfile(share))
goto err2; goto err2;
_mi_readinfo(info,F_WRLCK,0); info->lock_type=F_UNLCK; /* Force mi_readinfo to lock */
_mi_readinfo(info,F_WRLCK,0); /* Will lock the table */
info->lock_type=F_WRLCK;
share->r_locks=r_locks; share->w_locks=w_locks;
info->state->key_file_length=param->new_file_pos; info->state->key_file_length=param->new_file_pos;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
......
...@@ -52,8 +52,8 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) ...@@ -52,8 +52,8 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag)
info->data_file_length+=file->table->s->state.state.data_file_length; info->data_file_length+=file->table->s->state.state.data_file_length;
info->records+=file->table->s->state.state.records; info->records+=file->table->s->state.state.records;
info->del+=file->table->s->state.state.del; info->del+=file->table->s->state.state.del;
DBUG_PRINT("info2",("table: %s, offset: 0x%08lx", DBUG_PRINT("info2",("table: %s, offset: %lu",
file->table->filename,(ulong)file->file_offset)); file->table->filename,(ulong) file->file_offset));
} }
x->records = info->records; x->records = info->records;
x->deleted = info->del; x->deleted = info->del;
......
...@@ -36,7 +36,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos) ...@@ -36,7 +36,7 @@ int myrg_rrnd(MYRG_INFO *info,byte *buf,ulonglong filepos)
int error; int error;
MI_INFO *isam_info; MI_INFO *isam_info;
DBUG_ENTER("myrg_rrnd"); DBUG_ENTER("myrg_rrnd");
DBUG_PRINT("info",("offset: 0x%016qx", (ulonglong)filepos)); DBUG_PRINT("info",("offset: %lu", (ulong) filepos));
if (filepos == HA_OFFSET_ERROR) if (filepos == HA_OFFSET_ERROR)
{ {
...@@ -109,7 +109,7 @@ static MYRG_TABLE *find_table(MYRG_TABLE *start, MYRG_TABLE *end, ...@@ -109,7 +109,7 @@ static MYRG_TABLE *find_table(MYRG_TABLE *start, MYRG_TABLE *end,
else else
start=mid; start=mid;
} }
DBUG_PRINT("info",("offset: 0x%016qx, table: %s", DBUG_PRINT("info",("offset: %lu, table: %s",
(ulonglong)pos, start->table->filename)); (ulong) pos, start->table->filename));
DBUG_RETURN(start); DBUG_RETURN(start);
} }
...@@ -153,3 +153,17 @@ j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct ...@@ -153,3 +153,17 @@ j_lj_t3 index id id 4 NULL 2 where used; Using index; Distinct
t3_lj index id id 8 NULL 1 where used; Using index; Distinct t3_lj index id id 8 NULL 1 where used; Using index; Distinct
id id
2 2
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
1 00:36:30
a sec_to_time(sum(time_to_sec(t)))
1 00:06:15
1 00:36:30
...@@ -106,4 +106,10 @@ incr othr ...@@ -106,4 +106,10 @@ incr othr
2 24 2 24
4 33 4 33
3 53 3 53
count(*)
10
count(*)
20
count(*)
20
a a
...@@ -182,3 +182,19 @@ WHERE ...@@ -182,3 +182,19 @@ WHERE
((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2)) ((t1.id=j_lj_t2.id AND t2_lj.id IS NULL) OR (t1.id=t2.id AND t2.idx=2))
AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2)); AND ((t1.id=j_lj_t3.id AND t3_lj.id IS NULL) OR (t1.id=t3.id AND t3.idx=2));
drop table t1,t2,t3; drop table t1,t2,t3;
#
# Test using DISTINCT on a function that contains a group function
# This also test the case when one doesn't use all fields in GROUP BY.
#
drop table if exists t1;
create table t1 (a int not null, b int not null, t time);
insert into t1 values (1,1,"00:06:15"),(1,2,"00:06:15"),(1,2,"00:30:15"),(1,3,"00:06:15"),(1,3,"00:30:15");
select a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
select distinct a,sec_to_time(sum(time_to_sec(t))) from t1 group by a,b;
create table t2 (a int not null primary key, b int);
insert into t2 values (1,1),(2,2),(3,3);
select t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
select distinct t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
drop table t1,t2;
...@@ -35,7 +35,8 @@ select a from t3 order by a desc limit 300,10; ...@@ -35,7 +35,8 @@ select a from t3 order by a desc limit 300,10;
# The following should give errors # The following should give errors
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2); create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
drop table if exists t1,t2,t3,t4; # Because of windows, it's important that we drop the merge tables first!
drop table if exists t4,t3,t1,t2;
create table t1 (c char(10)) type=myisam; create table t1 (c char(10)) type=myisam;
create table t2 (c char(10)) type=myisam; create table t2 (c char(10)) type=myisam;
...@@ -70,6 +71,12 @@ INSERT INTO t1 VALUES (11,20),(13,43),(15,11),(17,22),(19,37); ...@@ -70,6 +71,12 @@ INSERT INTO t1 VALUES (11,20),(13,43),(15,11),(17,22),(19,37);
INSERT INTO t2 VALUES (12,25),(14,31),(16,42),(18,27),(10,30); INSERT INTO t2 VALUES (12,25),(14,31),(16,42),(18,27),(10,30);
SELECT * from t3 where incr in (1,2,3,4) order by othr; SELECT * from t3 where incr in (1,2,3,4) order by othr;
alter table t3 UNION=(t1);
select count(*) from t3;
alter table t3 UNION=(t1,t2);
select count(*) from t3;
alter table t3 TYPE=MYISAM;
select count(*) from t3;
drop table t3,t2,t1; drop table t3,t2,t1;
# #
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
# as such, and clarify ones such as "mediumint" with comments such as # as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx". # "3-byte int" or "same as xxx".
$version="1.54"; $version="1.55";
use DBI; use DBI;
use Getopt::Long; use Getopt::Long;
...@@ -1315,7 +1315,7 @@ report("default value for column",'create_default', ...@@ -1315,7 +1315,7 @@ report("default value for column",'create_default',
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("default value function for column",'create_default_func', report("default value function for column",'create_default_func',
"create table crash_q (q integer not null,q1 integer default (1+1)", "create table crash_q (q integer not null,q1 integer default (1+1))",
"drop table crash_q $drop_attr"); "drop table crash_q $drop_attr");
report("temporary tables",'temporary_table', report("temporary tables",'temporary_table',
...@@ -1696,7 +1696,7 @@ if (!report("drop table with cascade/restrict","drop_restrict", ...@@ -1696,7 +1696,7 @@ if (!report("drop table with cascade/restrict","drop_restrict",
report("-- as comment (ANSI)","comment_--", report("-- as comment (ANSI)","comment_--",
"select * from crash_me -- Testing of comments"); "select * from crash_me -- Testing of comments");
report("// as comment (ANSI)","comment_//", report("// as comment","comment_//",
"select * from crash_me // Testing of comments"); "select * from crash_me // Testing of comments");
report("# as comment","comment_#", report("# as comment","comment_#",
"select * from crash_me # Testing of comments"); "select * from crash_me # Testing of comments");
......
...@@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag) ...@@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag)
errkey = info.errkey; errkey = info.errkey;
table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1; table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1;
table->db_options_in_use = info.options; table->db_options_in_use = info.options;
table->is_view=1;
mean_rec_length=info.reclength; mean_rec_length=info.reclength;
block_size=0; block_size=0;
update_time=0; update_time=0;
......
...@@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd) ...@@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
for (uint i=0; i < arg_count ; i++) for (uint i=0; i < arg_count ; i++)
if (list.push_back(args[i])) if (list.push_back(args[i]))
return 1; return 1;
count_field_types(tmp_table_param,list); count_field_types(tmp_table_param,list,0);
if (table) if (table)
{ {
free_tmp_table(thd, table); free_tmp_table(thd, table);
......
...@@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options) ...@@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options)
long result=1; long result=1;
DBUG_ENTER("mysql_create_db"); DBUG_ENTER("mysql_create_db");
if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) if (!stripp_sp(db) || check_db_name(db))
{ {
net_printf(&thd->net,ER_WRONG_DB_NAME, db); net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) ...@@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists)
MY_DIR *dirp; MY_DIR *dirp;
DBUG_ENTER("mysql_rm_db"); DBUG_ENTER("mysql_rm_db");
if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) if (!stripp_sp(db) || check_db_name(db))
{ {
net_printf(&thd->net,ER_WRONG_DB_NAME, db); net_printf(&thd->net,ER_WRONG_DB_NAME, db);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
join.first_record=join.sort_and_group=0; join.first_record=join.sort_and_group=0;
join.select_options=select_options; join.select_options=select_options;
join.result=result; join.result=result;
count_field_types(&join.tmp_table_param,all_fields); count_field_types(&join.tmp_table_param,all_fields,0);
join.const_tables=0; join.const_tables=0;
join.having=0; join.having=0;
join.group= group != 0; join.group= group != 0;
...@@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* /*
** If we have different sort & group then we must sort the data by group ** If we have different sort & group then we must sort the data by group
** and copy it to another tmp table ** and copy it to another tmp table
** This code is also used if we are using distinct something
** we haven't been able to store in the temporary table yet
** like SEC_TO_TIME(SUM(...)).
*/ */
if (group && (!test_if_subpart(group,order) || select_distinct)) if (group && (!test_if_subpart(group,order) || select_distinct) ||
(select_distinct &&
join.tmp_table_param.using_indirect_summary_function))
{ /* Must copy to another table */ { /* Must copy to another table */
TABLE *tmp_table2; TABLE *tmp_table2;
DBUG_PRINT("info",("Creating group table")); DBUG_PRINT("info",("Creating group table"));
...@@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table)) if (make_simple_join(&join,tmp_table))
goto err; goto err;
calc_group_buffer(&join,group); calc_group_buffer(&join,group);
count_field_types(&join.tmp_table_param,all_fields); count_field_types(&join.tmp_table_param,all_fields,
select_distinct && !group);
join.tmp_table_param.hidden_field_count=(all_fields.elements-
fields.elements);
/* group data to new table */ /* group data to new table */
if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields,
(ORDER*) 0, 0 , 1, 0, (ORDER*) 0,
select_distinct && !group,
1, 0,
join.select_options))) join.select_options)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
if (group) if (group)
...@@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || if (create_sort_index(join.join_tab,group,HA_POS_ERROR) ||
alloc_group_fields(&join,group)) alloc_group_fields(&join,group))
{ {
free_tmp_table(thd,tmp_table2); /* purecov: inspected */ free_tmp_table(thd,tmp_table2); /* purecov: inspected */
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
} }
group=0; group=0;
...@@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (make_simple_join(&join,tmp_table)) if (make_simple_join(&join,tmp_table))
goto err; goto err;
calc_group_buffer(&join,group); calc_group_buffer(&join,group);
count_field_types(&join.tmp_table_param,all_fields); count_field_types(&join.tmp_table_param,all_fields,0);
} }
if (procedure) if (procedure)
{ {
if (procedure->change_columns(fields) || if (procedure->change_columns(fields) ||
result->prepare(fields)) result->prepare(fields))
goto err; goto err;
count_field_types(&join.tmp_table_param,all_fields); count_field_types(&join.tmp_table_param,all_fields,0);
} }
if (join.group || join.tmp_table_param.sum_func_count || if (join.group || join.tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP))) (procedure && (procedure->flags & PROC_GROUP)))
...@@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{ {
TABLE *table; TABLE *table;
uint i,field_count,reclength,null_count,null_pack_length, uint i,field_count,reclength,null_count,null_pack_length,
hidden_null_count, hidden_null_pack_length, hidden_field_count,
blob_count,group_null_items; blob_count,group_null_items;
bool using_unique_constraint=0; bool using_unique_constraint=0;
char *tmpname,path[FN_REFLEN]; char *tmpname,path[FN_REFLEN];
...@@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(*tmp->item)->marker=4; // Store null in key (*tmp->item)->marker=4; // Store null in key
if (param->group_length >= MAX_BLOB_WIDTH) if (param->group_length >= MAX_BLOB_WIDTH)
using_unique_constraint=1; using_unique_constraint=1;
if (group)
distinct=0; // Can't use distinct
} }
field_count=param->field_count+param->func_count+param->sum_func_count; field_count=param->field_count+param->func_count+param->sum_func_count;
hidden_field_count=param->hidden_field_count;
if (!my_multi_malloc(MYF(MY_WME), if (!my_multi_malloc(MYF(MY_WME),
&table,sizeof(*table), &table,sizeof(*table),
&reg_field,sizeof(Field*)*(field_count+1), &reg_field,sizeof(Field*)*(field_count+1),
...@@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->tmp_table=1; table->tmp_table=1;
table->db_low_byte_first=1; // True for HEAP and MyISAM table->db_low_byte_first=1; // True for HEAP and MyISAM
/* Calculate with type of fields we will need in heap table */ /* Calculate which type of fields we will store in the temporary table */
reclength=blob_count=null_count=group_null_items=0; reclength=blob_count=null_count=hidden_null_count=group_null_items=0;
param->using_indirect_summary_function=0;
List_iterator<Item> li(fields); List_iterator<Item> li(fields);
Item *item; Item *item;
...@@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
while ((item=li++)) while ((item=li++))
{ {
Item::Type type=item->type(); Item::Type type=item->type();
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
item->const_item()) {
/*
Mark that the we have ignored an item that refers to a summary
function. We need to know this if someone is going to use
DISTINCT on the result.
*/
param->using_indirect_summary_function=1;
continue;
}
if (item->const_item()) // We don't have to store this
continue; continue;
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
{ /* Can't calc group yet */ { /* Can't calc group yet */
...@@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
} }
*(reg_field++) =new_field; *(reg_field++) =new_field;
} }
if (!--hidden_field_count)
hidden_null_count=null_count;
} }
field_count= (uint) (reg_field - table->field); field_count= (uint) (reg_field - table->field);
...@@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->blob_fields=blob_count; table->blob_fields=blob_count;
if (blob_count == 0) if (blob_count == 0)
null_count++; // For delete link {
reclength+=(null_pack_length=(null_count+7)/8); /* We need to ensure that first byte is not 0 for the delete link */
if (hidden_null_count)
hidden_null_count++;
else
null_count++;
}
hidden_null_pack_length=(hidden_null_count+7)/8;
null_pack_length=hidden_null_count+(null_count+7)/8;
reclength+=null_pack_length;
if (!reclength) if (!reclength)
reclength=1; // Dummy select reclength=1; // Dummy select
...@@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bfill(null_flags,null_pack_length,255); // Set null fields bfill(null_flags,null_pack_length,255); // Set null fields
} }
null_count= (blob_count == 0) ? 1 : 0; null_count= (blob_count == 0) ? 1 : 0;
hidden_field_count=param->hidden_field_count;
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++) for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
{ {
Field *field= *reg_field; Field *field= *reg_field;
...@@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
recinfo->type=FIELD_SKIPP_ENDSPACE; recinfo->type=FIELD_SKIPP_ENDSPACE;
else else
recinfo->type=FIELD_NORMAL; recinfo->type=FIELD_NORMAL;
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
} }
param->copy_field_count=(uint) (copy - param->copy_field); param->copy_field_count=(uint) (copy - param->copy_field);
...@@ -3559,11 +3596,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3559,11 +3596,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
} }
} }
if (distinct && !group) if (distinct)
{ {
/* Create an unique key or an unique constraint over all columns */ /*
keyinfo->key_parts=field_count+ test(null_count); Create an unique key or an unique constraint over all columns
if (distinct && allow_distinct_limit) that should be in the result. In the temporary table, there are
'param->hidden_field_count' extra columns, whose null bits are stored
in the first 'hidden_null_pack_length' bytes of the row.
*/
null_pack_length-=hidden_null_pack_length;
keyinfo->key_parts=field_count+ test(null_pack_length);
if (allow_distinct_limit)
{ {
set_if_smaller(table->max_rows,thd->select_limit); set_if_smaller(table->max_rows,thd->select_limit);
param->end_write_records=thd->select_limit; param->end_write_records=thd->select_limit;
...@@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->flags=HA_NOSAME; keyinfo->flags=HA_NOSAME;
keyinfo->key_length=(uint16) reclength; keyinfo->key_length=(uint16) reclength;
keyinfo->name=(char*) "tmp"; keyinfo->name=(char*) "tmp";
if (null_count) if (null_pack_length)
{ {
key_part_info->null_bit=0; key_part_info->null_bit=0;
key_part_info->offset=0; key_part_info->offset=hidden_null_pack_length;
key_part_info->length=(null_count+7)/8; key_part_info->length=null_pack_length;
key_part_info->field=new Field_string((char*) table->record[0], key_part_info->field=new Field_string((char*) table->record[0],
(uint32) key_part_info->length, (uint32) key_part_info->length,
(uchar*) 0, (uchar*) 0,
...@@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->type= HA_KEYTYPE_BINARY; key_part_info->type= HA_KEYTYPE_BINARY;
key_part_info++; key_part_info++;
} }
for (i=0,reg_field=table->field; i < field_count; for (i=param->hidden_field_count, reg_field=table->field + i ;
i < field_count;
i++, reg_field++, key_part_info++) i++, reg_field++, key_part_info++)
{ {
key_part_info->null_bit=0; key_part_info->null_bit=0;
...@@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields) ...@@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields)
*****************************************************************************/ *****************************************************************************/
void void
count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func)
{ {
List_iterator<Item> li(fields); List_iterator<Item> li(fields);
Item *field; Item *field;
param->field_count=param->sum_func_count= param->field_count=param->sum_func_count=param->func_count=
param->func_count=0; param->hidden_field_count=0;
param->quick_group=1; param->quick_group=1;
while ((field=li++)) while ((field=li++))
{ {
...@@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) ...@@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields)
} }
} }
else else
{
param->func_count++; param->func_count++;
if (reset_with_sum_func)
field->with_sum_func=0;
}
} }
} }
......
...@@ -124,10 +124,13 @@ class TMP_TABLE_PARAM { ...@@ -124,10 +124,13 @@ class TMP_TABLE_PARAM {
KEY *keyinfo; KEY *keyinfo;
ha_rows end_write_records; ha_rows end_write_records;
uint copy_field_count,field_count,sum_func_count,func_count; uint copy_field_count,field_count,sum_func_count,func_count;
uint hidden_field_count;
uint group_parts,group_length; uint group_parts,group_length;
uint quick_group; uint quick_group;
bool using_indirect_summary_function;
TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {} TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0)
{}
~TMP_TABLE_PARAM() ~TMP_TABLE_PARAM()
{ {
cleanup(); cleanup();
...@@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields, ORDER *group, bool distinct, bool save_sum_fields,
bool allow_distinct_limit, uint select_options); bool allow_distinct_limit, uint select_options);
void free_tmp_table(THD *thd, TABLE *entry); void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields); void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);
bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields); bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param); void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item_result_field **func_ptr); void copy_funcs(Item_result_field **func_ptr);
......
...@@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->cuted_fields=0L; thd->cuted_fields=0L;
thd->proc_info="copy to tmp table"; thd->proc_info="copy to tmp table";
next_insert_id=thd->next_insert_id; // Remember for loggin next_insert_id=thd->next_insert_id; // Remember for loggin
error=copy_data_between_tables(table,new_table,create_list,handle_duplicates, copied=deleted=0;
order, &copied,&deleted); if (!new_table->is_view)
error=copy_data_between_tables(table,new_table,create_list,
handle_duplicates,
order, &copied, &deleted);
thd->last_insert_id=next_insert_id; // Needed for correct log thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields=0; /* Don`t calc cuted fields */ thd->count_cuted_fields=0; // Don`t calc cuted fields
new_table->time_stamp=save_time_stamp; new_table->time_stamp=save_time_stamp;
if (table->tmp_table) if (table->tmp_table)
......
...@@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) ...@@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
bool check_db_name(const char *name) bool check_db_name(const char *name)
{ {
const char *start=end;
while (*name) while (*name)
{ {
#if defined(USE_MB) && defined(USE_MB_IDENT) #if defined(USE_MB) && defined(USE_MB_IDENT)
...@@ -1050,7 +1051,7 @@ bool check_db_name(const char *name) ...@@ -1050,7 +1051,7 @@ bool check_db_name(const char *name)
return 1; return 1;
name++; name++;
} }
return 0; return (uint) (name - start) > NAME_LEN;
} }
......
...@@ -93,6 +93,7 @@ struct st_table { ...@@ -93,6 +93,7 @@ struct st_table {
my_bool locked_by_flush; my_bool locked_by_flush;
my_bool locked_by_name; my_bool locked_by_name;
my_bool crashed; my_bool crashed;
my_bool is_view;
Field *next_number_field, /* Set if next_number is activated */ Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */ *found_next_number_field, /* Set on open */
*rowid_field; *rowid_field;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment