diff options
author | unknown <jimw@mysql.com> | 2006-01-06 10:42:58 -0800 |
---|---|---|
committer | unknown <jimw@mysql.com> | 2006-01-06 10:42:58 -0800 |
commit | 91881b44c347e173d5d49aa9e5351a42267ed0a2 (patch) | |
tree | 8924a87e95e1f01b8788892513110b379c98c991 /sql | |
parent | 3c4c332fd0ce4f6ec06a1f3b0c98a25cac80a2f4 (diff) | |
parent | bf1ebe98dfe51c7f7b13e783cd13d8362a26afbf (diff) | |
download | mariadb-git-91881b44c347e173d5d49aa9e5351a42267ed0a2.tar.gz |
Merge mysql.com:/home/jimw/my/mysql-5.0-clean
into mysql.com:/home/jimw/my/mysql-5.1-clean
include/config-win.h:
Auto merged
mysql-test/r/bdb.result:
Auto merged
mysql-test/r/create.result:
Auto merged
mysql-test/r/view.result:
Auto merged
mysql-test/t/bdb.test:
Auto merged
mysql-test/t/create.test:
Auto merged
mysql-test/t/disabled.def:
Auto merged
mysql-test/t/view.test:
Auto merged
sql/ha_federated.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item.h:
Auto merged
sql/mysqld.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/parse_file.cc:
Auto merged
sql/sp.cc:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sp_head.h:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_handler.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_trigger.cc:
Auto merged
sql/field.cc:
Resolve conflict
sql/ha_ndbcluster.cc:
Resolve conflict
sql/log_event.cc:
Resolve conflict
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_federated.cc | 3 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 30 | ||||
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/item.cc | 6 | ||||
-rw-r--r-- | sql/item.h | 6 | ||||
-rw-r--r-- | sql/log_event.cc | 70 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 14 | ||||
-rw-r--r-- | sql/parse_file.cc | 2 | ||||
-rw-r--r-- | sql/sp.cc | 70 | ||||
-rw-r--r-- | sql/sp_head.cc | 82 | ||||
-rw-r--r-- | sql/sp_head.h | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_handler.cc | 37 | ||||
-rw-r--r-- | sql/sql_insert.cc | 6 | ||||
-rw-r--r-- | sql/sql_parse.cc | 12 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 31 |
18 files changed, 197 insertions, 185 deletions
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 944333496ae..bc087ac25e7 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -2607,8 +2607,7 @@ int ha_federated::stash_remote_error() { DBUG_ENTER("ha_federated::stash_remote_error()"); remote_error_number= mysql_errno(mysql); - my_snprintf(remote_error_buf, sizeof(remote_error_buf), "%s", - mysql_error(mysql)); + strmake(remote_error_buf, mysql_error(mysql), sizeof(remote_error_buf)-1); DBUG_RETURN(HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index dfbe1993ea8..a72bfa7d170 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -370,7 +370,8 @@ Thd_ndb::~Thd_ndb() if (ndb) { #ifndef DBUG_OFF - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (ndb->get_free_list_usage(&tmp)) { uint leaked= (uint) tmp.m_created - tmp.m_free; @@ -382,8 +383,8 @@ Thd_ndb::~Thd_ndb() } #endif delete ndb; + ndb= NULL; } - ndb= NULL; changed_tables.empty(); } @@ -3359,6 +3360,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) if (lock_type != F_UNLCK) { DBUG_PRINT("info", ("lock_type != F_UNLCK")); + if (!thd->transaction.on) + m_transaction_on= FALSE; + else + m_transaction_on= thd->variables.ndb_use_transactions; if (!thd_ndb->lock_count++) { PRINT_OPTION_FLAGS(thd); @@ -3373,7 +3378,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->stmt= trans; - trans_register_ha(thd, FALSE, &ndbcluster_hton); + if (m_transaction_on) + trans_register_ha(thd, FALSE, &ndbcluster_hton); } else { @@ -3388,7 +3394,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->all= trans; - trans_register_ha(thd, TRUE, &ndbcluster_hton); + if (m_transaction_on) + trans_register_ha(thd, TRUE, &ndbcluster_hton); /* If this is the start of a LOCK TABLE, a table look @@ -3422,10 +3429,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) m_ha_not_exact_count= !thd->variables.ndb_use_exact_count; m_autoincrement_prefetch= (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz; - if (!thd->transaction.on) - m_transaction_on= FALSE; - else - m_transaction_on= thd->variables.ndb_use_transactions; m_active_trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt; DBUG_ASSERT(m_active_trans); @@ -5172,7 +5175,8 @@ int ndbcluster_end(ha_panic_function type) if (g_ndb) { #ifndef DBUG_OFF - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (g_ndb->get_free_list_usage(&tmp)) { uint leaked= (uint) tmp.m_created - tmp.m_free; @@ -5184,10 +5188,9 @@ int ndbcluster_end(ha_panic_function type) } #endif delete g_ndb; + g_ndb= NULL; } - g_ndb= NULL; - if (g_ndb_cluster_connection) - delete g_ndb_cluster_connection; + delete g_ndb_cluster_connection; g_ndb_cluster_connection= NULL; hash_free(&ndbcluster_open_tables); @@ -8075,7 +8078,8 @@ ndbcluster_show_status(THD* thd, stat_print_fn *stat_print, if (get_thd_ndb(thd) && get_thd_ndb(thd)->ndb) { Ndb* ndb= (get_thd_ndb(thd))->ndb; - Ndb::Free_list_usage tmp; tmp.m_name= 0; + Ndb::Free_list_usage tmp; + tmp.m_name= 0; while (ndb->get_free_list_usage(&tmp)) { uint buflen= diff --git a/sql/handler.cc b/sql/handler.cc index cff7b21ddc2..6f3cdc5a5cd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2084,7 +2084,8 @@ int ha_enable_transaction(THD *thd, bool on) is an optimization hint that storage engine is free to ignore. So, let's commit an open transaction (if any) now. */ - error= end_trans(thd, COMMIT); + if (!(error= ha_commit_stmt(thd))) + error= end_trans(thd, COMMIT); } DBUG_RETURN(error); } diff --git a/sql/item.cc b/sql/item.cc index bf5718bb54d..fa5c2b5cc3b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4925,6 +4925,12 @@ int Item_ref::save_in_field(Field *to, bool no_conversions) } +void Item_ref::save_org_in_field(Field *field) +{ + (*ref)->save_org_in_field(field); +} + + void Item_ref::make_field(Send_field *field) { (*ref)->make_field(field); diff --git a/sql/item.h b/sql/item.h index c240733bd04..5de69013605 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1782,11 +1782,7 @@ public: void make_field(Send_field *field); bool fix_fields(THD *, Item **); int save_in_field(Field *field, bool no_conversions); - void save_org_in_field(Field *field) - { - (*ref)->save_org_in_field(field); - null_value= (*ref)->null_value; - } + void save_org_in_field(Field *field); enum Item_result result_type () const { return (*ref)->result_type(); } enum_field_types field_type() const { return (*ref)->field_type(); } Field *get_tmp_table_field() diff --git a/sql/log_event.cc b/sql/log_event.cc index 6e256a0c295..eb61cd1f407 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -118,13 +118,24 @@ static char *pretty_print_str(char *packet, char *str, int len) /* - slave_load_file_stem() + Creates a temporary name for load data infile: + + SYNOPSIS + slave_load_file_stem() + buf Store new filename here + file_id File_id (part of file name) + event_server_id Event_id (part of file name) + ext Extension for file name + + RETURN + Pointer to start of extension */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -static inline char* slave_load_file_stem(char*buf, uint file_id, - int event_server_id) +static char *slave_load_file_stem(char *buf, uint file_id, + int event_server_id, const char *ext) { + char *res; fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME); to_unix_path(buf); @@ -133,7 +144,9 @@ static inline char* slave_load_file_stem(char*buf, uint file_id, *buf++ = '-'; buf = int10_to_str(event_server_id, buf, 10); *buf++ = '-'; - return int10_to_str(file_id, buf, 10); + res= int10_to_str(file_id, buf, 10); + strmov(res, ext); // Add extension last + return res; // Pointer to extension } #endif @@ -928,7 +941,6 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) /* Pretty-print event common header if header is exactly 19 bytes */ if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); fprintf(file, "# Position Timestamp Type Master ID " "Size Master Pos Flags \n"); fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x " @@ -954,7 +966,6 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) if (i % 16 == 15) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); fprintf(file, "# %8.8lx %-48.48s |%16s|\n", (unsigned long) (hexdump_from + (i & 0xfffffff0)), hex_string, char_string); @@ -968,12 +979,10 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) *c= '\0'; /* Non-full last line */ - if (hex_string[0]) { - DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from); + if (hex_string[0]) fprintf(file, "# %8.8lx %-48.48s |%s|\n# ", (unsigned long) (hexdump_from + (i & 0xfffffff0)), hex_string, char_string); - } } } @@ -4238,16 +4247,15 @@ void Create_file_log_event::pack_info(Protocol *protocol) #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) int Create_file_log_event::exec_event(struct st_relay_log_info* rli) { - char proc_info[17+FN_REFLEN+10], *fname_buf= proc_info+17; - char *p; + char proc_info[17+FN_REFLEN+10], *fname_buf; + char *ext; int fd = -1; IO_CACHE file; int error = 1; bzero((char*)&file, sizeof(file)); - p = slave_load_file_stem(fname_buf, file_id, server_id); - strmov(p, ".info"); // strmov takes less code than memcpy - strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0 + fname_buf= strmov(proc_info, "Making temp file "); + ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info"); thd->proc_info= proc_info; my_delete(fname_buf, MYF(0)); // old copy may exist already if ((fd= my_create(fname_buf, CREATE_MODE, @@ -4262,12 +4270,11 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) } // a trick to avoid allocating another buffer - strmov(p, ".data"); - fname = fname_buf; - fname_len = (uint)(p-fname) + 5; + fname= fname_buf; + fname_len= (uint) (strmov(ext, ".data") - fname); if (write_base(&file)) { - strmov(p, ".info"); // to have it right in the error message + strmov(ext, ".info"); // to have it right in the error message slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf); @@ -4413,13 +4420,12 @@ int Append_block_log_event::get_create_or_append() const int Append_block_log_event::exec_event(struct st_relay_log_info* rli) { char proc_info[17+FN_REFLEN+10], *fname= proc_info+17; - char *p= slave_load_file_stem(fname, file_id, server_id); int fd; int error = 1; DBUG_ENTER("Append_block_log_event::exec_event"); - memcpy(p, ".data", 6); - strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0 + fname= strmov(proc_info, "Making temp file "); + slave_load_file_stem(fname, file_id, server_id, ".data"); thd->proc_info= proc_info; if (get_create_or_append()) { @@ -4545,10 +4551,9 @@ void Delete_file_log_event::pack_info(Protocol *protocol) int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) { char fname[FN_REFLEN+10]; - char *p= slave_load_file_stem(fname, file_id, server_id); - memcpy(p, ".data", 6); + char *ext= slave_load_file_stem(fname, file_id, server_id, ".data"); (void) my_delete(fname, MYF(MY_WME)); - memcpy(p, ".info", 6); + strmov(ext, ".info"); (void) my_delete(fname, MYF(MY_WME)); return Log_event::exec_event(rli); } @@ -4641,13 +4646,13 @@ void Execute_load_log_event::pack_info(Protocol *protocol) int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) { char fname[FN_REFLEN+10]; - char *p= slave_load_file_stem(fname, file_id, server_id); + char *ext; int fd; - int error = 1; + int error= 1; IO_CACHE file; - Load_log_event* lev = 0; + Load_log_event *lev= 0; - memcpy(p, ".info", 6); + ext= slave_load_file_stem(fname, file_id, server_id, ".info"); if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW, MYF(MY_WME))) < 0 || init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, @@ -4708,7 +4713,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) fd= -1; } (void) my_delete(fname, MYF(MY_WME)); - memcpy(p, ".data", 6); + memcpy(ext, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); error = 0; @@ -4906,11 +4911,10 @@ Execute_load_query_log_event::exec_event(struct st_relay_log_info* rli) memcpy(p, query, fn_pos_start); p+= fn_pos_start; fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'"))); - p= slave_load_file_stem(p, file_id, server_id); - fname_end= (p= strmake(p, STRING_WITH_LEN(".data"))); + p= slave_load_file_stem(p, file_id, server_id, ".data"); + fname_end= p= strend(p); // Safer than p=p+5 *(p++)='\''; - switch (dup_handling) - { + switch (dup_handling) { case LOAD_DUP_IGNORE: p= strmake(p, STRING_WITH_LEN(" IGNORE")); break; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0c6e0b89c19..4a6dddcad11 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1701,7 +1701,7 @@ void end_thread(THD *thd, bool put_in_cache) wake_thread--; thd=thread_cache.get(); thd->real_id=pthread_self(); - thd->thread_stack= (char *) &thd; + thd->thread_stack= (char*) &thd; // For store_globals (void) thd->store_globals(); thd->thr_create_time= time(NULL); threads.append(thd); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index f090fac2ecf..7dd694f3411 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -6955,6 +6955,7 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields) /* Create quick select from ref/ref_or_null scan. + SYNOPSIS get_quick_select_for_ref() thd Thread handle @@ -6974,15 +6975,18 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields) QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref, ha_rows records) { - MEM_ROOT *old_root= thd->mem_root; - /* The following call may change thd->mem_root */ - QUICK_RANGE_SELECT *quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); - /* save mem_root set by QUICK_RANGE_SELECT constructor */ - MEM_ROOT *alloc= thd->mem_root; + MEM_ROOT *old_root, *alloc; + QUICK_RANGE_SELECT *quick; KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; uint part; + + old_root= thd->mem_root; + /* The following call may change thd->mem_root */ + quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); + /* save mem_root set by QUICK_RANGE_SELECT constructor */ + alloc= thd->mem_root; /* return back default mem_root (thd->mem_root) changed by QUICK_RANGE_SELECT constructor diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 0b2bfe83b6f..3cddc879825 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -956,6 +956,6 @@ File_parser_dummy_hook::process_unknown_string(char *&unknown_key, char *end) { DBUG_ENTER("file_parser_dummy_hook::process_unknown_string"); - DBUG_PRINT("info", ("unknown key:%60s", unknown_key)); + DBUG_PRINT("info", ("Unknown key: '%60s'", unknown_key)); DBUG_RETURN(FALSE); } diff --git a/sql/sp.cc b/sql/sp.cc index c85c1f2afef..f70e150419a 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -398,14 +398,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, const char *body, st_sp_chistics &chistics, const char *definer, longlong created, longlong modified) { - LEX *oldlex= thd->lex, newlex; - sp_rcontext *save_spcont= thd->spcont; + LEX *old_lex= thd->lex, newlex; String defstr; char olddb[128]; bool dbchanged; ulong old_sql_mode= thd->variables.sql_mode; - ha_rows select_limit= thd->variables.select_limit; - int ret= SP_INTERNAL_ERROR; + ha_rows old_select_limit= thd->variables.select_limit; + sp_rcontext *old_spcont= thd->spcont; + int ret; thd->variables.sql_mode= sql_mode; thd->variables.select_limit= HA_POS_ERROR; @@ -421,7 +421,10 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, returns, strlen(returns), body, strlen(body), &chistics)) + { + ret= SP_INTERNAL_ERROR; goto end; + } dbchanged= FALSE; if ((ret= sp_use_new_db(thd, name->m_db.str, olddb, sizeof(olddb), @@ -450,10 +453,10 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, (*sphp)->optimize(); } end: - thd->spcont= save_spcont; + thd->spcont= old_spcont; thd->variables.sql_mode= old_sql_mode; - thd->variables.select_limit= select_limit; - thd->lex= oldlex; + thd->variables.select_limit= old_select_limit; + thd->lex= old_lex; return ret; } @@ -927,7 +930,6 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, ulong depth= (type == TYPE_ENUM_PROCEDURE ? thd->variables.max_sp_recursion_depth : 0); - DBUG_ENTER("sp_find_routine"); DBUG_PRINT("enter", ("name: %.*s.%.*s, type: %d, cache only %d", name->m_db.length, name->m_db.str, @@ -937,6 +939,11 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, if ((sp= sp_cache_lookup(cp, name))) { ulong level; + sp_head *new_sp; + const char *returns= ""; + char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; + String retstr(64); + DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); if (sp->m_first_free_instance) { @@ -947,7 +954,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED)); if (sp->m_first_free_instance->m_recursion_level > depth) { - sp->recursion_level_error(); + sp->recursion_level_error(thd); DBUG_RETURN(0); } DBUG_RETURN(sp->m_first_free_instance); @@ -955,37 +962,32 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, level= sp->m_last_cached_sp->m_recursion_level + 1; if (level > depth) { - sp->recursion_level_error(); + sp->recursion_level_error(thd); DBUG_RETURN(0); } + + strxmov(definer, sp->m_definer_user.str, "@", + sp->m_definer_host.str, NullS); + if (type == TYPE_ENUM_FUNCTION) { - sp_head *new_sp; - const char *returns= ""; - char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; - String retstr(64); - strxmov(definer, sp->m_definer_user.str, "@", - sp->m_definer_host.str, NullS); - if (type == TYPE_ENUM_FUNCTION) - { - sp_returns_type(thd, retstr, sp); - returns= retstr.ptr(); - } - if (db_load_routine(thd, type, name, &new_sp, - sp->m_sql_mode, sp->m_params.str, returns, - sp->m_body.str, *sp->m_chistics, definer, - sp->m_created, sp->m_modified) == SP_OK) - { - sp->m_last_cached_sp->m_next_cached_sp= new_sp; - new_sp->m_recursion_level= level; - new_sp->m_first_instance= sp; - sp->m_last_cached_sp= sp->m_first_free_instance= new_sp; - DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x", + sp_returns_type(thd, retstr, sp); + returns= retstr.ptr(); + } + if (db_load_routine(thd, type, name, &new_sp, + sp->m_sql_mode, sp->m_params.str, returns, + sp->m_body.str, *sp->m_chistics, definer, + sp->m_created, sp->m_modified) == SP_OK) + { + sp->m_last_cached_sp->m_next_cached_sp= new_sp; + new_sp->m_recursion_level= level; + new_sp->m_first_instance= sp; + sp->m_last_cached_sp= sp->m_first_free_instance= new_sp; + DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x", (ulong)new_sp, new_sp->m_recursion_level, new_sp->m_flags)); - DBUG_RETURN(new_sp); - } - DBUG_RETURN(0); + DBUG_RETURN(new_sp); } + DBUG_RETURN(0); } if (!cache_only) { diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 63d1388473e..1d171d929f3 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -24,6 +24,13 @@ #include "sp_rcontext.h" #include "sp_cache.h" +/* + Sufficient max length of printed destinations and frame offsets (all uints). +*/ +#define SP_INSTR_UINT_MAXLEN 8 +#define SP_STMT_PRINT_MAXLEN 40 + + Item_result sp_map_result_type(enum enum_field_types type) { @@ -876,17 +883,17 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) SYNOPSIS sp_head::recursion_level_error() + thd Thread handle NOTE For functions and triggers we return error about prohibited recursion. For stored procedures we return about reaching recursion limit. */ -void sp_head::recursion_level_error() +void sp_head::recursion_level_error(THD *thd) { if (m_type == TYPE_ENUM_PROCEDURE) { - THD *thd= current_thd; my_error(ER_SP_RECURSION_LIMIT, MYF(0), thd->variables.max_sp_recursion_depth, m_name.str); @@ -937,14 +944,15 @@ sp_head::execute(THD *thd) DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; m_first_instance->m_first_free_instance= m_next_cached_sp; - DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x", - (ulong)m_first_instance, this, m_next_cached_sp, - (m_next_cached_sp ? - m_next_cached_sp->m_recursion_level : - 0), - (m_next_cached_sp ? - m_next_cached_sp->m_flags : - 0))); + if (m_next_cached_sp) + { + DBUG_PRINT("info", + ("first free for 0x%lx ++: 0x%lx->0x%lx level: %lu flags %x", + (ulong)m_first_instance, (ulong) this, + (ulong) m_next_cached_sp, + m_next_cached_sp->m_recursion_level, + m_next_cached_sp->m_flags)); + } /* Check that if there are not any instances after this one then pointer to the last instance points on this instance or if there are @@ -1112,13 +1120,15 @@ sp_head::execute(THD *thd) state= EXECUTED; done: - DBUG_PRINT("info", ("err_status=%d killed=%d query_error=%d", + DBUG_PRINT("info", ("err_status: %d killed: %d query_error: %d", err_status, thd->killed, thd->query_error)); if (thd->killed) err_status= TRUE; - /* If the DB has changed, the pointer has changed too, but the - original thd->db will then have been freed */ + /* + If the DB has changed, the pointer has changed too, but the + original thd->db will then have been freed + */ if (dbchanged) { /* @@ -1129,10 +1139,11 @@ sp_head::execute(THD *thd) err_status|= mysql_change_db(thd, olddb, 1); } m_flags&= ~IS_INVOKED; - DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x", - (ulong)m_first_instance, - m_first_instance->m_first_free_instance, this, - m_recursion_level, m_flags)); + DBUG_PRINT("info", + ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x", + (ulong) m_first_instance, + (ulong) m_first_instance->m_first_free_instance, + (ulong) this, m_recursion_level, m_flags)); /* Check that we have one of following: @@ -1142,7 +1153,7 @@ sp_head::execute(THD *thd) 2) There are some free instances which mean that first free instance should go just after this one and recursion level of that free instance - should be on 1 more then recursion leven of this instance. + should be on 1 more then recursion level of this instance. */ DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 && this == m_first_instance->m_last_cached_sp && @@ -1756,16 +1767,16 @@ sp_head::set_info(longlong created, longlong modified, void -sp_head::set_definer(char *definer, uint definerlen) + +sp_head::set_definer(const char *definer, uint definerlen) { - char *p= strrchr(definer, '@'); + const char *p= strrchr(definer, '@'); if (!p) { - m_definer_user.str= strmake_root(mem_root, "", 0); + m_definer_user.str= (char*) ""; m_definer_user.length= 0; - - m_definer_host.str= strmake_root(mem_root, "", 0); + m_definer_host.str= (char*) ""; m_definer_host.length= 0; } else @@ -1860,9 +1871,9 @@ sp_head::show_create_procedure(THD *thd) byte *sql_mode_str; ulong sql_mode_len; bool full_access; - DBUG_ENTER("sp_head::show_create_procedure"); DBUG_PRINT("info", ("procedure %s", m_name.str)); + LINT_INIT(sql_mode_str); LINT_INIT(sql_mode_len); @@ -2215,12 +2226,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } -/* - Sufficient max length of printed destinations and frame offsets (all uints). -*/ -#define SP_INSTR_UINT_MAXLEN 8 -#define SP_STMT_PRINT_MAXLEN 40 void sp_instr_stmt::print(String *str) { @@ -2242,16 +2248,16 @@ sp_instr_stmt::print(String *str) /* Copy the query string and replace '\n' with ' ' in the process */ for (i= 0 ; i < len ; i++) { - if (m_query.str[i] == '\n') - str->qs_append(' '); - else - str->qs_append(m_query.str[i]); + char c= m_query.str[i]; + if (c == '\n') + c= ' '; + str->qs_append(c); } if (m_query.length > SP_STMT_PRINT_MAXLEN) str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */ str->qs_append('"'); } -#undef SP_STMT_PRINT_MAXLEN + int sp_instr_stmt::exec_core(THD *thd, uint *nextp) @@ -2617,6 +2623,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) DBUG_RETURN(0); } + void sp_instr_hpush_jump::print(String *str) { @@ -2627,8 +2634,7 @@ sp_instr_hpush_jump::print(String *str) str->qs_append(m_dest); str->qs_append(' '); str->qs_append(m_frame); - switch (m_type) - { + switch (m_type) { case SP_HANDLER_NONE: str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug break; @@ -2642,11 +2648,13 @@ sp_instr_hpush_jump::print(String *str) str->qs_append(STRING_WITH_LEN(" UNDO")); break; default: - str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); // This would be a bug as well + // This would be a bug as well + str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); str->qs_append(m_type); } } + uint sp_instr_hpush_jump::opt_mark(sp_head *sp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index d99b600f6b2..ff3cb8eac3e 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -285,7 +285,7 @@ public: void set_info(longlong created, longlong modified, st_sp_chistics *chistics, ulong sql_mode); - void set_definer(char *definer, uint definerlen); + void set_definer(const char *definer, uint definerlen); void reset_thd_mem_root(THD *thd); @@ -294,7 +294,7 @@ public: void optimize(); void opt_mark(uint ip); - void recursion_level_error(); + void recursion_level_error(THD *thd); inline sp_instr * get_instr(uint i) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9c3a9366620..b15320567c2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3564,7 +3564,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, of other queries). For simple queries first_not_own_table is 0. */ for (i= 0, table= tables; - table && table != first_not_own_table && i < number; + table != first_not_own_table && i < number; table= table->next_global, i++) { /* Remove SHOW_VIEW_ACL, because it will be checked during making view */ diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 6418f844dbe..f1bbf6f0f5e 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -227,6 +227,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) /* add to hash */ if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables)) { + my_free((char*) hash_tables, MYF(0)); mysql_ha_close(thd, tables); goto err; } @@ -369,28 +370,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p", hash_tables->db, hash_tables->table_name, hash_tables->alias, table)); - /* Table might have been flushed. */ - if (table && (table->s->version != refresh_version)) - { - /* - We must follow the thd->handler_tables chain, as we need the - address of the 'next' pointer referencing this table - for close_thread_table(). - */ - for (table_ptr= &(thd->handler_tables); - *table_ptr && (*table_ptr != table); - table_ptr= &(*table_ptr)->next) - {} - (*table_ptr)->file->ha_index_or_rnd_end(); - VOID(pthread_mutex_lock(&LOCK_open)); - if (close_thread_table(thd, table_ptr)) - { - /* Tell threads waiting for refresh that something has happened */ - VOID(pthread_cond_broadcast(&COND_refresh)); - } - VOID(pthread_mutex_unlock(&LOCK_open)); - table= hash_tables->table= NULL; - } if (!table) { /* @@ -436,6 +415,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, } tables->table=table; + HANDLER_TABLES_HACK(thd); + lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); + HANDLER_TABLES_HACK(thd); + + if (!lock) + goto err0; // mysql_lock_tables() printed error message already + if (cond && ((!cond->fixed && cond->fix_fields(thd, &cond)) || cond->check_cols(1))) goto err0; @@ -455,13 +441,6 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); - HANDLER_TABLES_HACK(thd); - lock= mysql_lock_tables(thd, &tables->table, 1, 0, ¬_used); - HANDLER_TABLES_HACK(thd); - - if (!lock) - goto err0; // mysql_lock_tables() printed error message already - /* In ::external_lock InnoDB resets the fields which tell it that the handle is used in the HANDLER interface. Tell it again that diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 598fac102c1..29df467b916 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2529,7 +2529,11 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) } /* First field to copy */ - field=table->field+table->s->fields - values.elements; + field= table->field+table->s->fields - values.elements; + + /* Mark all fields that are given values */ + for (Field **f= field ; *f ; f++) + (*f)->query_id= thd->query_id; /* Don't set timestamp if used */ table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 483a3540e47..ad205103140 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4856,7 +4856,6 @@ end_with_restore_list: if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION) reset_one_shot_variables(thd); - /* The return value for ROW_COUNT() is "implementation dependent" if the statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC @@ -4868,13 +4867,10 @@ end_with_restore_list: if (lex->sql_command != SQLCOM_CALL && lex->sql_command != SQLCOM_EXECUTE && uc_update_queries[lex->sql_command]<2) thd->row_count_func= -1; - goto cleanup; + DBUG_RETURN(res || thd->net.report_error); error: - res= 1; - -cleanup: - DBUG_RETURN(res || thd->net.report_error); + DBUG_RETURN(1); } @@ -5097,7 +5093,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, the given table list refers to the list for prelocking (contains tables of other queries). For simple queries first_not_own_table is 0. */ - for (; tables && tables != first_not_own_table; tables= tables->next_global) + for (; tables != first_not_own_table; tables= tables->next_global) { if (tables->schema_table && (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) @@ -7263,7 +7259,7 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name) /* Create and initialize. */ - if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER)))) + if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; definer->user= *user_name; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d5a38b13a0e..8c954297f42 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10772,7 +10772,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), item->save_org_in_field(group->field); /* Store in the used key if the field was 0 */ if (item->maybe_null) - group->buff[-1]=item->null_value ? 1 : 0; + group->buff[-1]= (char) group->field->is_null(); } if (!table->file->index_read(table->record[1], join->tmp_table_param.group_buff,0, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 2b124fb5bb4..e4b22cffca0 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -51,6 +51,13 @@ static File_option triggers_file_parameters[]= { { 0, 0 }, 0, FILE_OPTIONS_STRING } }; +File_option sql_modes_parameters= +{ + {(char*) STRING_WITH_LEN("sql_modes") }, + offsetof(class Table_triggers_list, definition_modes_list), + FILE_OPTIONS_ULLLIST +}; + /* This must be kept up to date whenever a new option is added to the list above, as it specifies the number of required parameters of the trigger in @@ -435,7 +442,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!is_acl_user(lex->definer->host.str, - lex->definer->user.str)) + lex->definer->user.str)) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -1161,7 +1168,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, if (is_special_var_used(event, time_type)) { - TABLE_LIST table_list; + TABLE_LIST table_list, **save_query_tables_own_last; bzero((char *) &table_list, sizeof (table_list)); table_list.db= (char *) table->s->db.str; table_list.db_length= table->s->db.length; @@ -1169,8 +1176,13 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, table_list.table_name_length= table->s->table_name.length; table_list.alias= (char *) table->alias; table_list.table= table; + save_query_tables_own_last= thd->lex->query_tables_own_last; + thd->lex->query_tables_own_last= 0; - if (check_table_access(thd, SELECT_ACL | UPDATE_ACL, &table_list, 0)) + err_status= check_table_access(thd, SELECT_ACL | UPDATE_ACL, + &table_list, 0); + thd->lex->query_tables_own_last= save_query_tables_own_last; + if (err_status) { sp_restore_security_context(thd, save_ctx); return TRUE; @@ -1212,32 +1224,29 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, TRUE Error */ +#define INVALID_SQL_MODES_LENGTH 13 + bool Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key, gptr base, MEM_ROOT *mem_root, char *end) { -#define INVALID_SQL_MODES_LENGTH 13 DBUG_ENTER("handle_old_incorrect_sql_modes"); DBUG_PRINT("info", ("unknown key:%60s", unknown_key)); + if (unknown_key + INVALID_SQL_MODES_LENGTH + 1 < end && unknown_key[INVALID_SQL_MODES_LENGTH] == '=' && !memcmp(unknown_key, STRING_WITH_LEN("sql_modes"))) { + char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; + DBUG_PRINT("info", ("sql_modes affected by BUG#14090 detected")); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_OLD_FILE_FORMAT, ER(ER_OLD_FILE_FORMAT), (char *)path, "TRIGGER"); - File_option sql_modes_parameters= - { - {(char *) STRING_WITH_LEN("sql_modes") }, - offsetof(class Table_triggers_list, definition_modes_list), - FILE_OPTIONS_ULLLIST - }; - char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1; if (get_file_options_ulllist(ptr, end, unknown_key, base, &sql_modes_parameters, mem_root)) { |