diff options
author | monty@hundin.mysql.fi <> | 2001-06-15 05:03:15 +0300 |
---|---|---|
committer | monty@hundin.mysql.fi <> | 2001-06-15 05:03:15 +0300 |
commit | a06f391e7ada4c05e34e54a517014aa3968d7df4 (patch) | |
tree | 90883e19e7220eb27c1fa092220fe373c7e82d80 | |
parent | 595d087e05579a9b8420b9267423b054fcca42c9 (diff) | |
download | mariadb-git-a06f391e7ada4c05e34e54a517014aa3968d7df4.tar.gz |
Fixed multi-table-delete
Optimize fixed length MyISAM rows to use pread/pwrite.
-rwxr-xr-x | BUILD/compile-pentium-debug-max | 2 | ||||
-rw-r--r-- | libmysqld/lib_vio.c | 5 | ||||
-rw-r--r-- | myisam/mi_statrec.c | 48 | ||||
-rw-r--r-- | mysql-test/r/multi_update.result | 10 | ||||
-rw-r--r-- | mysql-test/t/multi_update.test | 9 | ||||
-rw-r--r-- | sql/filesort.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 9 | ||||
-rw-r--r-- | sql/sql_delete.cc | 297 | ||||
-rw-r--r-- | sql/sql_parse.cc | 149 | ||||
-rw-r--r-- | sql/sql_select.cc | 9 | ||||
-rw-r--r-- | sql/sql_table.cc | 4 | ||||
-rw-r--r-- | sql/sql_unions.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 640 | ||||
-rw-r--r-- | sql/structs.h | 1 | ||||
-rw-r--r-- | sql/uniques.cc | 25 |
16 files changed, 727 insertions, 486 deletions
diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index dc88bab62d3..4149267811d 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" 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" diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c index 3238fd59699..35deaf8d090 100644 --- a/libmysqld/lib_vio.c +++ b/libmysqld/lib_vio.c @@ -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 */ diff --git a/myisam/mi_statrec.c b/myisam/mi_statrec.c index 05ff40d8921..7af8c304c0f 100644 --- a/myisam/mi_statrec.c +++ b/myisam/mi_statrec.c @@ -27,17 +27,16 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) { my_off_t filepos=info->s->state.dellink; 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_read(info->dfile,(char*) &temp[0],info->s->base.rec_reflength, - MYF(MY_NABP))) + if (my_pread(info->dfile,(char*) &temp[0],info->s->base.rec_reflength, + info->s->state.dellink+1, + MYF(MY_NABP))) goto err; info->s->state.dellink= _mi_rec_pos(info->s,temp); info->state->del--; info->state->empty-=info->s->base.pack_reclength; - VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); - if (my_write(info->dfile, (char*) record, info->s->base.reclength, - MYF(MY_NABP))) + if (my_pwrite(info->dfile, (char*) record, info->s->base.reclength, + filepos, + MYF(MY_NABP))) goto err; } else @@ -64,16 +63,18 @@ int _mi_write_static_record(MI_INFO *info, const byte *record) else { info->rec_cache.seek_not_done=1; /* We have done a seek */ - VOID(my_seek(info->dfile,info->state->data_file_length, - MY_SEEK_SET,MYF(0))); - if (my_write(info->dfile,(char*) record,info->s->base.reclength, - info->s->write_flag)) + if (my_pwrite(info->dfile,(char*) record,info->s->base.reclength, + info->state->data_file_length, + info->s->write_flag)) goto err; if (info->s->base.pack_reclength != info->s->base.reclength) { uint length=info->s->base.pack_reclength - info->s->base.reclength; 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; } } @@ -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) { 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_write(info->dfile,(char*) record,info->s->base.reclength, - MYF(MY_NABP)) != 0); + return (my_pwrite(info->dfile, + (char*) record,info->s->base.reclength, + pos, + MYF(MY_NABP)) != 0); } @@ -104,9 +106,8 @@ int _mi_delete_static_record(MI_INFO *info) _mi_dpointer(info,temp+1,info->s->state.dellink); info->s->state.dellink = info->lastpos; info->rec_cache.seek_not_done=1; - VOID(my_seek(info->dfile,info->lastpos,MY_SEEK_SET,MYF(0))); - return (my_write(info->dfile,(byte*) temp, 1+info->s->rec_reflength, - MYF(MY_NABP)) != 0); + return (my_pwrite(info->dfile,(byte*) temp, 1+info->s->rec_reflength, + info->lastpos, MYF(MY_NABP)) != 0); } @@ -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 check isn't disabled */ 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_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength, - MYF(MY_NABP))) + if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength, + info->lastpos, + MYF(MY_NABP))) DBUG_RETURN(-1); if (memcmp((byte*) info->rec_buff, (byte*) old, (uint) info->s->base.reclength)) @@ -152,9 +153,8 @@ int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def, DBUG_ENTER("_mi_cmp_static_unique"); 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_read(info->dfile, (char*) info->rec_buff, info->s->base.reclength, - MYF(MY_NABP))) + if (my_pread(info->dfile, (char*) info->rec_buff, info->s->base.reclength, + pos, MYF(MY_NABP))) DBUG_RETURN(-1); DBUG_RETURN(mi_unique_comp(def, record, info->rec_buff, def->null_are_equal)); diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 21852771c46..f8c51f25237 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -1,21 +1,11 @@ id1 t 1 3 2 2 -3 1 id2 t -3 3 -3 2 -3 1 -2 3 -2 2 -2 1 1 3 1 2 1 1 id3 t -3 3 -3 2 -3 1 2 3 2 2 2 1 diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index c9c705b2e64..a1ebc64504f 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -16,10 +16,11 @@ while ($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 t2; select * from t3; - -delete from t1,t2 where t1.id = t2.id and t1.id = 3; -select * from t1; -select * from t2; +delete t1,t2 from t1,t2 where 1; +drop table t1,t2,t3; diff --git a/sql/filesort.cc b/sql/filesort.cc index 76f6bc4c33c..eec619fc7a6 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -724,6 +724,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, { error=1; goto err; /* purecov: inspected */ } + buffpek->key+=sort_length; + queue_replaced(&queue); // Top element has been used } else cmp=0; // Not unique diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 66a68b52b7f..fd0ab984dda 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -147,7 +147,7 @@ void kill_one_thread(THD *thd, ulong id); #define SELECT_BIG_RESULT 16 #define OPTION_FOUND_ROWS 32 #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_SELECTS 1024 /* for SQL OPTION */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 6963b890051..dc66f3464df 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -600,7 +600,6 @@ public: #else Unique **tempfiles; #endif - byte * dup_checking; THD *thd; ha_rows deleted; uint num_of_tables; @@ -608,12 +607,8 @@ public: thr_lock_type lock_option; bool do_delete; public: - multi_delete(TABLE_LIST *dt, thr_lock_type lock_option_arg, uint n) - : delete_tables (dt), deleted(0), num_of_tables(n), error(0), - lock_option(lock_option_arg) - { - thd = current_thd; do_delete = false; - } + multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg, + uint num_of_tables); ~multi_delete(); int prepare(List<Item> &list); bool send_fields(List<Item> &list, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index dbcd38180dc..0376ef09ee1 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -286,112 +286,157 @@ int mysql_delete(THD *thd, } - - /*************************************************************************** ** delete multiple tables from join ***************************************************************************/ - +#ifndef DBUG_OFF #define MEM_STRIP_BUF_SIZE 2048 +#else +#define MEM_STRIP_BUF_SIZE sortbuffer_size +#endif + #ifndef SINISAS_STRIP int refposcmp2(void* arg, const void *a,const void *b) { - return memcmp(a,b,(int)arg); + return memcmp(a,b,(int) arg); } #endif -int -multi_delete::prepare(List<Item> &values) +multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, + thr_lock_type lock_option_arg, + uint num_of_tables_arg) + : delete_tables (dt), thd(thd_arg), deleted(0), + num_of_tables(num_of_tables_arg), error(0), lock_option(lock_option_arg), + do_delete(false) { - DBUG_ENTER("multi_delete::prepare"); - uint counter = 0; + uint counter=0; #ifdef SINISAS_STRIP - tempfiles = (IO_CACHE **) sql_calloc(sizeof(IO_CACHE *)*(num_of_tables)); + tempfiles = (IO_CACHE **) sql_calloc(sizeof(IO_CACHE *)* num_of_tables); memory_lane = (byte *)sql_alloc(MAX_REFLENGTH*MEM_STRIP_BUF_SIZE); #else - tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables)); + tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); #endif - do_delete = true; - dup_checking = (byte *) sql_calloc(MAX_REFLENGTH * (num_of_tables + 1)); - memset(dup_checking,'\xFF', MAX_REFLENGTH * (num_of_tables + 1)); - for (table_being_deleted=delete_tables; table_being_deleted; table_being_deleted=table_being_deleted->next, counter++) + + (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); + /* Don't use key read with MULTI-TABLE-DELETE */ + dt->table->used_keys=0; + for (dt=dt->next ; dt ; dt=dt->next,counter++) { - TABLE *table=table_being_deleted->table; - if ((thd->options & OPTION_SAFE_UPDATES) && !table->quick_keys) + TABLE *table=dt->table; + (void) table->file->extra(HA_EXTRA_NO_READCHECK); +#ifdef SINISAS_STRIP + tempfiles[counter]=(IO_CACHE *) sql_alloc(sizeof(IO_CACHE)); + if (open_cached_file(tempfiles[counter], mysql_tmpdir,TEMP_PREFIX, + DISK_BUFFER_SIZE, MYF(MY_WME))) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0)); - DBUG_RETURN(1); + my_error(ER_CANT_OPEN_FILE,MYF(0),(tempfiles[counter])->file_name,errno); + thd->fatal_error=1; + return; } - (void) table->file->extra(HA_EXTRA_NO_READCHECK); - if (counter < num_of_tables) +#else + tempfiles[counter] = new Unique (refposcmp2, + (void *) table->file->ref_length, + table->file->ref_length, + MEM_STRIP_BUF_SIZE); +#endif + } +} + + +int +multi_delete::prepare(List<Item> &values) +{ + DBUG_ENTER("multi_delete::prepare"); + do_delete = true; + thd->proc_info="deleting from main table"; + + if (thd->options & OPTION_SAFE_UPDATES) + { + TABLE_LIST *table_ref; + for (table_ref=delete_tables; table_ref; table_ref=table_ref->next) { -#ifdef SINISAS_STRIP - tempfiles[counter]=(IO_CACHE *)sql_alloc(sizeof(IO_CACHE)); - if (open_cached_file(tempfiles[counter], mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME))) + TABLE *table=table_ref->table; + if ((thd->options & OPTION_SAFE_UPDATES) && !table->quick_keys) { - my_error(ER_CANT_OPEN_FILE,MYF(0),(tempfiles[counter])->file_name,errno); + my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0)); DBUG_RETURN(1); } -#else - tempfiles[counter] = new Unique (refposcmp2,(void *)table->file->ref_length,table->file->ref_length,MEM_STRIP_BUF_SIZE); -#endif } } - thd->proc_info="updating"; DBUG_RETURN(0); } + multi_delete::~multi_delete() { - for (uint counter = 0; counter < num_of_tables; counter++) + + /* Add back EXTRA_READCHECK; In 4.0.1 we shouldn't need this anymore */ + for (table_being_deleted=delete_tables ; + table_being_deleted ; + table_being_deleted=table_being_deleted->next) + { + VOID(table_being_deleted->table->file->extra(HA_EXTRA_READCHECK)); + } + for (uint counter = 0; counter < num_of_tables-1; counter++) + { if (tempfiles[counter]) + { #ifdef SINISAS_STRIP // end_io_cache(tempfiles[counter]); #else - delete tempfiles[counter]; + delete tempfiles[counter]; #endif -// Here it crashes ... + } + } } + bool multi_delete::send_data(List<Item> &values) { - int secure_counter = -1; - for (table_being_deleted=delete_tables ; table_being_deleted ; table_being_deleted=table_being_deleted->next, secure_counter++) + int secure_counter= -1; + for (table_being_deleted=delete_tables ; + table_being_deleted ; + table_being_deleted=table_being_deleted->next, secure_counter++) { TABLE *table=table_being_deleted->table; - table->file->position(table->record[0]); int rl = table->file->ref_length; - byte *dup_check = dup_checking + (secure_counter + 1)*MAX_REFLENGTH; - if (!table->null_row && memcmp(dup_check,table->file->ref, rl)) + + /* Check if we are using outer join and we didn't find the row */ + if (table->status & (STATUS_NULL_ROW | STATUS_DELETED)) + continue; + + table->file->position(table->record[0]); + int rl = table->file->ref_length; + + if (secure_counter < 0) { - memcpy(dup_check,table->file->ref,rl); - if (secure_counter == -1) - { - if (!(error=table->file->delete_row(table->record[0]))) - deleted++; - else - { - send_error(error,"An error occured in deleting rows"); - return 1; - } - } + table->status|= STATUS_DELETED; + if (!(error=table->file->delete_row(table->record[0]))) + deleted++; else { + table->file->print_error(error,MYF(0)); + return 1; + } + } + else + { #ifdef SINISAS_STRIP - if (my_b_write(tempfiles[secure_counter],table->file->ref,rl)) + error=my_b_write(tempfiles[secure_counter],table->file->ref,rl); #else - if (tempfiles[secure_counter]->unique_add(table->file->ref)) + error=tempfiles[secure_counter]->unique_add(table->file->ref); #endif - { - error=-1; - return 1; - } - } + if (error) + { + error=-1; + return 1; + } } } return 0; } + #ifdef SINISAS_STRIP static inline int COMP (byte *ml,uint len,unsigned int left, unsigned int right) { @@ -712,14 +757,15 @@ static IO_CACHE *strip_duplicates_from_temp (byte *memory_lane, IO_CACHE *ptr, u } } -#endif +#endif /* SINISAS_STRIP */ + +/* Return true if some table is not transaction safe */ static bool some_table_is_not_transaction_safe (TABLE_LIST *tl) { - TABLE_LIST *deleting = tl; - for (deleting=deleting->next; deleting ; deleting=deleting->next) + for (; tl ; tl=tl->next) { - if (!(deleting->table->file->has_transactions())) + if (!(tl->table->file->has_transactions())) return true; } return false; @@ -728,35 +774,52 @@ static bool some_table_is_not_transaction_safe (TABLE_LIST *tl) void multi_delete::send_error(uint errcode,const char *err) { -// First send error what ever it is ... + /* First send error what ever it is ... */ ::send_error(&thd->net,errcode,err); -// If nothing deleted return - if (!deleted) return; -// Below can happen when thread is killed ... - if (!table_being_deleted) table_being_deleted=delete_tables; -// If rows from the first table only has been deleted and it is transactional, just do rollback -// The same if all tables are transactional, regardless of where we are. In all other cases do attempt deletes ... - if ((table_being_deleted->table->file->has_transactions() && table_being_deleted == delete_tables) || !some_table_is_not_transaction_safe(delete_tables)) - ha_rollback(current_thd); + /* If nothing deleted return */ + if (!deleted) + return; + /* Below can happen when thread is killed early ... */ + if (!table_being_deleted) + table_being_deleted=delete_tables; + + /* + If rows from the first table only has been deleted and it is transactional, + just do rollback. + The same if all tables are transactional, regardless of where we are. + In all other cases do attempt deletes ... + */ + if ((table_being_deleted->table->file->has_transactions() && + table_being_deleted == delete_tables) || + !some_table_is_not_transaction_safe(delete_tables->next)) + ha_rollback(thd); else if (do_delete) VOID(do_deletes(true)); } -int multi_delete::do_deletes (bool from_send_error) + +int multi_delete::do_deletes (bool from_send_error) { - TABLE *table; int error = 0, counter = 0, count; + if (from_send_error) { - for (TABLE_LIST *aux=delete_tables; aux != table_being_deleted; aux=aux->next) + /* Found out table number for 'table_being_deleted' */ + for (TABLE_LIST *aux=delete_tables; + aux != table_being_deleted; + aux=aux->next) counter++; } else table_being_deleted = delete_tables; + do_delete = false; - for (table_being_deleted=table_being_deleted->next; table_being_deleted ; counter++, table_being_deleted=table_being_deleted->next) + for (table_being_deleted=table_being_deleted->next; + table_being_deleted ; + table_being_deleted=table_being_deleted->next, counter++) { - table = table_being_deleted->table; int rl = table->file->ref_length; + TABLE *table = table_being_deleted->table; + int rl = table->file->ref_length; #ifdef SINISAS_STRIP int num_of_positions = (int)my_b_tell(tempfiles[counter])/rl; if (!num_of_positions) continue; @@ -766,11 +829,20 @@ int multi_delete::do_deletes (bool from_send_error) error=1; break; } #else - tempfiles[counter]->get(table); + if (tempfiles[counter]->get(table)) + { + error=1; + break; + } #endif -#if 0 - if (num_of_positions == table->file->records) // nice little optimization .... - { // but Monty has to fix generate_table... + +#if USE_REGENERATE_TABLE + // nice little optimization .... + // but Monty has to fix generate_table... + // This will not work for transactional tables because for other types + // records is not absolute + if (num_of_positions == table->file->records) + { TABLE_LIST table_list; bzero((char*) &table_list,sizeof(table_list)); table_list.name=table->table_name; table_list.real_name=table_being_deleted->real_name; @@ -780,69 +852,66 @@ int multi_delete::do_deletes (bool from_send_error) error=generate_table(thd,&table_list,(TABLE *)0); if (error <= 0) {error = 1; break;} deleted += num_of_positions; + continue; } - else - { -#endif - READ_RECORD info; error=0; +#endif /* USE_REGENERATE_TABLE */ + + READ_RECORD info; + error=0; #ifdef SINISAS_STRIP - SQL_SELECT *select= new SQL_SELECT; - select->head=table; - select->file=*tempfiles[counter]; - init_read_record(&info,thd,table,select,0,0); + SQL_SELECT *select= new SQL_SELECT; + select->head=table; + select->file=*tempfiles[counter]; + init_read_record(&info,thd,table,select,0,0); #else - init_read_record(&info,thd,table,NULL,0,0); + init_read_record(&info,thd,table,NULL,0,0); #endif - bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables); - while (!(error=info.read_record(&info)) && (!thd->killed || from_send_error || not_trans_safe)) + bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables); + while (!(error=info.read_record(&info)) && + (!thd->killed || from_send_error || not_trans_safe)) + { + error=table->file->delete_row(table->record[0]); + if (error) { - error=table->file->delete_row(table->record[0]); - if (error) - { - table->file->print_error(error,MYF(0)); - break; - } - else - deleted++; + table->file->print_error(error,MYF(0)); + break; } - end_read_record(&info); -#ifdef SINISAS_STRIP - delete select; -#endif - if (error == -1) - error = 0; -#if 0 + else + deleted++; } + end_read_record(&info); +#ifdef SINISAS_STRIP + delete select; #endif + if (error == -1) + error = 0; } return error; } + bool multi_delete::send_eof() { - int error = 0; - error = do_deletes(false); + thd->proc_info="deleting from reference tables"; + int error = do_deletes(false); + thd->proc_info="end"; if (error && error != -1) { ::send_error(&thd->net); return 1; } - for (table_being_deleted=delete_tables ; table_being_deleted ; table_being_deleted=table_being_deleted->next) - { - TABLE *table=table_being_deleted->table; - if (table) - VOID(table->file->extra(HA_EXTRA_READCHECK)); - } - if (deleted && (error <= 0 || some_table_is_not_transaction_safe(delete_tables))) + + if (deleted && + (error <= 0 || some_table_is_not_transaction_safe(delete_tables))) { mysql_update_log.write(thd,thd->query,thd->query_length); Query_log_event qinfo(thd, thd->query); - if (mysql_bin_log.write(&qinfo) && !some_table_is_not_transaction_safe(delete_tables)) - error=1; + if (mysql_bin_log.write(&qinfo) && + !some_table_is_not_transaction_safe(delete_tables)) + error=1; // Rollback VOID(ha_autocommit_or_rollback(thd,error >= 0)); } ::send_ok(&thd->net,deleted); return 0; - } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 20e33516225..6b71d7e3615 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1649,97 +1649,98 @@ mysql_execute_command(void) if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd)) res= -1; else - res = mysql_delete(thd,tables, select_lex->where, (ORDER*)select_lex->order_list.first, - select_lex->select_limit, lex->lock_option, select_lex->options); + res = mysql_delete(thd,tables, select_lex->where, + (ORDER*) select_lex->order_list.first, + select_lex->select_limit, lex->lock_option, + select_lex->options); break; } - case SQLCOM_MULTI_DELETE: - { - TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first; - multi_delete *result; + case SQLCOM_MULTI_DELETE: + { + TABLE_LIST *aux_tables=(TABLE_LIST *)thd->lex.auxilliary_table_list.first; + TABLE_LIST *auxi; + uint table_count=0; + multi_delete *result; - if (!tables || !aux_tables || - check_table_access(thd,SELECT_ACL, tables) || - check_table_access(thd,DELETE_ACL,aux_tables)) - { - res=-1; - goto error; - } - if (!tables->db) - tables->db=thd->db; - if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) - { - send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); - res=1; goto error; - } - uint howmuch=0; TABLE_LIST *walk, *auxi; - for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next, howmuch++) - { - if (!auxi->db) - auxi->db=thd->db; - if (!auxi->real_name) - auxi->real_name=auxi->name; - for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next) - { - if (!walk->db) walk->db=thd->db; - if (!strcmp(auxi->real_name,walk->real_name) && !strcmp(walk->db,auxi->db)) - break; - } - if (!walk) - { - net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); - res=-2; goto error; - } - else - { - auxi->lock_type=walk->lock_type=TL_WRITE; - auxi->table= (TABLE *) walk; - } - } - tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); - if (add_item_to_list(new Item_null())) goto error; - thd->proc_info="init"; - if (open_and_lock_tables(thd,tables)) - { - res=-1; goto error; - } - for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) - auxi->table= ((TABLE_LIST*) auxi->table)->table; - if ((result=new multi_delete(aux_tables,lex->lock_option,howmuch))) - { - res=mysql_select(thd,tables,select_lex->item_list, - select_lex->where,select_lex->ftfunc_list, - (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, - (ORDER *)NULL, - select_lex->options | thd->options, - result); - delete result; - } - else - res= -1; - close_thread_tables(thd); - break; - } + /* sql_yacc guarantees that tables and aux_tables are not zero */ + if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) || + check_table_access(thd,SELECT_ACL, tables) || + check_table_access(thd,DELETE_ACL, aux_tables)) + goto error; + if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) + { + send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); + goto error; + } + for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) + { + table_count++; + /* All tables in aux_tables must be found in FROM PART */ + TABLE_LIST *walk; + for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next) + { + if (!strcmp(auxi->real_name,walk->real_name) && + !strcmp(walk->db,auxi->db)) + break; + } + if (!walk) + { + net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); + goto error; + } + auxi->lock_type=walk->lock_type=TL_WRITE; + auxi->table= (TABLE *) walk; // Remember corresponding table + } + tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); + if (add_item_to_list(new Item_null())) + { + res= -1; + break; + } + thd->proc_info="init"; + if ((res=open_and_lock_tables(thd,tables))) + break; + /* Fix tables-to-be-deleted-from list to point at opened tables */ + for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) + auxi->table= ((TABLE_LIST*) auxi->table)->table; + if ((result=new multi_delete(thd,aux_tables,lex->lock_option, + table_count)) && ! thd->fatal_error) + { + res=mysql_select(thd,tables,select_lex->item_list, + select_lex->where,select_lex->ftfunc_list, + (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, + (ORDER *)NULL, + select_lex->options | thd->options | + SELECT_NO_JOIN_CACHE, + result); + } + else + res= -1; // Error is not sent + delete result; + close_thread_tables(thd); + break; + } case SQLCOM_UNION_SELECT: { - uint total_selects = select_lex->select_number; total_selects++; SQL_LIST *total=(SQL_LIST *) thd->calloc(sizeof(SQL_LIST)); if (select_lex->options & SELECT_DESCRIBE) lex->exchange=0; - res = link_in_large_list_and_check_acl(thd,lex,total); - if (res == -1) + if ((res = link_in_large_list_and_check_acl(thd,lex,total)) == -1) { res=0; 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; break; } 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; } break; @@ -1768,7 +1769,7 @@ mysql_execute_command(void) break; case SQLCOM_SHOW_DATABASES: #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; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f1ae2f90860..b7e9db46507 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -484,8 +484,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, (group && order) || test(select_options & OPTION_BUFFER_RESULT))); - make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) | - (ftfuncs.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH + // 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 columns of the tables: this is because MySQL @@ -2465,7 +2468,7 @@ make_join_readinfo(JOIN *join,uint options) ** if previous table use cache */ 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) { if ((options & SELECT_DESCRIBE) || diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a7ef6c30c4c..3988a823e83 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -59,9 +59,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) VOID(pthread_mutex_lock(&LOCK_open)); 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), tables->real_name); diff --git a/sql/sql_unions.cc b/sql/sql_unions.cc index 06612265f81..55aca0f5b68 100644 --- a/sql/sql_unions.cc +++ b/sql/sql_unions.cc @@ -30,4 +30,5 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) for (sl=&lex->select_lex;sl;sl=sl->next) { } + return 0; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 60292d5a515..5483945ce36 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -543,7 +543,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_mi_check_type opt_to mi_check_types normal_join table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_rkey_mode handler_read_or_scan - single_multi table_multi_delete table_sini_wild union union_list + single_multi table_wild_list table_wild_one opt_wild union union_list + precision END_OF_INPUT %type <NONE> @@ -650,7 +651,6 @@ master_def: } - /* create a table */ create: @@ -674,36 +674,41 @@ create: | CREATE opt_unique_or_fulltext INDEX ident ON table_ident { - Lex->sql_command= SQLCOM_CREATE_INDEX; + LEX *lex=Lex; + lex->sql_command= SQLCOM_CREATE_INDEX; if (!add_table_to_list($6,NULL,1)) YYABORT; - Lex->create_list.empty(); - Lex->key_list.empty(); - Lex->col_list.empty(); - Lex->change=NullS; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->change=NullS; } '(' key_list ')' { - Lex->key_list.push_back(new Key($2,$4.str,Lex->col_list)); - Lex->col_list.empty(); + LEX *lex=Lex; + lex->key_list.push_back(new Key($2,$4.str,lex->col_list)); + lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident { - Lex->sql_command=SQLCOM_CREATE_DB; - Lex->name=$4.str; - Lex->create_info.options=$3; + LEX *lex=Lex; + lex->sql_command=SQLCOM_CREATE_DB; + lex->name=$4.str; + lex->create_info.options=$3; } | CREATE udf_func_type UDF_SYM ident { - Lex->sql_command = SQLCOM_CREATE_FUNCTION; - Lex->udf.name=$4.str; - Lex->udf.name_length=$4.length; - Lex->udf.type= $2; + LEX *lex=Lex; + lex->sql_command = SQLCOM_CREATE_FUNCTION; + lex->udf.name=$4.str; + lex->udf.name_length=$4.length; + lex->udf.type= $2; } UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING { - Lex->udf.returns=(Item_result) $7; - Lex->udf.dl=$9.str; + LEX *lex=Lex; + lex->udf.returns=(Item_result) $7; + lex->udf.dl=$9.str; } create2: @@ -714,8 +719,9 @@ create3: /* empty */ {} | opt_duplicate opt_as SELECT_SYM { - Lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; - mysql_init_select(Lex); + LEX *lex=Lex; + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + mysql_init_select(lex); } select_options select_item_list opt_select_from {} @@ -823,8 +829,9 @@ field_list_item: } | key_type opt_ident '(' key_list ')' { - Lex->key_list.push_back(new Key($1,$2,Lex->col_list)); - Lex->col_list.empty(); /* Alloced by sql_alloc */ + LEX *lex=Lex; + lex->key_list.push_back(new Key($1,$2,lex->col_list)); + lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { @@ -842,16 +849,18 @@ opt_constraint: field_spec: field_ident { - Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0; - Lex->default_value=0; + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->default_value=0; } type opt_attribute { + LEX *lex=Lex; if (add_field_to_list($1.str, (enum enum_field_types) $3, - Lex->length,Lex->dec,Lex->type, - Lex->default_value,Lex->change, - Lex->interval)) + lex->length,lex->dec,lex->type, + lex->default_value,lex->change, + lex->interval)) YYABORT; } @@ -903,12 +912,14 @@ type: { $$=FIELD_TYPE_DECIMAL;} | ENUM {Lex->interval_list.empty();} '(' string_list ')' { - Lex->interval=typelib(Lex->interval_list); + LEX *lex=Lex; + lex->interval=typelib(lex->interval_list); $$=FIELD_TYPE_ENUM; } | SET { Lex->interval_list.empty();} '(' string_list ')' { - Lex->interval=typelib(Lex->interval_list); + LEX *lex=Lex; + lex->interval=typelib(lex->interval_list); $$=FIELD_TYPE_SET; } @@ -940,7 +951,14 @@ real_type: float_options: /* empty */ {} | '(' NUM ')' { Lex->length=$2.str; } - | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; } + | precision {} + +precision: + '(' NUM ',' NUM ')' + { + LEX *lex=Lex; + lex->length=$2.str; lex->dec=$4.str; + } field_options: /* empty */ {} @@ -960,7 +978,7 @@ opt_len: opt_precision: /* empty */ {} - | '(' NUM ',' NUM ')' { Lex->length=$2.str; Lex->dec=$4.str; } + | precision {} opt_attribute: /* empty */ {} @@ -1088,42 +1106,69 @@ add_column: alter_list_item: add_column field_list_item opt_place { Lex->simple_alter=0; } | add_column '(' field_list ')' { Lex->simple_alter=0; } - | CHANGE opt_column field_ident { Lex->change= $3.str; Lex->simple_alter=0; } + | CHANGE opt_column field_ident + { + LEX *lex=Lex; + lex->change= $3.str; lex->simple_alter=0; + } field_spec | MODIFY_SYM opt_column field_ident { - Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0; - Lex->default_value=0; - Lex->simple_alter=0; + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->default_value=0; + lex->simple_alter=0; } type opt_attribute { + LEX *lex=Lex; if (add_field_to_list($3.str, (enum enum_field_types) $5, - Lex->length,Lex->dec,Lex->type, - Lex->default_value, $3.str, - Lex->interval)) + lex->length,lex->dec,lex->type, + lex->default_value, $3.str, + lex->interval)) YYABORT; - Lex->simple_alter=0; + lex->simple_alter=0; } | DROP opt_column field_ident opt_restrict - { Lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, - $3.str)); Lex->simple_alter=0; } - | DROP PRIMARY_SYM KEY_SYM { Lex->drop_primary=1; Lex->simple_alter=0; } + { + LEX *lex=Lex; + lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, + $3.str)); lex->simple_alter=0; + } + | DROP PRIMARY_SYM KEY_SYM + { + LEX *lex=Lex; + lex->drop_primary=1; lex->simple_alter=0; + } | DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; } | DROP key_or_index field_ident - { Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, - $3.str)); Lex->simple_alter=0; } + { + LEX *lex=Lex; + lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, + $3.str)); + lex->simple_alter=0; + } | DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; } | ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; } | ALTER opt_column field_ident SET DEFAULT literal - { Lex->alter_list.push_back(new Alter_column($3.str,$6)); Lex->simple_alter=0; } + { + LEX *lex=Lex; + lex->alter_list.push_back(new Alter_column($3.str,$6)); + lex->simple_alter=0; + } | ALTER opt_column field_ident DROP DEFAULT - { Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); Lex->simple_alter=0; } + { + LEX *lex=Lex; + lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); + lex->simple_alter=0; + } | RENAME opt_to table_alias table_ident { LEX *lex=Lex; - lex->select->db=$4->db.str ; lex->name= $4->table.str; lex->simple_alter=0; + lex->select->db=$4->db.str; + lex->name= $4->table.str; + lex->simple_alter=0; } | create_table_options { Lex->simple_alter=0; } | order_clause { Lex->simple_alter=0; } @@ -1154,14 +1199,16 @@ opt_to: slave: SLAVE START_SYM { - Lex->sql_command = SQLCOM_SLAVE_START; - Lex->type = 0; + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_START; + lex->type = 0; } | SLAVE STOP_SYM { - Lex->sql_command = SQLCOM_SLAVE_STOP; - Lex->type = 0; + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_STOP; + lex->type = 0; }; restore: @@ -1187,8 +1234,9 @@ backup: repair: REPAIR table_or_tables { - Lex->sql_command = SQLCOM_REPAIR; - Lex->check_opt.init(); + LEX *lex=Lex; + lex->sql_command = SQLCOM_REPAIR; + lex->check_opt.init(); } table_list opt_mi_check_type @@ -1212,24 +1260,27 @@ mi_check_type: analyze: ANALYZE_SYM table_or_tables { - Lex->sql_command = SQLCOM_ANALYZE; - Lex->check_opt.init(); + LEX *lex=Lex; + lex->sql_command = SQLCOM_ANALYZE; + lex->check_opt.init(); } table_list opt_mi_check_type check: CHECK_SYM table_or_tables { - Lex->sql_command = SQLCOM_CHECK; - Lex->check_opt.init(); + LEX *lex=Lex; + lex->sql_command = SQLCOM_CHECK; + lex->check_opt.init(); } table_list opt_mi_check_type optimize: OPTIMIZE table_or_tables { - Lex->sql_command = SQLCOM_OPTIMIZE; - Lex->check_opt.init(); + LEX *lex=Lex; + lex->sql_command = SQLCOM_OPTIMIZE; + lex->check_opt.init(); } table_list opt_mi_check_type @@ -1753,13 +1804,15 @@ when_list: when_list2: expr THEN_SYM expr { - Select->when_list.head()->push_back($1); - Select->when_list.head()->push_back($3); + SELECT_LEX *sel=Select; + sel->when_list.head()->push_back($1); + sel->when_list.head()->push_back($3); } | when_list2 WHEN_SYM expr THEN_SYM expr { - Select->when_list.head()->push_back($3); - Select->when_list.head()->push_back($5); + SELECT_LEX *sel=Select; + sel->when_list.head()->push_back($3); + sel->when_list.head()->push_back($5); } opt_pad: @@ -1774,15 +1827,21 @@ join_table_list: | join_table_list INNER_SYM JOIN_SYM join_table ON expr { add_join_on($4,$6); $$=$4; } | join_table_list INNER_SYM JOIN_SYM join_table - { Select->db1=$1->db; Select->table1=$1->name; - Select->db2=$4->db; Select->table2=$4->name; } + { + SELECT_LEX *sel=Select; + sel->db1=$1->db; sel->table1=$1->name; + sel->db2=$4->db; sel->table2=$4->name; + } USING '(' using_list ')' { add_join_on($4,$8); $$=$4; } | join_table_list LEFT opt_outer JOIN_SYM join_table ON expr { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } | join_table_list LEFT opt_outer JOIN_SYM join_table - { Select->db1=$1->db; Select->table1=$1->name; - Select->db2=$5->db; Select->table2=$5->name; } + { + SELECT_LEX *sel=Select; + sel->db1=$1->db; sel->table1=$1->name; + sel->db2=$5->db; sel->table2=$5->name; + } USING '(' using_list ')' { add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table @@ -1790,8 +1849,11 @@ join_table_list: | join_table_list RIGHT opt_outer JOIN_SYM join_table ON expr { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list RIGHT opt_outer JOIN_SYM join_table - { Select->db1=$1->db; Select->table1=$1->name; - Select->db2=$5->db; Select->table2=$5->name; } + { + SELECT_LEX *sel=Select; + sel->db1=$1->db; sel->table1=$1->name; + sel->db2=$5->db; sel->table2=$5->name; + } USING '(' using_list ')' { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table @@ -1805,10 +1867,16 @@ normal_join: | CROSS JOIN_SYM {} join_table: - { Select->use_index_ptr=Select->ignore_index_ptr=0; } + { + SELECT_LEX *sel=Select; + sel->use_index_ptr=sel->ignore_index_ptr=0; + } table_ident opt_table_alias opt_key_definition - { if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, Select->use_index_ptr, - Select->ignore_index_ptr))) YYABORT; } + { + SELECT_LEX *sel=Select; + if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, sel->use_index_ptr, + sel->ignore_index_ptr))) YYABORT; + } | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; } @@ -1819,9 +1887,17 @@ opt_outer: opt_key_definition: /* empty */ {} | USE_SYM key_usage_list - { Select->use_index= *$2; Select->use_index_ptr= &Select->use_index; } + { + SELECT_LEX *sel=Select; + sel->use_index= *$2; + sel->use_index_ptr= &sel->use_index; + } | IGNORE_SYM key_usage_list - { Select->ignore_index= *$2; Select->ignore_index_ptr= &Select->ignore_index;} + { + SELECT_LEX *sel=Select; + sel->ignore_index= *$2; + sel->ignore_index_ptr= &sel->ignore_index; + } key_usage_list: key_or_index { Select->interval_list.empty() } '(' key_usage_list2 ')' @@ -1837,12 +1913,15 @@ key_usage_list2: using_list: ident - { if (!($$= new Item_func_eq(new Item_field(Select->db1,Select->table1, $1.str), new Item_field(Select->db2,Select->table2,$1.str)))) + { + SELECT_LEX *sel=Select; + if (!($$= new Item_func_eq(new Item_field(sel->db1,sel->table1, $1.str), new Item_field(sel->db2,sel->table2,$1.str)))) YYABORT; } | using_list ',' ident { - if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(Select->db1,Select->table1,$3.str), new Item_field(Select->db2,Select->table2,$3.str)), $1))) + SELECT_LEX *sel=Select; + if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1))) YYABORT; } @@ -1879,7 +1958,10 @@ where_clause: having_clause: /* empty */ | HAVING { Select->create_refs=1; } expr - { Select->having= $3; Select->create_refs=0; } + { + SELECT_LEX *sel=Select; + sel->having= $3; sel->create_refs=0; + } opt_escape: ESCAPE_SYM TEXT_STRING { $$= $2.str; } @@ -1926,14 +2008,21 @@ order_dir: limit_clause: /* empty */ { - Select->select_limit= (Lex->sql_command == SQLCOM_HA_READ) ? + SELECT_LEX *sel=Select; + sel->select_limit= (Lex->sql_command == SQLCOM_HA_READ) ? 1 : current_thd->default_select_limit; - Select->offset_limit= 0L; + sel->offset_limit= 0L; } | LIMIT ULONG_NUM - { Select->select_limit= $2; Select->offset_limit=0L; } + { + SELECT_LEX *sel=Select; + sel->select_limit= $2; sel->offset_limit=0L; + } | LIMIT ULONG_NUM ',' ULONG_NUM - { Select->select_limit= $4; Select->offset_limit=$2; } + { + SELECT_LEX *sel=Select; + sel->select_limit= $4; sel->offset_limit=$2; + } delete_limit_clause: /* empty */ @@ -1944,14 +2033,14 @@ delete_limit_clause: { Select->select_limit= (ha_rows) $2; } ULONG_NUM: - NUM { $$= strtoul($1.str,NULL,10); } - | REAL_NUM { $$= strtoul($1.str,NULL,10); } + NUM { $$= strtoul($1.str,NULL,10); } + | REAL_NUM { $$= strtoul($1.str,NULL,10); } | FLOAT_NUM { $$= strtoul($1.str,NULL,10); } ULONGLONG_NUM: - NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } - | LONG_NUM { $$= strtoull($1.str,NULL,10); } - | REAL_NUM { $$= strtoull($1.str,NULL,10); } + NUM { $$= (ulonglong) strtoul($1.str,NULL,10); } + | LONG_NUM { $$= strtoull($1.str,NULL,10); } + | REAL_NUM { $$= strtoull($1.str,NULL,10); } | FLOAT_NUM { $$= strtoull($1.str,NULL,10); } procedure_clause: @@ -2006,28 +2095,32 @@ opt_into: drop: DROP TABLE_SYM if_exists table_list opt_restrict { - Lex->sql_command = SQLCOM_DROP_TABLE; - Lex->drop_if_exists = $3; + LEX *lex=Lex; + lex->sql_command = SQLCOM_DROP_TABLE; + lex->drop_if_exists = $3; } | DROP INDEX ident ON table_ident {} { - Lex->sql_command= SQLCOM_DROP_INDEX; - Lex->drop_list.empty(); - Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, + LEX *lex=Lex; + lex->sql_command= SQLCOM_DROP_INDEX; + lex->drop_list.empty(); + lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, $3.str)); if (!add_table_to_list($5,NULL, 1)) YYABORT; } | DROP DATABASE if_exists ident { - Lex->sql_command= SQLCOM_DROP_DB; - Lex->drop_if_exists=$3; - Lex->name=$4.str; + LEX *lex=Lex; + lex->sql_command= SQLCOM_DROP_DB; + lex->drop_if_exists=$3; + lex->name=$4.str; } | DROP UDF_SYM ident { - Lex->sql_command = SQLCOM_DROP_FUNCTION; - Lex->udf.name=$3.str; + LEX *lex=Lex; + lex->sql_command = SQLCOM_DROP_FUNCTION; + lex->udf.name=$3.str; } @@ -2070,17 +2163,19 @@ insert2: insert_table: table_name { - Lex->field_list.empty(); - Lex->many_values.empty(); - Lex->insert_list=0; + LEX *lex=Lex; + lex->field_list.empty(); + lex->many_values.empty(); + lex->insert_list=0; } insert_field_spec: opt_field_spec insert_values {} | SET { - if (!(Lex->insert_list = new List_item) || - Lex->many_values.push_back(Lex->insert_list)) + LEX *lex=Lex; + if (!(lex->insert_list = new List_item) || + lex->many_values.push_back(lex->insert_list)) YYABORT; } ident_eq_list @@ -2118,8 +2213,9 @@ ident_eq_list: ident_eq_value: simple_ident equal expr { - if (Lex->field_list.push_back($1) || - Lex->insert_list->push_back($3)) + LEX *lex=Lex; + if (lex->field_list.push_back($1) || + lex->insert_list->push_back($3)) YYABORT; } @@ -2134,7 +2230,8 @@ no_braces: } opt_values ')' { - if (Lex->many_values.push_back(Lex->insert_list)) + LEX *lex=Lex; + if (lex->many_values.push_back(lex->insert_list)) YYABORT; } @@ -2163,10 +2260,11 @@ update: opt_order_clause delete_limit_clause { - Lex->sql_command = SQLCOM_UPDATE; - Select->order_list.elements=0; - Select->order_list.first=0; - Select->order_list.next= (byte**) &Select->order_list.first; + LEX *lex=Lex; + lex->sql_command = SQLCOM_UPDATE; + lex->select->order_list.elements=0; + lex->select->order_list.first=0; + lex->select->order_list.next= (byte**) &lex->select->order_list.first; } update_list: @@ -2190,49 +2288,60 @@ opt_low_priority: delete: DELETE_SYM { - Lex->sql_command= SQLCOM_DELETE; Select->options=0; - Lex->lock_option= current_thd->update_lock_default; - Select->order_list.elements=0; - Select->order_list.first=0; - Select->order_list.next= (byte**) &Select->order_list.first; - } - opt_delete_options single_multi {} + LEX *lex=Lex; + lex->sql_command= SQLCOM_DELETE; lex->select->options=0; + lex->lock_option= lex->thd->update_lock_default; + lex->select->order_list.elements=0; + lex->select->order_list.first=0; + lex->select->order_list.next= (byte**) &lex->select->order_list.first; + } + opt_delete_options single_multi {} single_multi: - FROM table_name where_clause opt_order_clause delete_limit_clause {} - | table_multi_delete - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_MULTI_DELETE; - mysql_init_select(lex); - lex->select->select_limit=HA_POS_ERROR; - lex->auxilliary_table_list.elements=0; - lex->auxilliary_table_list.first=0; - lex->auxilliary_table_list.next= (byte**) &(lex->auxilliary_table_list.first); - } - FROM - { - current_thd->lex.auxilliary_table_list=current_thd->lex.select_lex.table_list; - current_thd->lex.select->table_list.elements=0; - current_thd->lex.select->table_list.first=0; - current_thd->lex.select->table_list.next= (byte**) &(current_thd->lex.select->table_list.first); - } join_table_list where_clause - -table_multi_delete: - table_sini_wild {} - | table_multi_delete ',' table_sini_wild {} - -table_sini_wild: - ident '.' '*' { if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) YYABORT; } - | ident '.' ident '.' '*' - { if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT;} - | ident { if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) YYABORT; } - | ident '.' ident - { if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT;} + FROM table_name where_clause opt_order_clause delete_limit_clause {} + | table_wild_list + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_MULTI_DELETE; + mysql_init_select(lex); + lex->select->select_limit=HA_POS_ERROR; + lex->auxilliary_table_list.elements=0; + lex->auxilliary_table_list.first=0; + lex->auxilliary_table_list.next= (byte**) &(lex->auxilliary_table_list.first); + } + FROM + { + LEX *lex=Lex; + lex->auxilliary_table_list=lex->select_lex.table_list; + lex->select->table_list.elements=0; + lex->select->table_list.first=0; + lex->select->table_list.next= (byte**) &(lex->select->table_list.first); + } join_table_list where_clause + + +table_wild_list: + table_wild_one {} + | table_wild_list ',' table_wild_one {} + +table_wild_one: + ident opt_wild + { + if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) + YYABORT; + } + | ident '.' ident opt_wild + { + if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) + YYABORT; + } + +opt_wild: + /* empty */ {} + | '.' '*' {} opt_delete_options: - /* empty */ {} + /* empty */ {} | opt_delete_option opt_delete_options {} opt_delete_option: @@ -2244,11 +2353,10 @@ truncate: { LEX* lex = Lex; lex->sql_command= SQLCOM_TRUNCATE; - Select->options=0; - Select->order_list.elements=0; - Select->order_list.first=0; - Select->order_list.next= (byte**) &Select->order_list.first; - + lex->select->options=0; + lex->select->order_list.elements=0; + lex->select->order_list.first=0; + lex->select->order_list.next= (byte**) &lex->select->order_list.first; lex->lock_option= current_thd->update_lock_default; } opt_table_sym: @@ -2263,16 +2371,24 @@ show_param: DATABASES wild { Lex->sql_command= SQLCOM_SHOW_DATABASES; } | TABLES opt_db wild - { Lex->sql_command= SQLCOM_SHOW_TABLES; Select->db= $2; Select->options=0;} + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_TABLES; + lex->select->db= $2; lex->select->options=0; + } | TABLE_SYM STATUS_SYM opt_db wild - { Lex->sql_command= SQLCOM_SHOW_TABLES; - Select->options|= SELECT_DESCRIBE; - Select->db= $3; + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_TABLES; + lex->select->options|= SELECT_DESCRIBE; + lex->select->db= $3; } | OPEN_SYM TABLES opt_db wild - { Lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; - Select->db= $3; - Select->options=0; + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; + lex->select->db= $3; + lex->select->options=0; } | opt_full COLUMNS FROM table_ident opt_db wild { @@ -2307,8 +2423,12 @@ show_param: | LOGS_SYM { Lex->sql_command= SQLCOM_SHOW_LOGS; } | GRANTS FOR_SYM user - { Lex->sql_command= SQLCOM_SHOW_GRANTS; - Lex->grant_user=$3; Lex->grant_user->password.str=NullS; } + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_GRANTS; + lex->grant_user=$3; + lex->grant_user->password.str=NullS; + } | CREATE TABLE_SYM table_ident { Lex->sql_command = SQLCOM_SHOW_CREATE; @@ -2340,9 +2460,10 @@ opt_full: describe: describe_command table_ident { - Lex->wild=0; - Lex->verbose=0; - Lex->sql_command=SQLCOM_SHOW_FIELDS; + LEX *lex=Lex; + lex->wild=0; + lex->verbose=0; + lex->sql_command=SQLCOM_SHOW_FIELDS; if (!add_table_to_list($2, NULL,0)) YYABORT; } @@ -2363,7 +2484,12 @@ opt_describe_column: /* flush things */ flush: - FLUSH_SYM {Lex->sql_command= SQLCOM_FLUSH; Lex->type=0; } flush_options + FLUSH_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_FLUSH; lex->type=0; + } + flush_options flush_options: flush_options ',' flush_option @@ -2384,8 +2510,11 @@ opt_table_list: | table_list {} reset: - RESET_SYM {Lex->sql_command= SQLCOM_RESET; Lex->type=0; } reset_options - + RESET_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_RESET; lex->type=0; + } reset_options reset_options: reset_options ',' reset_option | reset_option @@ -2395,7 +2524,12 @@ reset_option: | MASTER_SYM { Lex->type|= REFRESH_MASTER; } purge: - PURGE { Lex->sql_command = SQLCOM_PURGE; Lex->type=0;} + PURGE + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_PURGE; + lex->type=0; + } MASTER_SYM LOGS_SYM TO_SYM TEXT_STRING { Lex->to_log = $6.str; @@ -2406,29 +2540,34 @@ purge: kill: KILL_SYM expr { - if ($2->fix_fields(current_thd,0)) - { - send_error(¤t_thd->net, ER_SET_CONSTANTS_ONLY); - YYABORT; - } - Lex->sql_command=SQLCOM_KILL; - Lex->thread_id= (ulong) $2->val_int(); + LEX *lex=Lex; + if ($2->fix_fields(lex->thd,0)) + { + send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY); + YYABORT; + } + lex->sql_command=SQLCOM_KILL; + lex->thread_id= (ulong) $2->val_int(); } /* change database */ use: USE_SYM ident - { Lex->sql_command=SQLCOM_CHANGE_DB; Select->db= $2.str; } + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str; + } /* import, export of files */ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING { - Lex->sql_command= SQLCOM_LOAD; - Lex->local_file= $4; - if (!(Lex->exchange= new sql_exchange($6.str,0))) + LEX *lex=Lex; + lex->sql_command= SQLCOM_LOAD; + lex->local_file= $4; + if (!(lex->exchange= new sql_exchange($6.str,0))) YYABORT; - Lex->field_list.empty(); + lex->field_list.empty(); } opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term opt_ignore_lines opt_field_spec @@ -2476,7 +2615,11 @@ field_term_list: field_term: TERMINATED BY text_string { Lex->exchange->field_term= $3;} | OPTIONALLY ENCLOSED BY text_string - { Lex->exchange->enclosed= $4; Lex->exchange->opt_enclosed=1;} + { + LEX *lex=Lex; + lex->exchange->enclosed= $4; + lex->exchange->opt_enclosed=1; + } | ENCLOSED BY text_string { Lex->exchange->enclosed= $3;} | ESCAPED BY text_string { Lex->exchange->escaped= $3;} @@ -2546,13 +2689,25 @@ order_ident: simple_ident: ident - { $$ = !Select->create_refs || Select->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); } + { + SELECT_LEX *sel=Select; + $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); + } | ident '.' ident - { $$ = !Select->create_refs || Select->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); } + { + SELECT_LEX *sel=Select; + $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); + } | '.' ident '.' ident - { $$ = !Select->create_refs || Select->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); } + { + SELECT_LEX *sel=Select; + $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); + } | ident '.' ident '.' ident - { $$ = !Select->create_refs || Select->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); } + { + SELECT_LEX *sel=Select; + $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); + } field_ident: @@ -2569,10 +2724,11 @@ ident: IDENT { $$=$1; } | keyword { + LEX *lex; $$.str=sql_strmake($1.str,$1.length); $$.length=$1.length; - if (Lex->next_state != STATE_END) - Lex->next_state=STATE_OPERATOR_OR_IDENT; + if ((lex=Lex)->next_state != STATE_END) + lex->next_state=STATE_OPERATOR_OR_IDENT; } ident_or_text: @@ -2724,12 +2880,12 @@ keyword: set: SET opt_option { - THD *thd=current_thd; - Lex->sql_command= SQLCOM_SET_OPTION; - Select->options=thd->options; - Select->select_limit=thd->default_select_limit; - Lex->gemini_spin_retries=thd->gemini_spin_retries; - Lex->tx_isolation=thd->tx_isolation; + LEX *lex=Lex; + lex->sql_command= SQLCOM_SET_OPTION; + lex->select->options=lex->thd->options; + lex->select->select_limit=lex->thd->default_select_limit; + lex->gemini_spin_retries=lex->thd->gemini_spin_retries; + lex->tx_isolation=lex->thd->tx_isolation; } option_value_list @@ -2744,18 +2900,20 @@ option_value_list: option_value: set_option equal NUM { + SELECT_LEX *sel=Select; if (atoi($3.str) == 0) - Select->options&= ~$1; + sel->options&= ~$1; else - Select->options|= $1; + sel->options|= $1; } | set_isolation | AUTOCOMMIT equal NUM { + SELECT_LEX *sel=Select; if (atoi($3.str) != 0) /* Test NOT AUTOCOMMIT */ - Select->options&= ~(OPTION_NOT_AUTO_COMMIT); + sel->options&= ~(OPTION_NOT_AUTO_COMMIT); else - Select->options|= OPTION_NOT_AUTO_COMMIT; + sel->options|= OPTION_NOT_AUTO_COMMIT; } | SQL_SELECT_LIMIT equal ULONG_NUM { @@ -2767,8 +2925,9 @@ option_value: } | SQL_MAX_JOIN_SIZE equal ULONG_NUM { - current_thd->max_join_size= $3; - Select->options&= ~OPTION_BIG_SELECTS; + LEX *lex=Lex; + lex->thd->max_join_size= $3; + lex->select->options&= ~OPTION_BIG_SELECTS; } | SQL_MAX_JOIN_SIZE equal DEFAULT { @@ -2891,7 +3050,10 @@ set_isolation: default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation]; } | SESSION_SYM tx_isolation - { current_thd->session_tx_isolation= Lex->tx_isolation= $2; } + { + LEX *lex=Lex; + lex->thd->session_tx_isolation= lex->tx_isolation= $2; + } | tx_isolation { Lex->tx_isolation= $1; } @@ -2975,8 +3137,9 @@ handler_rkey_function: | LAST_SYM { Lex->ha_read_mode = RLAST; } | handler_rkey_mode { - Lex->ha_read_mode = RKEY; - if (!(Lex->insert_list = new List_item)) + LEX *lex=Lex; + lex->ha_read_mode = RKEY; + if (!(lex->insert_list = new List_item)) YYABORT; } '(' values ')' { } @@ -2992,22 +3155,24 @@ handler_rkey_mode: revoke: REVOKE { - Lex->sql_command = SQLCOM_REVOKE; - Lex->users_list.empty(); - Lex->columns.empty(); - Lex->grant= Lex->grant_tot_col=0; - Select->db=0; + LEX *lex=Lex; + lex->sql_command = SQLCOM_REVOKE; + lex->users_list.empty(); + lex->columns.empty(); + lex->grant= lex->grant_tot_col=0; + lex->select->db=0; } grant_privileges ON opt_table FROM user_list grant: GRANT { - Lex->sql_command = SQLCOM_GRANT; - Lex->users_list.empty(); - Lex->columns.empty(); - Lex->grant= Lex->grant_tot_col=0; - Select->db=0; + LEX *lex=Lex; + lex->sql_command = SQLCOM_GRANT; + lex->users_list.empty(); + lex->columns.empty(); + lex->grant= lex->grant_tot_col=0; + lex->select->db=0; } grant_privileges ON opt_table TO_SYM user_list grant_option @@ -3047,43 +3212,47 @@ grant_privilege: opt_table: '*' { - Select->db=current_thd->db; - if (Lex->grant == UINT_MAX) - Lex->grant = DB_ACLS & ~GRANT_ACL; - else if (Lex->columns.elements) + LEX *lex=Lex; + lex->select->db=lex->thd->db; + if (lex->grant == UINT_MAX) + lex->grant = DB_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) { - net_printf(¤t_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + net_printf(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; - } + } } | ident '.' '*' { - Select->db = $1.str; - if (Lex->grant == UINT_MAX) - Lex->grant = DB_ACLS & ~GRANT_ACL; - else if (Lex->columns.elements) + LEX *lex=Lex; + lex->select->db = $1.str; + if (lex->grant == UINT_MAX) + lex->grant = DB_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) { - net_printf(¤t_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + net_printf(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; } } | '*' '.' '*' { - Select->db = NULL; - if (Lex->grant == UINT_MAX) - Lex->grant = GLOBAL_ACLS & ~GRANT_ACL; - else if (Lex->columns.elements) + LEX *lex=Lex; + lex->select->db = NULL; + if (lex->grant == UINT_MAX) + lex->grant = GLOBAL_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) { - net_printf(¤t_thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); + net_printf(&lex->thd->net,ER_ILLEGAL_GRANT_FOR_TABLE); YYABORT; } } | table_ident { + LEX *lex=Lex; if (!add_table_to_list($1,NULL,0)) YYABORT; - if (Lex->grant == UINT_MAX) - Lex->grant = TABLE_ACLS & ~GRANT_ACL; + if (lex->grant == UINT_MAX) + lex->grant = TABLE_ACLS & ~GRANT_ACL; } @@ -3114,7 +3283,11 @@ grant_user: opt_column_list: - /* empty */ { Lex->grant |= Lex->which_columns; } + /* empty */ + { + LEX *lex=Lex; + lex->grant |= lex->which_columns; + } | '(' column_list ')' column_list: @@ -3127,16 +3300,17 @@ column_list_id: String *new_str = new String((const char*) $1.str,$1.length); List_iterator <LEX_COLUMN> iter(Lex->columns); class LEX_COLUMN *point; + LEX *lex=Lex; while ((point=iter++)) { if (!my_strcasecmp(point->column.ptr(),new_str->ptr())) break; } - Lex->grant_tot_col|= Lex->which_columns; + lex->grant_tot_col|= lex->which_columns; if (point) - point->rights |= Lex->which_columns; + point->rights |= lex->which_columns; else - Lex->columns.push_back(new LEX_COLUMN (*new_str,Lex->which_columns)); + lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); } grant_option: diff --git a/sql/structs.h b/sql/structs.h index 36f503312c0..594432134b2 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -164,3 +164,4 @@ typedef struct st_lex_user { #define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_UPDATED 16 /* Record is updated by formula */ #define STATUS_NULL_ROW 32 /* table->null_row is set */ +#define STATUS_DELETED 64 diff --git a/sql/uniques.cc b/sql/uniques.cc index c1ffeda1729..cbb67ecbbe5 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -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 */ init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16); 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) SORTPARAM sort_param; 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 */ if ((record_pointers=table->record_pointers= (byte*) @@ -110,17 +111,16 @@ bool Unique::get(TABLE *table) if (flush()) return 1; - IO_CACHE *outfile=table->io_cache, tempfile; + IO_CACHE *outfile=table->io_cache; BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer; uint maxbuffer= file_ptrs.elements - 1; uchar *sort_buffer; my_off_t save_pos; bool error=1; - my_b_clear(&tempfile); - /* 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) && open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, @@ -134,25 +134,24 @@ bool Unique::get(TABLE *table) sort_param.keys= max_in_memory_size / sort_param.sort_length; if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) * - sort_param.sort_length, - MYF(0)))) + sort_param.sort_length, + MYF(0)))) return 1; sort_param.unique_buff= sort_buffer+(sort_param.keys* sort_param.sort_length); /* 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; - if (flush_io_cache(&tempfile) || - reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) + if (flush_io_cache(&file) || + reinit_io_cache(&file,READ_CACHE,0L,0,0)) 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)) goto err; error=0; err: x_free((gptr) sort_buffer); - close_cached_file(&tempfile); if (flush_io_cache(outfile)) error=1; |