Commit e96fcbcf authored by unknown's avatar unknown

Fixed multi-table-delete

Optimize fixed length MyISAM rows to use pread/pwrite.


BUILD/compile-pentium-debug-max:
  Also build embedded server
libmysqld/lib_vio.c:
  Add vio_poll_read()
myisam/mi_statrec.c:
  Use pread()/pwrite() instead of seek+read/write
mysql-test/r/multi_update.result:
  Fix multi-table-delete test
mysql-test/t/multi_update.test:
  Fix multi-table-delete test
sql/filesort.cc:
  Fix multi-table-delete
sql/mysql_priv.h:
  Fix multi-table-delete
sql/sql_class.h:
  Fix multi-table-delete
sql/sql_delete.cc:
  Fix multi-table-delete
sql/sql_parse.cc:
  Fix multi-table-delete
sql/sql_select.cc:
  Fix multi-table-delete
sql/sql_table.cc:
  cleanup
sql/sql_unions.cc:
  cleanup
sql/sql_yacc.yy:
  cleanup/ optimize
sql/structs.h:
  Fix multi-table-delete
sql/uniques.cc:
  Fix multi-table-delete
parent 8d6348f6
...@@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" ...@@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs" extra_configs="$pentium_configs $debug_configs"
extra_configs="$extra_configs --with-berkeley-db --with-innodb" extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server"
. "$path/FINISH.sh" . "$path/FINISH.sh"
...@@ -233,4 +233,9 @@ void vio_in_addr(Vio *vio, struct in_addr *in) ...@@ -233,4 +233,9 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
{ {
} }
my_bool vio_poll_read(Vio *vio,uint timeout)
{
return 0;
}
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */
...@@ -27,17 +27,16 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) ...@@ -27,17 +27,16 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
{ {
my_off_t filepos=info->s->state.dellink; my_off_t filepos=info->s->state.dellink;
info->rec_cache.seek_not_done=1; /* We have done a seek */ info->rec_cache.seek_not_done=1; /* We have done a seek */
VOID(my_seek(info->dfile,info->s->state.dellink+1,MY_SEEK_SET,MYF(0))); if (my_pread(info->dfile,(char*) &temp[0],info->s->base.rec_reflength,
info->s->state.dellink+1,
if (my_read(info->dfile,(char*) &temp[0],info->s->base.rec_reflength, MYF(MY_NABP)))
MYF(MY_NABP)))
goto err; goto err;
info->s->state.dellink= _mi_rec_pos(info->s,temp); info->s->state.dellink= _mi_rec_pos(info->s,temp);
info->state->del--; info->state->del--;
info->state->empty-=info->s->base.pack_reclength; info->state->empty-=info->s->base.pack_reclength;
VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); if (my_pwrite(info->dfile, (char*) record, info->s->base.reclength,
if (my_write(info->dfile, (char*) record, info->s->base.reclength, filepos,
MYF(MY_NABP))) MYF(MY_NABP)))
goto err; goto err;
} }
else else
...@@ -64,16 +63,18 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) ...@@ -64,16 +63,18 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
else else
{ {
info->rec_cache.seek_not_done=1; /* We have done a seek */ info->rec_cache.seek_not_done=1; /* We have done a seek */
VOID(my_seek(info->dfile,info->state->data_file_length, if (my_pwrite(info->dfile,(char*) record,info->s->base.reclength,
MY_SEEK_SET,MYF(0))); info->state->data_file_length,
if (my_write(info->dfile,(char*) record,info->s->base.reclength, info->s->write_flag))
info->s->write_flag))
goto err; goto err;
if (info->s->base.pack_reclength != info->s->base.reclength) if (info->s->base.pack_reclength != info->s->base.reclength)
{ {
uint length=info->s->base.pack_reclength - info->s->base.reclength; uint length=info->s->base.pack_reclength - info->s->base.reclength;
bzero((char*) temp,length); bzero((char*) temp,length);
if (my_write(info->dfile, (byte*) temp,length, info->s->write_flag)) if (my_pwrite(info->dfile, (byte*) temp,length,
info->state->data_file_length+
info->s->base.pack_reclength,
info->s->write_flag))
goto err; goto err;
} }
} }
...@@ -88,9 +89,10 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) ...@@ -88,9 +89,10 @@ int _mi_write_static_record(MI_INFO *info, const byte *record)
int _mi_update_static_record(MI_INFO *info, my_off_t pos, const byte *record) int _mi_update_static_record(MI_INFO *info, my_off_t pos, const byte *record)
{ {
info->rec_cache.seek_not_done=1; /* We have done a seek */ info->rec_cache.seek_not_done=1; /* We have done a seek */
VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0))); return (my_pwrite(info->dfile,
return (my_write(info->dfile,(char*) record,info->s->base.reclength, (char*) record,info->s->base.reclength,
MYF(MY_NABP)) != 0); pos,
MYF(MY_NABP)) != 0);
} }
...@@ -104,9 +106,8 @@ int _mi_delete_static_record(MI_INFO *info) ...@@ -104,9 +106,8 @@ int _mi_delete_static_record(MI_INFO *info)
_mi_dpointer(info,temp+1,info->s->state.dellink); _mi_dpointer(info,temp+1,info->s->state.dellink);
info->s->state.dellink = info->lastpos; info->s->state.dellink = info->lastpos;
info->rec_cache.seek_not_done=1; info->rec_cache.seek_not_done=1;
VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0))); return (my_pwrite(info->dfile,(byte*) temp, 1+info->s->rec_reflength,
return (my_write(info->dfile,(byte*) temp, 1+info->s->rec_reflength, info->lastpos, MYF(MY_NABP)) != 0);
MYF(MY_NABP)) != 0);
} }
...@@ -129,9 +130,9 @@ int _mi_cmp_static_record(register MI_INFO *info, register const byte *old) ...@@ -129,9 +130,9 @@ int _mi_cmp_static_record(register MI_INFO *info, register const byte *old)
if ((info->opt_flag & READ_CHECK_USED)) if ((info->opt_flag & READ_CHECK_USED))
{ /* If check isn't disabled */ { /* If check isn't disabled */
info->rec_cache.seek_not_done=1; /* We have done a seek */ info->rec_cache.seek_not_done=1; /* We have done a seek */
VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0))); if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength, info->lastpos,
MYF(MY_NABP))) MYF(MY_NABP)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
if (memcmp((byte*) info->rec_buff, (byte*) old, if (memcmp((byte*) info->rec_buff, (byte*) old,
(uint) info->s->base.reclength)) (uint) info->s->base.reclength))
...@@ -152,9 +153,8 @@ int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def, ...@@ -152,9 +153,8 @@ int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
DBUG_ENTER("_mi_cmp_static_unique"); DBUG_ENTER("_mi_cmp_static_unique");
info->rec_cache.seek_not_done=1; /* We have done a seek */ info->rec_cache.seek_not_done=1; /* We have done a seek */
VOID(my_seek(info->dfile,pos,MY_SEEK_SET,MYF(0))); if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength,
if (my_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength, pos, MYF(MY_NABP)))
MYF(MY_NABP)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff, DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff,
def->null_are_equal)); def->null_are_equal));
......
id1 t id1 t
1 3 1 3
2 2 2 2
3 1
id2 t id2 t
3 3
3 2
3 1
2 3
2 2
2 1
1 3 1 3
1 2 1 2
1 1 1 1
id3 t id3 t
3 3
3 2
3 1
2 3 2 3
2 2 2 2
2 1 2 1
......
...@@ -16,10 +16,11 @@ while ($1) ...@@ -16,10 +16,11 @@ while ($1)
dec $1; dec $1;
} }
delete t1.*,t2.* from t1,t2 where t1.id1 = t2.id2 and t1.id1 = 3;
delete t3 from t3 left join t1 on (id1=id3) where t1.id1 is null;
delete t2 from t1,t2,t3 where id1=id2 and id2=id3 and id1=2;
select * from t1; select * from t1;
select * from t2; select * from t2;
select * from t3; select * from t3;
delete t1,t2 from t1,t2 where 1;
delete from t1,t2 where t1.id = t2.id and t1.id = 3; drop table t1,t2,t3;
select * from t1;
select * from t2;
...@@ -724,6 +724,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, ...@@ -724,6 +724,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
{ {
error=1; goto err; /* purecov: inspected */ error=1; goto err; /* purecov: inspected */
} }
buffpek->key+=sort_length;
queue_replaced(&queue); // Top element has been used
} }
else else
cmp=0; // Not unique cmp=0; // Not unique
......
...@@ -147,7 +147,7 @@ void kill_one_thread(THD *thd, ulong id); ...@@ -147,7 +147,7 @@ void kill_one_thread(THD *thd, ulong id);
#define SELECT_BIG_RESULT 16 #define SELECT_BIG_RESULT 16
#define OPTION_FOUND_ROWS 32 #define OPTION_FOUND_ROWS 32
#define SELECT_HIGH_PRIORITY 64 /* Intern */ #define SELECT_HIGH_PRIORITY 64 /* Intern */
#define SELECT_USE_CACHE 256 /* Intern */ #define SELECT_NO_JOIN_CACHE 256 /* Intern */
#define OPTION_BIG_TABLES 512 /* for SQL OPTION */ #define OPTION_BIG_TABLES 512 /* for SQL OPTION */
#define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */ #define OPTION_BIG_SELECTS 1024 /* for SQL OPTION */
......
...@@ -600,7 +600,6 @@ class Unique :public Sql_alloc ...@@ -600,7 +600,6 @@ class Unique :public Sql_alloc
#else #else
Unique **tempfiles; Unique **tempfiles;
#endif #endif
byte * dup_checking;
THD *thd; THD *thd;
ha_rows deleted; ha_rows deleted;
uint num_of_tables; uint num_of_tables;
...@@ -608,12 +607,8 @@ class Unique :public Sql_alloc ...@@ -608,12 +607,8 @@ class Unique :public Sql_alloc
thr_lock_type lock_option; thr_lock_type lock_option;
bool do_delete; bool do_delete;
public: public:
multi_delete(TABLE_LIST *dt, thr_lock_type lock_option_arg, uint n) multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg,
: delete_tables (dt), deleted(0), num_of_tables(n), error(0), uint num_of_tables);
lock_option(lock_option_arg)
{
thd = current_thd; do_delete = false;
}
~multi_delete(); ~multi_delete();
int prepare(List<Item> &list); int prepare(List<Item> &list);
bool send_fields(List<Item> &list, bool send_fields(List<Item> &list,
......
This diff is collapsed.
...@@ -1649,97 +1649,98 @@ mysql_execute_command(void) ...@@ -1649,97 +1649,98 @@ mysql_execute_command(void)
if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd)) if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
res= -1; res= -1;
else else
res = mysql_delete(thd,tables, select_lex->where, (ORDER*)select_lex->order_list.first, res = mysql_delete(thd,tables, select_lex->where,
select_lex->select_limit, lex->lock_option, select_lex->options); (ORDER*) select_lex->order_list.first,
select_lex->select_limit, lex->lock_option,
select_lex->options);
break; break;
} }
case SQLCOM_MULTI_DELETE: case SQLCOM_MULTI_DELETE:
{ {
TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first; TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first;
multi_delete *result; TABLE_LIST *auxi;
uint table_count=0;
multi_delete *result;
if (!tables || !aux_tables || /* sql_yacc guarantees that tables and aux_tables are not zero */
check_table_access(thd,SELECT_ACL, tables) || if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
check_table_access(thd,DELETE_ACL,aux_tables)) check_table_access(thd,SELECT_ACL, tables) ||
{ check_table_access(thd,DELETE_ACL, aux_tables))
res=-1; goto error;
goto error; if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
} {
if (!tables->db) send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
tables->db=thd->db; goto error;
if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) }
{ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); {
res=1; goto error; table_count++;
} /* All tables in aux_tables must be found in FROM PART */
uint howmuch=0; TABLE_LIST *walk, *auxi; TABLE_LIST *walk;
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next, howmuch++) for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next)
{ {
if (!auxi->db) if (!strcmp(auxi->real_name,walk->real_name) &&
auxi->db=thd->db; !strcmp(walk->db,auxi->db))
if (!auxi->real_name) break;
auxi->real_name=auxi->name; }
for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next) if (!walk)
{ {
if (!walk->db) walk->db=thd->db; net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name);
if (!strcmp(auxi->real_name,walk->real_name) && !strcmp(walk->db,auxi->db)) goto error;
break; }
} auxi->lock_type=walk->lock_type=TL_WRITE;
if (!walk) auxi->table= (TABLE *) walk; // Remember corresponding table
{ }
net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
res=-2; goto error; if (add_item_to_list(new Item_null()))
} {
else res= -1;
{ break;
auxi->lock_type=walk->lock_type=TL_WRITE; }
auxi->table= (TABLE *) walk; thd->proc_info="init";
} if ((res=open_and_lock_tables(thd,tables)))
} break;
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); /* Fix tables-to-be-deleted-from list to point at opened tables */
if (add_item_to_list(new Item_null())) goto error; for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
thd->proc_info="init"; auxi->table= ((TABLE_LIST*) auxi->table)->table;
if (open_and_lock_tables(thd,tables)) if ((result=new multi_delete(thd,aux_tables,lex->lock_option,
{ table_count)) && ! thd->fatal_error)
res=-1; goto error; {
} res=mysql_select(thd,tables,select_lex->item_list,
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) select_lex->where,select_lex->ftfunc_list,
auxi->table= ((TABLE_LIST*) auxi->table)->table; (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
if ((result=new multi_delete(aux_tables,lex->lock_option,howmuch))) (ORDER *)NULL,
{ select_lex->options | thd->options |
res=mysql_select(thd,tables,select_lex->item_list, SELECT_NO_JOIN_CACHE,
select_lex->where,select_lex->ftfunc_list, result);
(ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, }
(ORDER *)NULL, else
select_lex->options | thd->options, res= -1; // Error is not sent
result); delete result;
delete result; close_thread_tables(thd);
} break;
else }
res= -1;
close_thread_tables(thd);
break;
}
case SQLCOM_UNION_SELECT: case SQLCOM_UNION_SELECT:
{ {
uint total_selects = select_lex->select_number; total_selects++;
SQL_LIST *total=(SQL_LIST *) thd->calloc(sizeof(SQL_LIST)); SQL_LIST *total=(SQL_LIST *) thd->calloc(sizeof(SQL_LIST));
if (select_lex->options & SELECT_DESCRIBE) if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0; lex->exchange=0;
res = link_in_large_list_and_check_acl(thd,lex,total); if ((res = link_in_large_list_and_check_acl(thd,lex,total)) == -1)
if (res == -1)
{ {
res=0; res=0;
break; break;
} }
if (res && (res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, any_db))) if (res &&
(res=check_access(thd,
lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
any_db)))
{ {
res=0; res=0;
break; break;
} }
if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first))) if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first)))
{ {
res=mysql_union(thd,lex,total_selects); res=mysql_union(thd,lex, select_lex->select_number+1);
if (res==-1) res=0; if (res==-1) res=0;
} }
break; break;
...@@ -1768,7 +1769,7 @@ mysql_execute_command(void) ...@@ -1768,7 +1769,7 @@ mysql_execute_command(void)
break; break;
case SQLCOM_SHOW_DATABASES: case SQLCOM_SHOW_DATABASES:
#if defined(DONT_ALLOW_SHOW_COMMANDS) #if defined(DONT_ALLOW_SHOW_COMMANDS)
send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
#else #else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) && if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
......
...@@ -484,8 +484,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -484,8 +484,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
(group && order) || (group && order) ||
test(select_options & OPTION_BUFFER_RESULT))); test(select_options & OPTION_BUFFER_RESULT)));
make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) | // No cache for MATCH
(ftfuncs.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH make_join_readinfo(&join,
(select_options & (SELECT_DESCRIBE |
SELECT_NO_JOIN_CACHE)) |
(ftfuncs.elements ? SELECT_NO_JOIN_CACHE : 0));
/* Need to tell Innobase that to play it safe, it should fetch all /* Need to tell Innobase that to play it safe, it should fetch all
columns of the tables: this is because MySQL columns of the tables: this is because MySQL
...@@ -2465,7 +2468,7 @@ make_join_readinfo(JOIN *join,uint options) ...@@ -2465,7 +2468,7 @@ make_join_readinfo(JOIN *join,uint options)
** if previous table use cache ** if previous table use cache
*/ */
table->status=STATUS_NO_RECORD; table->status=STATUS_NO_RECORD;
if (i != join->const_tables && (options & SELECT_USE_CACHE) && if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
tab->use_quick != 2 && !tab->on_expr) tab->use_quick != 2 && !tab->on_expr)
{ {
if ((options & SELECT_DESCRIBE) || if ((options & SELECT_DESCRIBE) ||
......
...@@ -59,9 +59,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) ...@@ -59,9 +59,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
pthread_mutex_unlock(&thd->mysys_var->mutex); pthread_mutex_unlock(&thd->mysys_var->mutex);
if(global_read_lock) if (global_read_lock)
{ {
if(thd->global_read_lock) if (thd->global_read_lock)
{ {
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
tables->real_name); tables->real_name);
......
...@@ -30,4 +30,5 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) ...@@ -30,4 +30,5 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
for (sl=&lex->select_lex;sl;sl=sl->next) for (sl=&lex->select_lex;sl;sl=sl->next)
{ {
} }
return 0;
} }
This diff is collapsed.
...@@ -164,3 +164,4 @@ typedef struct st_lex_user { ...@@ -164,3 +164,4 @@ typedef struct st_lex_user {
#define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_NOT_READ 8 /* Record isn't read */
#define STATUS_UPDATED 16 /* Record is updated by formula */ #define STATUS_UPDATED 16 /* Record is updated by formula */
#define STATUS_NULL_ROW 32 /* table->null_row is set */ #define STATUS_NULL_ROW 32 /* table->null_row is set */
#define STATUS_DELETED 64
...@@ -44,7 +44,8 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, ...@@ -44,7 +44,8 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
/* If the following fail's the next add will also fail */ /* If the following fail's the next add will also fail */
init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size); max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)); open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
MYF(MY_WME));
} }
...@@ -95,7 +96,7 @@ bool Unique::get(TABLE *table) ...@@ -95,7 +96,7 @@ bool Unique::get(TABLE *table)
SORTPARAM sort_param; SORTPARAM sort_param;
table->found_records=elements+tree.elements_in_tree; table->found_records=elements+tree.elements_in_tree;
if (!my_b_inited(&file)) if (my_b_tell(&file) == 0)
{ {
/* Whole tree is in memory; Don't use disk if you don't need to */ /* Whole tree is in memory; Don't use disk if you don't need to */
if ((record_pointers=table->record_pointers= (byte*) if ((record_pointers=table->record_pointers= (byte*)
...@@ -110,17 +111,16 @@ bool Unique::get(TABLE *table) ...@@ -110,17 +111,16 @@ bool Unique::get(TABLE *table)
if (flush()) if (flush())
return 1; return 1;
IO_CACHE *outfile=table->io_cache, tempfile; IO_CACHE *outfile=table->io_cache;
BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer; BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
uint maxbuffer= file_ptrs.elements - 1; uint maxbuffer= file_ptrs.elements - 1;
uchar *sort_buffer; uchar *sort_buffer;
my_off_t save_pos; my_off_t save_pos;
bool error=1; bool error=1;
my_b_clear(&tempfile);
/* Open cached file if it isn't open */ /* Open cached file if it isn't open */
outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),MYF(MY_ZEROFILL)); outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_ZEROFILL));
if (!outfile || ! my_b_inited(outfile) && if (!outfile || ! my_b_inited(outfile) &&
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
...@@ -134,25 +134,24 @@ bool Unique::get(TABLE *table) ...@@ -134,25 +134,24 @@ bool Unique::get(TABLE *table)
sort_param.keys= max_in_memory_size / sort_param.sort_length; sort_param.keys= max_in_memory_size / sort_param.sort_length;
if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) * if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
sort_param.sort_length, sort_param.sort_length,
MYF(0)))) MYF(0))))
return 1; return 1;
sort_param.unique_buff= sort_buffer+(sort_param.keys* sort_param.unique_buff= sort_buffer+(sort_param.keys*
sort_param.sort_length); sort_param.sort_length);
/* Merge the buffers to one file, removing duplicates */ /* Merge the buffers to one file, removing duplicates */
if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&tempfile)) if (merge_many_buff(&sort_param,sort_buffer,file_ptr,&maxbuffer,&file))
goto err; goto err;
if (flush_io_cache(&tempfile) || if (flush_io_cache(&file) ||
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) reinit_io_cache(&file,READ_CACHE,0L,0,0))
goto err; goto err;
if (merge_buffers(&sort_param, &tempfile, outfile, sort_buffer, file_ptr, if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
file_ptr, file_ptr+maxbuffer,0)) file_ptr, file_ptr+maxbuffer,0))
goto err; goto err;
error=0; error=0;
err: err:
x_free((gptr) sort_buffer); x_free((gptr) sort_buffer);
close_cached_file(&tempfile);
if (flush_io_cache(outfile)) if (flush_io_cache(outfile))
error=1; error=1;
......
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