diff --git a/sql/filesort.cc b/sql/filesort.cc index d0146e5e56a..76f6bc4c33c 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -739,7 +739,6 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, buffpek=(BUFFPEK*) queue_top(&queue); if (cmp) // Remove duplicates { -// Was if (!cmp(&sort_length, param->unique_buff, (uchar**) buffpek->key)) if (!cmp(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key)) goto skip_duplicate; memcpy(param->unique_buff, (uchar*) buffpek->key,sort_length); diff --git a/sql/sql_class.h b/sql/sql_class.h index 19ac075697b..3b83558ebdb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -464,34 +464,6 @@ public: void send_error(uint errcode,const char *err); bool send_eof(); }; - - class multi_delete : public select_result { - TABLE_LIST *delete_tables, *table_being_deleted; - IO_CACHE **tempfiles; - thr_lock_type lock_option; - ulong deleted; - byte *dup_checking, wrong_record[MAX_REFLENGTH], *memory_lane; - int num_of_tables, error; - bool do_delete; - THD *thd; - public: - multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n) - : delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0) - { - memset(wrong_record,'\xFF',MAX_REFLENGTH); - thd = current_thd; do_delete = false; - } - ~multi_delete(); - int prepare(List &list); - bool send_fields(List &list, - uint flag) { return 0; } - bool send_data(List &items); - void send_error(uint errcode,const char *err); - int do_deletes (bool from_send_error); - bool send_eof(); - }; - - class select_insert :public select_result { protected: TABLE *table; @@ -619,3 +591,35 @@ public: friend int unique_write_to_file(gptr key, element_count count, Unique *unique); friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique); }; + + class multi_delete : public select_result { + TABLE_LIST *delete_tables, *table_being_deleted; +#ifdef SINISAS_STRIP + IO_CACHE **tempfiles; + byte *memory_lane; +#else + Unique **tempfiles; +#endif + byte * dup_checking; + THD *thd; + ha_rows deleted; + int num_of_tables, error; + thr_lock_type lock_option; + bool do_delete; + public: + multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n) + : delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0) + { + thd = current_thd; do_delete = false; + } + ~multi_delete(); + int prepare(List &list); + bool send_fields(List &list, + uint flag) { return 0; } + bool send_data(List &items); + void send_error(uint errcode,const char *err); + int do_deletes (bool from_send_error); + bool send_eof(); + }; + + diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 4f3fe80473e..30b0f8a82bb 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -150,7 +150,7 @@ int mysql_delete(THD *thd, (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))); #ifdef HAVE_INNOBASE_DB /* We need to add code to not generate table based on the table type */ - if (!innobase_skip) + if (!innodb_skip) use_generate_table=0; // Innobase can't use re-generate table #endif if (use_generate_table && ! thd->open_tables) @@ -294,15 +294,27 @@ int mysql_delete(THD *thd, #define MEM_STRIP_BUF_SIZE 2048 +#ifndef SINISAS_STRIP +int refposcmp2(void* arg, const void *a,const void *b) +{ + return memcmp(a,b,(int)arg); +} +#endif int multi_delete::prepare(List &values) { DBUG_ENTER("multi_delete::prepare"); + uint counter = 0; +#ifdef SINISAS_STRIP tempfiles = (IO_CACHE **) sql_calloc(sizeof(IO_CACHE *)*(num_of_tables)); - memory_lane = (byte *)sql_alloc(MAX_REFLENGTH*MEM_STRIP_BUF_SIZE); uint counter = 0; + memory_lane = (byte *)sql_alloc(MAX_REFLENGTH*MEM_STRIP_BUF_SIZE); +#else + tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables)); +#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)); do_delete = true; + 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++) { TABLE *table=table_being_deleted->table; @@ -314,12 +326,16 @@ multi_delete::prepare(List &values) (void) table->file->extra(HA_EXTRA_NO_READCHECK); if (counter < num_of_tables) { +#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_CANT_OPEN_FILE,MYF(0),(tempfiles[counter])->file_name,errno); 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"; @@ -330,7 +346,11 @@ multi_delete::~multi_delete() { for (uint counter = 0; counter < num_of_tables; counter++) if (tempfiles[counter]) - end_io_cache(tempfiles[counter]); +#ifdef SINISAS_STRIP +// end_io_cache(tempfiles[counter]); +#else + delete tempfiles[counter]; +#endif // Here it crashes ... } @@ -342,7 +362,7 @@ bool multi_delete::send_data(List &values) 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) && memcmp(table->file->ref,wrong_record,rl)) + if (!table->null_row && memcmp(dup_check,table->file->ref, rl)) { memcpy(dup_check,table->file->ref,rl); if (secure_counter == -1) @@ -357,7 +377,11 @@ bool multi_delete::send_data(List &values) } else { +#ifdef SINISAS_STRIP if (my_b_write(tempfiles[secure_counter],table->file->ref,rl)) +#else + if (tempfiles[secure_counter]->unique_add(table->file->ref)) +#endif { error=-1; return 1; @@ -687,11 +711,7 @@ static IO_CACHE *strip_duplicates_from_temp (byte *memory_lane, IO_CACHE *ptr, u return tempptr; } } -#else -int refposcmp2(void* arg, const void *a,const void *b) -{ - return memcmp(a,b,(int)arg); -} + #endif static bool some_table_is_not_transaction_safe (TABLE_LIST *tl) @@ -708,9 +728,14 @@ 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 ... ::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); else if (do_delete) @@ -732,30 +757,16 @@ int multi_delete::do_deletes (bool from_send_error) for (table_being_deleted=table_being_deleted->next; table_being_deleted ; counter++, table_being_deleted=table_being_deleted->next) { 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; -#ifdef SINISAS_STRIP tempfiles[counter] = strip_duplicates_from_temp(memory_lane, tempfiles[counter],rl,&num_of_positions); if (!num_of_positions) { error=1; break; } #else - Unique strip_it(refposcmp2,(void *)rl,rl,MEM_STRIP_BUF_SIZE); - if (reinit_io_cache(tempfiles[counter],READ_CACHE,0L,0,0)) - { - error=1; break; - } - for (count = 0; count < num_of_positions; count++) - { - byte tmp [MAX_REFLENGTH]; - if (my_b_read(tempfiles[counter], tmp, rl) || strip_it.unique_add(tmp)) - { - error = 1; - break; - } - } - strip_it.get(table); + tempfiles[counter]->get(table); #endif #if 0 if (num_of_positions == table->file->records) // nice little optimization .... @@ -773,12 +784,17 @@ int multi_delete::do_deletes (bool from_send_error) else { #endif + READ_RECORD info; error=0; +#ifdef SINISAS_STRIP SQL_SELECT *select= new SQL_SELECT; - READ_RECORD info; select->head=table; select->file=*tempfiles[counter]; - init_read_record(&info,thd,table,select,0,0); error=0; - while (!(error=info.read_record(&info)) && (!thd->killed || from_send_error)) + init_read_record(&info,thd,table,select,0,0); +#else + 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)) { error=table->file->delete_row(table->record[0]); if (error) @@ -789,8 +805,11 @@ int multi_delete::do_deletes (bool from_send_error) else deleted++; } - end_read_record(&info); delete select; - if (error = -1) error = 0; // Monty, that is what read_record returns on end of the file !! + end_read_record(&info); +#ifdef SINISAS_STRIP + delete select; +#endif + if (error = -1) error = 0; #if 0 } #endif @@ -822,11 +841,6 @@ bool multi_delete::send_eof() error=1; VOID(ha_autocommit_or_rollback(thd,error >= 0)); } - if (thd->lock) - { - mysql_unlock_tables(thd, thd->lock); - thd->lock=0; - } ::send_ok(&thd->net,deleted); return 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1dbce659d18..422735f45e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1059,7 +1059,7 @@ mysql_execute_command(void) THD *thd=current_thd; LEX *lex= &thd->lex; TABLE_LIST *tables=(TABLE_LIST*) lex->select->table_list.first; - SELECT_LEX *Select = lex->select; + SELECT_LEX *select_lex = lex->select; DBUG_ENTER("mysql_execute_command"); if(table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables)) @@ -1071,7 +1071,7 @@ mysql_execute_command(void) case SQLCOM_SELECT: { select_result *result; - if (Select->options & SELECT_DESCRIBE) + if (select_lex->options & SELECT_DESCRIBE) lex->exchange=0; if (tables) { @@ -1089,12 +1089,12 @@ mysql_execute_command(void) break; // Error message is given } - thd->offset_limit=Select->offset_limit; - thd->select_limit=Select->select_limit+Select->offset_limit; - if (thd->select_limit < Select->select_limit) + thd->offset_limit=select_lex->offset_limit; + thd->select_limit=select_lex->select_limit+select_lex->offset_limit; + if (thd->select_limit < select_lex->select_limit) thd->select_limit= HA_POS_ERROR; // no limit if (thd->select_limit == HA_POS_ERROR) - Select->options&= ~OPTION_FOUND_ROWS; + select_lex->options&= ~OPTION_FOUND_ROWS; if (lex->exchange) { @@ -1119,8 +1119,8 @@ mysql_execute_command(void) { res= -1; #ifdef DELETE_ITEMS - delete Select->having; - delete Select->where; + delete select_lex->having; + delete select_lex->where; #endif break; } @@ -1138,22 +1138,22 @@ mysql_execute_command(void) if (!(res=open_and_lock_tables(thd,tables))) { - res=mysql_select(thd,tables,Select->item_list, - Select->where, - Select->ftfunc_list, - (ORDER*) Select->order_list.first, - (ORDER*) Select->group_list.first, - Select->having, + res=mysql_select(thd,tables,select_lex->item_list, + select_lex->where, + select_lex->ftfunc_list, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, (ORDER*) lex->proc_list.first, - Select->options | thd->options, + select_lex->options | thd->options, result); if (res) result->abort(); } delete result; #ifdef DELETE_ITEMS - delete Select->having; - delete Select->where; + delete select_lex->having; + delete select_lex->where; #endif break; } @@ -1272,7 +1272,7 @@ mysql_execute_command(void) res=0; break; } - if (Select->item_list.elements) // With select + if (select_lex->item_list.elements) // With select { select_result *result; @@ -1290,9 +1290,9 @@ mysql_execute_command(void) for (table = tables->next ; table ; table=table->next) table->lock_type= lex->lock_option; } - thd->offset_limit=Select->offset_limit; - thd->select_limit=Select->select_limit+Select->offset_limit; - if (thd->select_limit < Select->select_limit) + thd->offset_limit=select_lex->offset_limit; + thd->select_limit=select_lex->select_limit+select_lex->offset_limit; + if (thd->select_limit < select_lex->select_limit) thd->select_limit= HA_POS_ERROR; // No limit if (!(res=open_and_lock_tables(thd,tables->next))) @@ -1301,16 +1301,16 @@ mysql_execute_command(void) tables->real_name, &lex->create_info, lex->create_list, lex->key_list, - Select->item_list,lex->duplicates))) + select_lex->item_list,lex->duplicates))) { - res=mysql_select(thd,tables->next,Select->item_list, - Select->where, - Select->ftfunc_list, - (ORDER*) Select->order_list.first, - (ORDER*) Select->group_list.first, - Select->having, + res=mysql_select(thd,tables->next,select_lex->item_list, + select_lex->where, + select_lex->ftfunc_list, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, (ORDER*) lex->proc_list.first, - Select->options | thd->options, + select_lex->options | thd->options, result); if (res) result->abort(); @@ -1365,10 +1365,10 @@ mysql_execute_command(void) } if (!tables->db) tables->db=thd->db; - if (!Select->db) - Select->db=tables->db; + if (!select_lex->db) + select_lex->db=tables->db; if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) || - check_access(thd,INSERT_ACL | CREATE_ACL,Select->db,&priv) || + check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) || check_merge_table_access(thd, tables->db, (TABLE_LIST *) lex->create_info.merge_list.first)) @@ -1384,7 +1384,7 @@ mysql_execute_command(void) TABLE_LIST tmp_table; bzero((char*) &tmp_table,sizeof(tmp_table)); tmp_table.real_name=lex->name; - tmp_table.db=Select->db; + tmp_table.db=select_lex->db; tmp_table.grant.privilege=priv; if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables)) goto error; @@ -1394,11 +1394,11 @@ mysql_execute_command(void) if (end_active_trans(thd)) res= -1; else - res= mysql_alter_table(thd, Select->db, lex->name, + res= mysql_alter_table(thd, select_lex->db, lex->name, &lex->create_info, tables, lex->create_list, lex->key_list, lex->drop_list, lex->alter_list, - (ORDER *) Select->order_list.first, + (ORDER *) select_lex->order_list.first, lex->drop_primary, lex->duplicates, lex->alter_keys_onoff, lex->simple_alter); break; @@ -1518,22 +1518,22 @@ mysql_execute_command(void) goto error; if (grant_option && check_grant(thd,UPDATE_ACL,tables)) goto error; - if (Select->item_list.elements != lex->value_list.elements) + if (select_lex->item_list.elements != lex->value_list.elements) { send_error(&thd->net,ER_WRONG_VALUE_COUNT); DBUG_VOID_RETURN; } res = mysql_update(thd,tables, - Select->item_list, + select_lex->item_list, lex->value_list, - Select->where, - (ORDER *) Select->order_list.first, - Select->select_limit, + select_lex->where, + (ORDER *) select_lex->order_list.first, + select_lex->select_limit, lex->duplicates, lex->lock_option); #ifdef DELETE_ITEMS - delete Select->where; + delete select_lex->where; #endif break; case SQLCOM_INSERT: @@ -1577,9 +1577,9 @@ mysql_execute_command(void) } select_result *result; - thd->offset_limit=Select->offset_limit; - thd->select_limit=Select->select_limit+Select->offset_limit; - if (thd->select_limit < Select->select_limit) + thd->offset_limit=select_lex->offset_limit; + thd->select_limit=select_lex->select_limit+select_lex->offset_limit; + if (thd->select_limit < select_lex->select_limit) thd->select_limit= HA_POS_ERROR; // No limit if (check_dup(thd,tables->db,tables->real_name,tables->next)) @@ -1599,14 +1599,14 @@ mysql_execute_command(void) lex->sql_command == SQLCOM_REPLACE_SELECT ? DUP_REPLACE : DUP_IGNORE))) { - res=mysql_select(thd,tables->next,Select->item_list, - Select->where, - Select->ftfunc_list, - (ORDER*) Select->order_list.first, - (ORDER*) Select->group_list.first, - Select->having, + res=mysql_select(thd,tables->next,select_lex->item_list, + select_lex->where, + select_lex->ftfunc_list, + (ORDER*) select_lex->order_list.first, + (ORDER*) select_lex->group_list.first, + select_lex->having, (ORDER*) lex->proc_list.first, - Select->options | thd->options, + select_lex->options | thd->options, result); delete result; } @@ -1614,14 +1614,14 @@ mysql_execute_command(void) res= -1; } #ifdef DELETE_ITEMS - delete Select->having; - delete Select->where; + delete select_lex->having; + delete select_lex->where; #endif break; } case SQLCOM_TRUNCATE: - Select->where=0; - Select->select_limit=HA_POS_ERROR; + select_lex->where=0; + select_lex->select_limit=HA_POS_ERROR; /* Fall through */ case SQLCOM_DELETE: { @@ -1635,8 +1635,8 @@ mysql_execute_command(void) if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd)) res= -1; else - res = mysql_delete(thd,tables, Select->where, (ORDER*)Select->order_list.first, - Select->select_limit, lex->lock_option, Select->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: @@ -1645,17 +1645,15 @@ mysql_execute_command(void) multi_delete *result; if (!tables || !aux_tables || - check_table_access(thd,SELECT_ACL, 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; } if (!tables->db) tables->db=thd->db; - if (!aux_tables->db) - aux_tables->db=thd->db; - if ((thd->options & OPTION_SAFE_UPDATES) && !Select->where) + if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) { send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); res=1; goto error; @@ -1664,66 +1662,42 @@ mysql_execute_command(void) for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next, howmuch++) { if (!auxi->db) - auxi->db=thd->db; + auxi->db=thd->db; if (!auxi->real_name) - auxi->real_name=auxi->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->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; + net_printf(&thd->net,ER_NONUNIQ_TABLE,auxi->real_name); + res=-2; goto error; } else - auxi->lock_type=walk->lock_type=TL_WRITE; - TABLE form; char path[FN_REFLEN]; - (void)sprintf(path,"%s/%s/%s",mysql_data_home,auxi->db,auxi->name); - if (openfrm(path,auxi->name,(uint)HA_TRY_READ_ONLY,COMPUTE_TYPES,0,&form)) { - res=-1; goto error; + auxi->lock_type=walk->lock_type=TL_WRITE; + auxi->table= (TABLE *) walk; } - char *field_name=sql_strdup(form.fieldnames.type_names[0]); VOID(closefrm(&form)); - if (add_item_to_list(new Item_field(auxi->db,auxi->name,field_name))) - { - net_printf(&thd->net,ER_WRONG_TABLE_NAME,auxi->name); - res=-1; goto error; - } - } - if (!howmuch--) - { - my_error(ER_NO_TABLES_USED, MYF(0)); - res=-2; goto error; } 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; } - /* This double loop definitely looks like it could have been merged up. But not !! - * Problmes are that we have to first set lock for tables to be deleted to write - * and then to get auxi->table from tables, like below ..... - */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) - { - for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next) - { - if (!strcmp(auxi->real_name,walk->real_name) && !strcmp(walk->db,auxi->db)) - break; - } - auxi->table = walk->table; - } + auxi->table= ((TABLE_LIST*) auxi->table)->table; if ((result=new multi_delete(aux_tables,lex->lock_option,howmuch))) { - res=mysql_select(thd,tables,Select->item_list, - Select->where,Select->ftfunc_list, + 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->options | thd->options, + select_lex->options | thd->options, result); delete result; } @@ -1797,7 +1771,7 @@ mysql_execute_command(void) DBUG_VOID_RETURN; #else { - char *db=Select->db ? Select->db : thd->db; + char *db=select_lex->db ? select_lex->db : thd->db; if (!db) { send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */ @@ -1812,7 +1786,7 @@ mysql_execute_command(void) if (check_access(thd,SELECT_ACL,db,&thd->col_access)) goto error; /* purecov: inspected */ /* grant is checked in mysqld_show_tables */ - if (Select->options & SELECT_DESCRIBE) + if (select_lex->options & SELECT_DESCRIBE) res= mysqld_extend_show_tables(thd,db, (lex->wild ? lex->wild->ptr() : NullS)); else @@ -1877,7 +1851,7 @@ mysql_execute_command(void) } #endif case SQLCOM_CHANGE_DB: - mysql_change_db(thd,Select->db); + mysql_change_db(thd,select_lex->db); break; case SQLCOM_LOAD: { @@ -1901,10 +1875,10 @@ mysql_execute_command(void) case SQLCOM_SET_OPTION: { uint org_options=thd->options; - thd->options=Select->options; + thd->options=select_lex->options; thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ? TL_WRITE_LOW_PRIORITY : TL_WRITE); - thd->default_select_limit=Select->select_limit; + thd->default_select_limit=select_lex->select_limit; thd->tx_isolation=lex->tx_isolation; if (thd->gemini_spin_retries != lex->gemini_spin_retries) { @@ -1915,7 +1889,7 @@ mysql_execute_command(void) thd->options,(long) thd->default_select_limit)); /* Check if auto_commit mode changed */ - if ((org_options ^ Select->options) & OPTION_NOT_AUTO_COMMIT) + if ((org_options ^ select_lex->options) & OPTION_NOT_AUTO_COMMIT) { if ((org_options & OPTION_NOT_AUTO_COMMIT)) { @@ -2025,7 +1999,7 @@ mysql_execute_command(void) if (tables && !tables->db) tables->db=thd->db; if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, - tables && tables->db ? tables->db : Select->db, + tables && tables->db ? tables->db : select_lex->db, tables ? &tables->grant.privilege : 0, tables ? 0 : 1)) goto error; @@ -2077,7 +2051,7 @@ mysql_execute_command(void) res=1; } else - res = mysql_grant(thd, Select->db, lex->users_list, lex->grant, + res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, lex->sql_command == SQLCOM_REVOKE); if(!res) { @@ -2125,8 +2099,8 @@ mysql_execute_command(void) if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL, tables)) goto error; res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir, - lex->insert_list, lex->ha_rkey_mode, Select->where, - Select->select_limit, Select->offset_limit); + lex->insert_list, lex->ha_rkey_mode, select_lex->where, + select_lex->select_limit, select_lex->offset_limit); break; case SQLCOM_BEGIN: @@ -2403,19 +2377,19 @@ mysql_init_query(THD *thd) void mysql_init_select(LEX *lex) { - SELECT_LEX *Select = lex->select; - Select->where=Select->having=0; - Select->select_limit=current_thd->default_select_limit; - Select->offset_limit=0L; - Select->options=0; Select->linkage=UNSPECIFIED_TYPE; - Select->select_number = 0; lex->exchange = 0; + SELECT_LEX *select_lex = lex->select; + select_lex->where=select_lex->having=0; + select_lex->select_limit=current_thd->default_select_limit; + select_lex->offset_limit=0L; + select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE; + select_lex->select_number = 0; lex->exchange = 0; lex->proc_list.first=0; - Select->order_list.elements=Select->group_list.elements=0; - Select->order_list.first=0; - Select->order_list.next= (byte**) &Select->order_list.first; - Select->group_list.first=0; - Select->group_list.next= (byte**) &Select->group_list.first; - Select->next = (SELECT_LEX *)NULL; + select_lex->order_list.elements=select_lex->group_list.elements=0; + select_lex->order_list.first=0; + select_lex->order_list.next= (byte**) &select_lex->order_list.first; + select_lex->group_list.first=0; + select_lex->group_list.next= (byte**) &select_lex->group_list.first; + select_lex->next = (SELECT_LEX *)NULL; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bdfa75ab9d7..226d94b06ac 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -542,7 +542,7 @@ 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_sin_wild + single_multi table_multi_delete table_sini_wild END_OF_INPUT %type @@ -764,12 +764,12 @@ create_table_option: { /* Move the union list to the merge_list */ LEX *lex=Lex; - TABLE_LIST *table_list= (TABLE_LIST*) Select->table_list.first; - lex->create_info.merge_list= Select->table_list; + TABLE_LIST *table_list= (TABLE_LIST*) lex->select->table_list.first; + lex->create_info.merge_list= lex->select->table_list; lex->create_info.merge_list.elements--; lex->create_info.merge_list.first= (byte*) (table_list->next); - Select->table_list.elements=1; - Select->table_list.next= (byte**) &(table_list->next); + lex->select->table_list.elements=1; + lex->select->table_list.next= (byte**) &(table_list->next); table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } @@ -1064,10 +1064,10 @@ alter: lex->col_list.empty(); lex->drop_list.empty(); lex->alter_list.empty(); - Select->order_list.elements=0; - Select->order_list.first=0; - Select->order_list.next= (byte**) &Select->order_list.first; - Select->db=lex->name=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->select->db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; lex->alter_keys_onoff=LEAVE_AS_IS; @@ -1118,7 +1118,10 @@ alter_list_item: | ALTER opt_column field_ident DROP DEFAULT { Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); Lex->simple_alter=0; } | RENAME opt_to table_alias table_ident - { Select->db=$4->db.str ; Lex->name= $4->table.str; Lex->simple_alter=0; } + { + LEX *lex=Lex; + 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; } @@ -2197,9 +2200,9 @@ single_multi: | table_multi_delete { LEX *lex=Lex; - Lex->sql_command = SQLCOM_MULTI_DELETE; + lex->sql_command = SQLCOM_MULTI_DELETE; mysql_init_select(lex); - Select->select_limit=HA_POS_ERROR; + 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); @@ -2213,13 +2216,17 @@ single_multi: } join_table_list where_clause table_multi_delete: - table_sin_wild {} - | table_multi_delete ',' table_sin_wild {} + table_sini_wild {} + | table_multi_delete ',' table_sini_wild {} -table_sin_wild: - ident '.' '*' { if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) YYABORT; } +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;} + opt_delete_options: /* empty */ {} diff --git a/sql/uniques.cc b/sql/uniques.cc index 36a395dfa5d..c1ffeda1729 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -39,12 +39,12 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, uint size, ulong max_in_memory_size_arg) :max_in_memory_size(max_in_memory_size_arg),elements(0) { - my_b_clear(&file); init_tree(&tree, max_in_memory_size / 16, size, comp_func, 0, 0); tree.cmp_arg=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)); } @@ -74,8 +74,6 @@ bool Unique::flush() int unique_write_to_file(gptr key, element_count count, Unique *unique) { - if (!my_b_inited(&unique->file) && open_cached_file(&unique->file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME))) - return 1; return my_b_write(&unique->file, key, unique->tree.size_of_element) ? 1 : 0; } @@ -114,7 +112,7 @@ bool Unique::get(TABLE *table) IO_CACHE *outfile=table->io_cache, tempfile; BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer; - uint maxbuffer= file_ptrs.elements - 1; // I added -1 ..... + uint maxbuffer= file_ptrs.elements - 1; uchar *sort_buffer; my_off_t save_pos; bool error=1; @@ -122,16 +120,15 @@ bool Unique::get(TABLE *table) my_b_clear(&tempfile); /* Open cached file if it isn't open */ - if (!outfile) outfile= (IO_CACHE *) sql_calloc(sizeof(IO_CACHE)); - if (! my_b_inited(outfile) && + 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, MYF(MY_WME))) return 1; reinit_io_cache(outfile,WRITE_CACHE,0L,0,0); -// sort_param.keys=elements; sort_param.max_rows= elements; - sort_param.examined_rows=0; sort_param.sort_form=table; sort_param.sort_length=sort_param.ref_length=tree.size_of_element; sort_param.keys= max_in_memory_size / sort_param.sort_length;