diff options
author | Sinisa@sinisa.nasamreza.org <> | 2003-01-21 15:54:36 +0200 |
---|---|---|
committer | Sinisa@sinisa.nasamreza.org <> | 2003-01-21 15:54:36 +0200 |
commit | 74f478f9a5571556eacf0a2922d32f282520d301 (patch) | |
tree | 12b636bd4e539bd743ac707375d81f309509f79c /sql | |
parent | fe5e05cd90d4c07b815b3250164cf739039fa48a (diff) | |
parent | ff4ef4c4e7d51421cfde0016148eda935f65cd4e (diff) | |
download | mariadb-git-74f478f9a5571556eacf0a2922d32f282520d301.tar.gz |
Merge sinisa@work.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/work/mysql-4.0
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_innodb.cc | 10 | ||||
-rw-r--r-- | sql/log_event.cc | 10 | ||||
-rw-r--r-- | sql/slave.cc | 21 | ||||
-rw-r--r-- | sql/sql_acl.cc | 1 | ||||
-rw-r--r-- | sql/sql_db.cc | 23 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 98 | ||||
-rw-r--r-- | sql/sql_table.cc | 9 |
8 files changed, 113 insertions, 62 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b4fe6130e9b..b1cb45be6b3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4166,6 +4166,16 @@ ha_innobase::store_lock( lock_type = TL_WRITE_ALLOW_WRITE; } + /* In queries of type INSERT INTO t1 SELECT ... FROM t2 ... + MySQL would use the lock TL_READ_NO_INSERT on t2, and that + would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts + to t2. Convert the lock to a normal read lock to allow + concurrent inserts to t2. */ + + if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) { + lock_type = TL_READ; + } + lock.type=lock_type; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 45f54e420de..e243a953c63 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1702,10 +1702,11 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { - thd->query = (char*)query; thd->set_time((time_t)when); thd->current_tablenr = 0; + thd->query_length= q_len; VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query = (char*)query; thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->query_error = 0; // clear error @@ -1760,7 +1761,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) else { // master could be inconsistent, abort and tell DBA to check/fix it + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db = thd->query = 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->variables.convert_set = 0; close_thread_tables(thd); free_root(&thd->mem_root,0); @@ -1768,7 +1771,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) } } thd->db= 0; // prevent db from being freed + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query= 0; // just to be sure + VOID(pthread_mutex_unlock(&LOCK_thread_count)); // assume no convert for next query unless set explictly thd->variables.convert_set = 0; close_thread_tables(thd); @@ -1816,7 +1821,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, { init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)db); - thd->query = 0; + DBUG_ASSERT(thd->query == 0); + thd->query = 0; // Should not be needed thd->query_error = 0; if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) diff --git a/sql/slave.cc b/sql/slave.cc index b8689a28a54..30c345f8030 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -867,6 +867,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name) { ulong packet_len = my_net_read(net); // read create table statement + char *query; Vio* save_vio; HA_CHECK_OPT check_opt; TABLE_LIST tables; @@ -886,15 +887,23 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, return 1; } thd->command = COM_TABLE_DUMP; - thd->query = sql_alloc(packet_len + 1); - if (!thd->query) + /* Note that we should not set thd->query until the area is initalized */ + if (!(query = sql_alloc(packet_len + 1))) { sql_print_error("create_table_from_dump: out of memory"); net_printf(&thd->net, ER_GET_ERRNO, "Out of memory"); return 1; } - memcpy(thd->query, net->read_pos, packet_len); - thd->query[packet_len] = 0; + memcpy(query, net->read_pos, packet_len); + query[packet_len]= 0; + thd->query_length= packet_len; + /* + We make the following lock in an attempt to ensure that the compiler will + not rearrange the code so that thd->query is set too soon + */ + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= query; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->current_tablenr = 0; thd->query_error = 0; thd->net.no_send_ok = 1; @@ -2049,7 +2058,9 @@ err: // print the current replication position sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s", IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { mc_mysql_close(mysql); @@ -2183,7 +2194,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); err: + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a9bb22fb8f7..9091784bbf3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2322,6 +2322,7 @@ my_bool grant_init(THD *org_thd) if (t_table->file->index_first(t_table->record[0])) { t_table->file->index_end(); + return_val= 0; goto end_unlock; } grant_option= TRUE; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e805cf74f19..4cb46c00bed 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -78,9 +78,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) if (!thd->query) { /* The client used the old obsolete mysql_create_db() call */ - thd->query = path; - thd->query_length = (uint) (strxmov(path,"create database `", db, "`", - NullS) - path); + thd->query_length= (uint) (strxmov(path,"create database `", db, "`", + NullS) - path); + thd->query= path; } { mysql_update_log.write(thd,thd->query, thd->query_length); @@ -92,8 +92,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) } if (thd->query == path) { - thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net, result); } @@ -167,9 +168,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { if (!thd->query) { - thd->query = path; - thd->query_length = (uint) (strxmov(path,"drop database ", db, NullS)- - path); + thd->query_length= (uint) (strxmov(path,"drop database `", db, "`", + NullS)- + path); + thd->query= path; } mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) @@ -179,8 +181,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } if (thd->query == path) { - thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net,(ulong) deleted); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5bf3a1c0bcd..0b6170f1e37 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -852,7 +852,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) goto err; } net_flush(&thd->net); - if ((error = table->file->dump(thd,fd))) + if ((error= table->file->dump(thd,fd))) my_error(ER_GET_ERRNO, MYF(0)); err: @@ -958,7 +958,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, tbl_name[tbl_len] = 0; if (mysql_table_dump(thd, db, tbl_name, -1)) send_error(&thd->net); // dump to NET - break; } case COM_CHANGE_USER: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 237197ba6be..e811c55ed1b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1009,7 +1009,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, table_map found_const_table_map,all_table_map; TABLE **table_vector; JOIN_TAB *stat,*stat_end,*s,**stat_ref; - SQL_SELECT *select; KEYUSE *keyuse,*start_keyuse; table_map outer_join=0; JOIN_TAB *stat_vector[MAX_TABLES+1]; @@ -1021,7 +1020,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2)); if (!stat || !stat_ref || !table_vector) DBUG_RETURN(1); // Eom /* purecov: inspected */ - select=0; join->best_ref=stat_vector; @@ -1205,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, { // Found everything for ref. int tmp; ref_changed = 1; - s->type=JT_CONST; + s->type= JT_CONST; join->const_table_map|=table->map; set_position(join,const_count++,s,start_keyuse); if (create_ref_for_key(join, s, start_keyuse, @@ -1256,23 +1254,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (s->const_keys) { ha_rows records; - if (!select) - select=make_select(s->table, found_const_table_map, - found_const_table_map, - and_conds(conds,s->on_expr),&error); - records=get_quick_record_count(select,s->table, s->const_keys, - join->row_limit); + SQL_SELECT *select; + select= make_select(s->table, found_const_table_map, + found_const_table_map, + s->on_expr ? s->on_expr : conds, + &error); + records= get_quick_record_count(select,s->table, s->const_keys, + join->row_limit); s->quick=select->quick; s->needed_reg=select->needed_reg; select->quick=0; + if (records == 0 && s->table->reginfo.impossible_range) + { + /* + Impossible WHERE or ON expression + In case of ON, we mark that the we match one empty NULL row. + In case of WHERE, don't set found_const_table_map to get the + caller to abort with a zero row result. + */ + join->const_table_map|= s->table->map; + set_position(join,const_count++,s,(KEYUSE*) 0); + s->type= JT_CONST; + if (s->on_expr) + { + /* Generate empty row */ + s->info= "Impossible ON condition"; + found_const_table_map|= s->table->map; + s->type= JT_CONST; + mark_as_null_row(s->table); // All fields are NULL + } + } if (records != HA_POS_ERROR) { s->found_records=records; s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); } + delete select; } } - delete select; /* Find best combination and return it */ join->join_tab=stat; @@ -2367,7 +2386,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, keyparts != keyinfo->key_parts) j->type=JT_REF; /* Must read with repeat */ else if (ref_key == j->ref.key_copy) - { /* Should never be reached */ + { /* This happen if we are using a constant expression in the ON part of an LEFT JOIN. @@ -7333,36 +7352,39 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (tab->info) item_list.push_back(new Item_string(tab->info,strlen(tab->info))); - else if (tab->select) + else { - if (tab->use_quick == 2) + if (tab->select) { - sprintf(buff_ptr,"; Range checked for each record (index map: %u)", - tab->keys); - buff_ptr=strend(buff_ptr); + if (tab->use_quick == 2) + { + sprintf(buff_ptr,"; Range checked for each record (index map: %u)", + tab->keys); + buff_ptr=strend(buff_ptr); + } + else + buff_ptr=strmov(buff_ptr,"; Using where"); } - else - buff_ptr=strmov(buff_ptr,"; Using where"); - } - if (key_read) - buff_ptr= strmov(buff_ptr,"; Using index"); - if (table->reginfo.not_exists_optimize) - buff_ptr= strmov(buff_ptr,"; Not exists"); - if (need_tmp_table) - { - need_tmp_table=0; - buff_ptr= strmov(buff_ptr,"; Using temporary"); - } - if (need_order) - { - need_order=0; - buff_ptr= strmov(buff_ptr,"; Using filesort"); + if (key_read) + buff_ptr= strmov(buff_ptr,"; Using index"); + if (table->reginfo.not_exists_optimize) + buff_ptr= strmov(buff_ptr,"; Not exists"); + if (need_tmp_table) + { + need_tmp_table=0; + buff_ptr= strmov(buff_ptr,"; Using temporary"); + } + if (need_order) + { + need_order=0; + buff_ptr= strmov(buff_ptr,"; Using filesort"); + } + if (distinct && test_all_bits(used_tables,thd->used_tables)) + buff_ptr= strmov(buff_ptr,"; Distinct"); + if (buff_ptr == buff) + buff_ptr+= 2; + item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2)); } - if (distinct && test_all_bits(used_tables,thd->used_tables)) - buff_ptr= strmov(buff_ptr,"; Distinct"); - if (buff_ptr == buff) - buff_ptr+= 2; - item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2)); // For next iteration used_tables|=table->map; if (result->send_data(item_list)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 266bf8aefa9..c04b4871b4d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1771,12 +1771,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, /* We changed a temporary table */ if (error) { - /* - * The following function call will also free a - * new_table pointer. - * Therefore, here new_table pointer is not free'd as it is - * free'd in close_temporary() which is called by by the - * close_temporary_table() function. + /* + The following function call will free the new_table pointer, + in close_temporary_table(), so we can safely directly jump to err */ close_temporary_table(thd,new_db,tmp_name); goto err; |