diff options
53 files changed, 370 insertions, 275 deletions
diff --git a/mysql-test/suite/maria/r/compat_aliases.result b/mysql-test/suite/maria/r/compat_aliases.result index 22150cc680b..bcc9ece0986 100644 --- a/mysql-test/suite/maria/r/compat_aliases.result +++ b/mysql-test/suite/maria/r/compat_aliases.result @@ -1,7 +1,7 @@ select * from information_schema.plugins where plugin_name like '%aria'; PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE PLUGIN_MATURITY PLUGIN_AUTH_VERSION -Maria 1.5 ACTIVE DAEMON 50300.0 NULL NULL Monty Program Ab Compatibility aliases for the Aria engine GPL Gamma 1.5 -Aria 1.5 ACTIVE STORAGE ENGINE 50300.0 NULL NULL Monty Program Ab Crash-safe tables with MyISAM heritage GPL Gamma 1.5 +Maria 1.5 ACTIVE DAEMON # NULL NULL Monty Program Ab Compatibility aliases for the Aria engine GPL Gamma 1.5 +Aria 1.5 ACTIVE STORAGE ENGINE # NULL NULL Monty Program Ab Crash-safe tables with MyISAM heritage GPL Gamma 1.5 select maria_vars.variable_name, aria_vars.variable_name from information_schema.session_variables as maria_vars left join information_schema.session_variables as aria_vars diff --git a/mysql-test/suite/maria/t/compat_aliases.test b/mysql-test/suite/maria/t/compat_aliases.test index d48128a3041..7b94d24e643 100644 --- a/mysql-test/suite/maria/t/compat_aliases.test +++ b/mysql-test/suite/maria/t/compat_aliases.test @@ -3,6 +3,7 @@ # command-line options). They should match aria* variables. # +--replace_column 5 # select * from information_schema.plugins where plugin_name like '%aria'; select maria_vars.variable_name, aria_vars.variable_name from diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 0d0ae2dabe5..0e489263c69 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -224,6 +224,8 @@ void *_myrealloc(register void *ptr, register size_t size, struct st_irem *irem; char *data; DBUG_ENTER("_myrealloc"); + DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) ptr, + (ulong) size, MyFlags)); if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR)) DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags)); @@ -245,6 +247,8 @@ void *_myrealloc(register void *ptr, register size_t size, (void) fflush(stderr); DBUG_RETURN((uchar*) NULL); } + DBUG_PRINT("my", ("old_size: %lu -> new_size: %lu", + (ulong) irem->datasize, (ulong) size)); if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */ { diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index d1fa971847b..13a2f8cf7c2 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -212,7 +212,7 @@ mysql_event_fill_row(THD *thd, Safety: this can only happen if someone started the server and then altered mysql.event. */ - my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias, + my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, MYF(0), table->alias.c_ptr(), (int) ET_FIELD_COUNT, table->s->fields); DBUG_RETURN(TRUE); } @@ -896,7 +896,11 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name, same fields. */ if (db.length > table->field[ET_FIELD_DB]->field_length || - name.length > table->field[ET_FIELD_NAME]->field_length) + name.length > table->field[ET_FIELD_NAME]->field_length || + table->s->keys == 0 || + table->key_info[0].key_parts != 2 || + table->key_info[0].key_part[0].fieldnr != ET_FIELD_DB+1 || + table->key_info[0].key_part[1].fieldnr != ET_FIELD_NAME+1) DBUG_RETURN(TRUE); table->field[ET_FIELD_DB]->store(db.str, db.length, &my_charset_bin); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 8446fe75c8f..4d6636eedb2 100755 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -100,7 +100,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) err_msg.append(err->msg, strlen(err->msg), system_charset_info); DBUG_ASSERT(err->level < 3); (sql_print_message_handlers[err->level])("%*s", err_msg.length(), - err_msg.c_ptr()); + err_msg.c_ptr_safe()); } DBUG_VOID_RETURN; } diff --git a/sql/events.cc b/sql/events.cc index 1b794edb5ec..3713266aaa6 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -480,7 +480,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER will be written into the binary log as the definer for the SQL thread. */ - ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); + ret= write_bin_log(thd, TRUE, log_query.ptr(), log_query.length()); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -779,7 +779,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol) protocol->store(et->name.str, et->name.length, system_charset_info); protocol->store(sql_mode.str, sql_mode.length, system_charset_info); protocol->store(tz_name->ptr(), tz_name->length(), system_charset_info); - protocol->store(show_str.c_ptr(), show_str.length(), + protocol->store(show_str.ptr(), show_str.length(), et->creation_ctx->get_client_cs()); protocol->store(et->creation_ctx->get_client_cs()->csname, strlen(et->creation_ctx->get_client_cs()->csname), diff --git a/sql/field.cc b/sql/field.cc index bf496406fd6..4194c6a8939 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1536,9 +1536,9 @@ void Field::make_field(Send_field *field) } else field->org_table_name= field->db_name= ""; - if (orig_table && orig_table->alias) + if (orig_table && orig_table->alias.ptr()) { - field->table_name= orig_table->alias; + field->table_name= orig_table->alias.ptr(); field->org_col_name= field_name; } else diff --git a/sql/field.h b/sql/field.h index ca400caac59..0161f69ac4d 100644 --- a/sql/field.h +++ b/sql/field.h @@ -131,7 +131,8 @@ public: */ struct st_table *table; // Pointer for table struct st_table *orig_table; // Pointer to original table - const char **table_name, *field_name; + const char * const *table_name; + const char *field_name; /** reference to the list of options or NULL */ engine_option_value *option_list; void *option_struct; /* structure with parsed options */ @@ -551,10 +552,14 @@ public: return (op_result == E_DEC_OVERFLOW); } int warn_if_overflow(int op_result); + void set_table_name(String *alias) + { + table_name= &alias->Ptr; + } void init(TABLE *table_arg) { orig_table= table= table_arg; - table_name= &table_arg->alias; + set_table_name(&table_arg->alias); } /* maximum possible display length */ diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index b777b26bab0..fd0d65a4e73 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1097,7 +1097,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, error != HA_ADMIN_ALREADY_DONE && error != HA_ADMIN_TRY_ALTER) { - print_admin_msg(thd, "error", table_share->db.str, table->alias, + print_admin_msg(thd, "error", table_share->db.str, + table->alias.c_ptr(), opt_op_name[flag], "Subpartition %s returned error", sub_elem->partition_name); @@ -1124,7 +1125,8 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, error != HA_ADMIN_ALREADY_DONE && error != HA_ADMIN_TRY_ALTER) { - print_admin_msg(thd, "error", table_share->db.str, table->alias, + print_admin_msg(thd, "error", table_share->db.str, + table->alias.c_ptr(), opt_op_name[flag], "Partition %s returned error", part_elem->partition_name); } @@ -3884,6 +3886,7 @@ int ha_partition::index_init(uint inx, bool sorted) m_part_spec.start_part= NO_CURRENT_PART_ID; m_start_key.length= 0; m_ordered= sorted; + m_ordered_scan_ongoing= FALSE; m_curr_key_info[0]= table->key_info+inx; if (m_pkey_is_clustered && table->s->primary_key != MAX_KEY) { @@ -4707,6 +4710,12 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) int error; handler *file= m_file[i]; + /* + Reset null bits (to avoid valgrind warnings) and to give a default + value for not read null fields. + */ + bfill(rec_buf_ptr, table->s->null_bytes, 255); + switch (m_index_scan_type) { case partition_index_read: error= file->ha_index_read_map(rec_buf_ptr, diff --git a/sql/handler.cc b/sql/handler.cc index c931b689842..6e5cfb738bb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2009,7 +2009,8 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, dummy_share.db.length= strlen(db); dummy_share.table_name.str= (char*) alias; dummy_share.table_name.length= strlen(alias); - dummy_table.alias= alias; + dummy_table.alias.set(alias, dummy_share.table_name.length, + table_alias_charset); file->change_table_ptr(&dummy_table, &dummy_share); @@ -2852,11 +2853,12 @@ void handler::print_error(int error, myf errflag) { const char* engine= table_type(); if (temporary) - my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine); + my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.c_ptr(), + engine); else { SET_FATAL_ERROR; - my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine); + my_error(ER_GET_ERRMSG, MYF(0), error, str.c_ptr(), engine); } } else diff --git a/sql/handler.h b/sql/handler.h index f76580b7082..00d6347eb78 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -139,6 +139,7 @@ #define HA_HAS_NEW_CHECKSUM (LL(1) << 36) #define HA_MRR_CANT_SORT (LL(1) << 37) +#define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (LL(1) << 38) /* Set of all binlog flags. Currently only contain the capabilities diff --git a/sql/item.cc b/sql/item.cc index 1419c9c3e6e..7b6f6e89a1f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -781,7 +781,8 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) } if (cs->ctype) { - uint orig_len= length; + const char *str_start= str; + /* This will probably need a better implementation in the future: a function in CHARSET_INFO structure. @@ -791,16 +792,20 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) length--; str++; } - if (orig_len != length && !is_autogenerated_name) + if (str != str_start && !is_autogenerated_name) { + char buff[SAFE_NAME_LEN]; + strmake(buff, str_start, + min(sizeof(buff)-1, length + (int) (str-str_start))); + if (length == 0) push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY), - str + length - orig_len); + buff); else push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES), - str + length - orig_len); + buff); } } if (!my_charset_same(cs, system_charset_info)) @@ -2566,14 +2571,12 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end) tmp= my_strntod(cs, (char*) cptr, end - cptr, &end, &error); if (error || (end != org_end && !check_if_only_end_space(cs, end, org_end))) { - /* - We can use str_value.ptr() here as Item_string is gurantee to put an - end \0 here. - */ + char buff[80]; + strmake(buff, cptr, min(sizeof(buff)-1, (size_t) (org_end-cptr))); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE", - cptr); + buff); } return tmp; } @@ -2582,8 +2585,10 @@ double_from_string_with_check (CHARSET_INFO *cs, const char *cptr, char *end) double Item_string::val_real() { DBUG_ASSERT(fixed == 1); - return double_from_string_with_check (str_value.charset(), str_value.ptr(), - (char *) str_value.ptr() + str_value.length()); + return double_from_string_with_check(str_value.charset(), + str_value.ptr(), + (char *) str_value.ptr() + + str_value.length()); } diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 7d025ef518b..b15083f54a2 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -121,14 +121,20 @@ bool Cached_item_int::cmp(void) bool Cached_item_field::cmp(void) { - bool tmp= field->cmp(buff) != 0; // This is not a blob! - if (tmp) - field->get_image(buff,length,field->charset()); + bool tmp= FALSE; // Value is identical + /* Note that field can't be a blob here ! */ if (null_value != field->is_null()) { null_value= !null_value; - tmp=TRUE; + tmp= TRUE; // Value has changed } + + /* + If value is not null and value changed (from null to not null or + becasue of value change), then copy the new value to buffer. + */ + if (! null_value && (tmp || (tmp= (field->cmp(buff) != 0)))) + field->get_image(buff,length,field->charset()); return tmp; } diff --git a/sql/item_func.cc b/sql/item_func.cc index c4eb6cdc2aa..872cdf0185b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2961,7 +2961,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, String *res= arguments[i]->val_str(&buffers[i]); if (arguments[i]->null_value) continue; - f_args.args[i]= (char*) res->c_ptr(); + f_args.args[i]= (char*) res->c_ptr_safe(); f_args.lengths[i]= res->length(); break; } @@ -5812,7 +5812,7 @@ Item_func_sp::func_name() const qname.append('.'); } append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length); - return qname.ptr(); + return qname.c_ptr_safe(); } @@ -5868,7 +5868,7 @@ Item_func_sp::init_result_field(THD *thd) */ share= dummy_table->s; - dummy_table->alias = ""; + dummy_table->alias.set("", 0, table_alias_charset); dummy_table->maybe_null = maybe_null; dummy_table->in_use= thd; dummy_table->copy_blobs= TRUE; diff --git a/sql/item_sum.h b/sql/item_sum.h index b5516792676..46e5ae76ab1 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1274,8 +1274,13 @@ public: void make_unique(); double val_real() { - String *res; res=val_str(&str_value); - return res ? my_atof(res->c_ptr()) : 0.0; + int error; + const char *end; + String *res; + if (!(res= val_str(&str_value))) + return 0.0; + end= res->ptr() + res->length(); + return (my_strtod(res->ptr(), (char**) &end, &error)); } longlong val_int() { diff --git a/sql/key.cc b/sql/key.cc index 89423e5280e..a1793e9e5f4 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -113,13 +113,24 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, if (key_length == 0) key_length= key_info->key_length; - for (key_part= key_info->key_part; (int) key_length > 0; key_part++) + for (key_part= key_info->key_part; + (int) key_length > 0; + key_part++, to_key+= length, key_length-= length) { if (key_part->null_bit) { *to_key++= test(from_record[key_part->null_offset] & key_part->null_bit); key_length--; + if (to_key[-1]) + { + /* + Don't copy data for null values + The -1 below is to subtract the null byte which is already handled + */ + length= min(key_length, (uint) key_part->store_length-1); + continue; + } } if (key_part->key_part_flag & HA_BLOB_PART || key_part->key_part_flag & HA_VAR_LENGTH_PART) @@ -138,8 +149,6 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info, if (bytes < length) cs->cset->fill(cs, (char*) to_key + bytes, length - bytes, ' '); } - to_key+= length; - key_length-= length; } } @@ -166,16 +175,28 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info, { key_length= key_info->key_length; } - for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++) + for (key_part= key_info->key_part ; + (int) key_length > 0 ; + key_part++, from_key+= length, key_length-= length) { uchar used_uneven_bits= 0; if (key_part->null_bit) { - if (*from_key++) + bool null_value; + if ((null_value= *from_key++)) to_record[key_part->null_offset]|= key_part->null_bit; else to_record[key_part->null_offset]&= ~key_part->null_bit; key_length--; + if (null_value) + { + /* + Don't copy data for null bytes + The -1 below is to subtract the null byte which is already handled + */ + length= min(key_length, (uint) key_part->store_length-1); + continue; + } } if (key_part->type == HA_KEYTYPE_BIT) { @@ -229,8 +250,6 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info, memcpy(to_record + key_part->offset, from_key + used_uneven_bits , (size_t) length - used_uneven_bits); } - from_key+= length; - key_length-= length; } } diff --git a/sql/lock.cc b/sql/lock.cc index 566275c5ea2..7c569bf7cfc 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -903,7 +903,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); + my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr()); /* Clear the lock type of the lock data that are stored already. */ sql_lock->lock_count= (uint) (locks - sql_lock->locks); reset_lock_data(sql_lock); diff --git a/sql/log.cc b/sql/log.cc index 07d9890ff78..93a9383f731 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1751,7 +1751,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) log_query.append(thd->lex->ident.str, thd->lex->ident.length)) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), TRUE, TRUE, errcode); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } @@ -1773,7 +1773,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) log_query.append(thd->lex->ident.str, thd->lex->ident.length)) DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), TRUE, TRUE, errcode); DBUG_RETURN(mysql_bin_log.write(&qinfo)); } diff --git a/sql/log_event.cc b/sql/log_event.cc index fa7bb01077d..32552bfe85f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -568,7 +568,7 @@ append_query_string(CHARSET_INFO *csinfo, if (to->reserve(orig_len + from->length()*2+3)) return 1; - beg= to->c_ptr_quick() + to->length(); + beg= (char*) to->ptr() + to->length(); ptr= beg; if (csinfo->escape_with_backslash_is_dangerous) ptr= str_to_hex(ptr, from->ptr(), from->length()); diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 8ca525994c9..7cd2c13ee11 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -116,7 +116,7 @@ my_bool my_net_init(NET *net, Vio* vio) net->vio = vio; my_net_local_init(net); /* Set some limits */ if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ - NET_HEADER_SIZE + COMP_HEADER_SIZE, + NET_HEADER_SIZE + COMP_HEADER_SIZE +1, MYF(MY_WME)))) DBUG_RETURN(1); net->buff_end=net->buff+net->max_packet; @@ -580,7 +580,7 @@ net_real_write(NET *net,const uchar *packet, size_t len) uchar *b; uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE + - COMP_HEADER_SIZE, MYF(MY_WME)))) + COMP_HEADER_SIZE + 1, MYF(MY_WME)))) { net->error= 2; net->last_errno= ER_OUT_OF_RESOURCES; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d77893bdb1c..3818040d781 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11130,7 +11130,8 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, if (!tmp.length()) tmp.append(STRING_WITH_LEN("(empty)")); - DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, tmp.ptr())); + DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, + tmp.c_ptr_safe())); DBUG_VOID_RETURN; } @@ -11153,7 +11154,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg, } if (!tmp.length()) tmp.append(STRING_WITH_LEN("(empty)")); - DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr())); + DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.c_ptr())); DBUG_VOID_RETURN; } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 5973c95d101..5428467b850 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1030,7 +1030,7 @@ int pull_out_semijoin_tables(JOIN *join) pulled_a_table= TRUE; pulled_tables |= tbl->table->map; DBUG_PRINT("info", ("Table %s pulled out (reason: func dep)", - tbl->table->alias)); + tbl->table->alias.c_ptr())); /* Pulling a table out of uncorrelated subquery in general makes makes it correlated. See the NOTE to this funtion. @@ -2605,7 +2605,8 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd, thd->mem_root= &table->mem_root; table->field=reg_field; - table->alias= "weedout-tmp"; + table->alias.set("weedout-tmp", sizeof("weedout-tmp")-1, + table_alias_charset); table->reginfo.lock_type=TL_WRITE; /* Will be updated */ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->map=1; @@ -2737,7 +2738,7 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd, else recinfo->type=FIELD_NORMAL; - field->table_name= &table->alias; + field->set_table_name(&table->alias); } //param->recinfo=recinfo; diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 1e4e87ebac7..be1471b7e2c 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -1783,7 +1783,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl) JOIN_TAB *tab= tbl->table->reginfo.join_tab; if (!(join->const_table_map & tab->table->map)) { - DBUG_PRINT("info", ("Eliminated table %s", table->alias)); + DBUG_PRINT("info", ("Eliminated table %s", table->alias.c_ptr())); tab->type= JT_CONST; join->eliminated_tables |= table->map; join->const_table_map|= table->map; @@ -1818,7 +1818,7 @@ void Dep_analysis_context::dbug_print_deps() fprintf(DBUG_FILE, " equality%ld: %s -> %s.%s\n", (long)(eq_mod - equality_mods), str.c_ptr(), - eq_mod->field->table->table->alias, + eq_mod->field->table->table->alias.c_ptr(), eq_mod->field->field->field_name); } else @@ -1836,12 +1836,13 @@ void Dep_analysis_context::dbug_print_deps() if ((table_dep= table_deps[i])) { /* Print table */ - fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias); + fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias.c_ptr()); /* Print fields */ for (Dep_value_field *field_dep= table_dep->fields; field_dep; field_dep= field_dep->next_table_field) { - fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias, + fprintf(DBUG_FILE, " field %s.%s ->", + table_dep->table->alias.c_ptr(), field_dep->field->field_name); uint ofs= field_dep->bitmap_offset; for (uint bit= ofs; bit < ofs + n_equality_mods; bit++) diff --git a/sql/protocol.cc b/sql/protocol.cc index 8a9d712077d..70b171fa652 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -632,6 +632,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags) uint count= 0; #endif + /* We have to reallocate it here as a stored procedure may have reset it */ + (void) local_packet->alloc(thd->variables.net_buffer_length); + while ((item=it++)) { char *pos; diff --git a/sql/set_var.cc b/sql/set_var.cc index 7e00ae5aa19..193b47704c6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -990,7 +990,7 @@ bool sys_var_str::check(THD *thd, set_var *var) if ((res=(*check_func)(thd, var)) < 0) my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), - name, var->value->str_value.ptr()); + name, var->value->str_value.c_ptr()); return res; } @@ -2281,11 +2281,15 @@ bool sys_var_character_set::check(THD *thd, set_var *var) } tmp= NULL; } - else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && - !(tmp=get_old_charset_by_name(res->c_ptr()))) + else { - my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); - return 1; + const char *name= res->c_ptr_safe(); + if (!(tmp=get_charset_by_csname(name,MY_CS_PRIMARY,MYF(0))) && + !(tmp=get_old_charset_by_name(name))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); + return 1; + } } } else // INT_RESULT @@ -2622,7 +2626,7 @@ static int sys_check_log_path(THD *thd, set_var *var) if (!(res= var->value->val_str(&str))) goto err; - log_file_str= res->c_ptr(); + log_file_str= res->c_ptr_safe(); bzero(&f_stat, sizeof(MY_STAT)); path_length= unpack_filename(path, log_file_str); @@ -3085,7 +3089,7 @@ bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var) my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL"); return 1; } - const char *locale_str= res->c_ptr(); + const char *locale_str= res->c_ptr_safe(); if (!(locale_match= my_locale_by_name(locale_str))) { my_printf_error(ER_UNKNOWN_ERROR, @@ -4117,7 +4121,7 @@ bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var) optimizer_switch_typelib.count, thd->variables.optimizer_switch, global_system_variables.optimizer_switch, - res->c_ptr_safe(), res->length(), NULL, + res->ptr(), res->length(), NULL, &error, &error_len, ¬_used); if (error_len) { diff --git a/sql/sp.cc b/sql/sp.cc index ebf2b3c360d..d2c732c2100 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -785,7 +785,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, { Parser_state parser_state; - if (parser_state.init(thd, defstr.c_ptr(), defstr.length())) + if (parser_state.init(thd, defstr.c_ptr_safe(), defstr.length())) { ret= SP_INTERNAL_ERROR; goto end; @@ -1104,7 +1104,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) (sp->m_explicit_name ? sp->m_db.length : 0), sp->m_name.str, sp->m_name.length, sp->m_params.str, sp->m_params.length, - retstr.c_ptr(), retstr.length(), + retstr.ptr(), retstr.length(), sp->m_body.str, sp->m_body.length, sp->m_chistics, &(thd->lex->definer->user), &(thd->lex->definer->host))) @@ -1116,7 +1116,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) thd->variables.sql_mode= saved_mode; /* Such a statement can always go directly to binlog, no trans cache */ if (thd->binlog_query(THD::MYSQL_QUERY_TYPE, - log_query.c_ptr(), log_query.length(), + log_query.ptr(), log_query.length(), FALSE, FALSE, 0)) ret= SP_INTERNAL_ERROR; thd->variables.sql_mode= 0; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index be8f705a53e..686e1a1346f 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -118,7 +118,7 @@ sp_rcontext::init_var_table(THD *thd) return TRUE; m_var_table->copy_blobs= TRUE; - m_var_table->alias= ""; + m_var_table->alias.set("", 0, table_alias_charset); return FALSE; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e14c8961165..2ae6147a033 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1474,12 +1474,11 @@ void close_temporary_tables(THD *thd) /* Better add "if exists", in case a RESET MASTER has been done */ const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS "; - uint stub_len= sizeof(stub) - 1; - char buf[256]; - String s_query= String(buf, sizeof(buf), system_charset_info); + char buf[FN_REFLEN]; + String s_query(buf, sizeof(buf), system_charset_info); bool found_user_tables= FALSE; - memcpy(buf, stub, stub_len); + s_query.copy(stub, sizeof(stub)-1, system_charset_info); /* Insertion sort of temp tables by pseudo_thread_id to build ordered list @@ -1533,19 +1532,24 @@ void close_temporary_tables(THD *thd) { bool save_thread_specific_used= thd->thread_specific_used; my_thread_id save_pseudo_thread_id= thd->variables.pseudo_thread_id; + char db_buf[FN_REFLEN]; + String db(db_buf, sizeof(db_buf), system_charset_info); + /* Set pseudo_thread_id to be that of the processed table */ thd->variables.pseudo_thread_id= tmpkeyval(thd, table); - String db; - db.append(table->s->db.str); + + db.copy(table->s->db.str, table->s->db.length, system_charset_info); + s_query.length(sizeof(stub)-1); + /* Loop forward through all tables that belong to a common database within the sublist of common pseudo_thread_id to create single DROP query */ - for (s_query.length(stub_len); + for (; table && is_user_table(table) && tmpkeyval(thd, table) == thd->variables.pseudo_thread_id && table->s->db.length == db.length() && - strcmp(table->s->db.str, db.ptr()) == 0; + memcmp(table->s->db.str, db.ptr(), db.length()) == 0; table= next) { /* @@ -1849,7 +1853,7 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list) /* Table might be in use by some outer statement. */ if (table->query_id && table->query_id != thd->query_id) { - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); DBUG_RETURN(-1); } @@ -1872,7 +1876,7 @@ void close_temporary_table(THD *thd, TABLE *table, DBUG_ENTER("close_temporary_table"); DBUG_PRINT("tmptable", ("closing table: '%s'.'%s' 0x%lx alias: '%s'", table->s->db.str, table->s->table_name.str, - (long) table, table->alias)); + (long) table, table->alias.c_ptr())); /* When closing a MERGE parent or child table, detach the children @@ -2606,7 +2610,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ("query_id: %lu server_id: %u pseudo_thread_id: %lu", (ulong) table->query_id, (uint) thd->server_id, (ulong) thd->variables.pseudo_thread_id)); - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); DBUG_RETURN(0); } table->query_id= thd->query_id; @@ -2643,7 +2647,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, When looking for a usable TABLE, ignore MERGE children, as they belong to their parent and cannot be used explicitly. */ - if (!my_strcasecmp(system_charset_info, table->alias, alias) && + if (!my_strcasecmp(system_charset_info, table->alias.c_ptr(), alias) && table->query_id != thd->query_id && /* skip tables already used */ !(thd->prelocked_mode && table->query_id) && !table->parent) @@ -2999,13 +3003,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->alias_name_used= my_strcasecmp(table_alias_charset, table->s->table_name.str, alias); /* Fix alias if table name changes */ - if (strcmp(table->alias, alias)) - { - uint length=(uint) strlen(alias)+1; - table->alias= (char*) my_realloc((char*) table->alias, length, - MYF(MY_WME)); - memcpy((char*) table->alias, alias, length); - } + if (strcmp(table->alias.c_ptr(), alias)) + table->alias.copy(alias, strlen(alias), table->alias.charset()); + /* These variables are also set in reopen_table() */ table->tablenr=thd->current_tablenr++; table->used_fields=0; @@ -3026,13 +3026,19 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->pos_in_table_list= table_list; table_list->updatable= 1; // It is not derived table nor non-updatable VIEW table->clear_column_bitmaps(); -#if !defined(DBUG_OFF) && !defined(HAVE_valgrind) /* Fill record with random values to find bugs where we access fields without first reading them. */ - bfill(table->record[0], table->s->reclength, 254); -#endif + TRASH(table->record[0], table->s->reclength); + /* + Initialize the null marker bits, to ensure that if we are doing a read + of only selected columns (like in keyread), all null markers are + initialized. + */ + bfill(table->record[0], table->s->null_bytes, 255); + bfill(table->record[1], table->s->null_bytes, 255); + DBUG_ASSERT(table->key_read == 0); DBUG_RETURN(table); } @@ -3089,7 +3095,7 @@ bool reopen_table(TABLE *table) #ifdef EXTRA_DEBUG if (table->db_stat) sql_print_error("Table %s had a open data handler in reopen_table", - table->alias); + table->alias.c_ptr()); #endif bzero((char*) &table_list, sizeof(TABLE_LIST)); table_list.db= table->s->db.str; @@ -3100,7 +3106,7 @@ bool reopen_table(TABLE *table) DBUG_RETURN(1); // Thread was killed if (open_unireg_entry(thd, &tmp, &table_list, - table->alias, + table->alias.c_ptr(), table->s->table_cache_key.str, table->s->table_cache_key.length, thd->mem_root, 0)) @@ -3141,14 +3147,14 @@ bool reopen_table(TABLE *table) VOID(closefrm(table, 1)); // close file, free everything *table= tmp; + table->alias.move(tmp.alias); table->default_column_bitmaps(); table->file->change_table_ptr(table, table->s); - DBUG_ASSERT(table->alias != 0); + DBUG_ASSERT(table->alias.ptr() != 0); for (field=table->field ; *field ; field++) { - (*field)->table= (*field)->orig_table= table; - (*field)->table_name= &table->alias; + (*field)->init(table); } for (key=0 ; key < table->s->keys ; key++) { @@ -3275,7 +3281,7 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p) DBUG_PRINT("tcache", ("MERGE parent, attach children")); if(table->file->extra(HA_EXTRA_ATTACH_CHILDREN)) { - my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias.c_ptr()); error= TRUE; /* Remove table from open_tables. */ *prv_p= next; @@ -3368,7 +3374,8 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) if (!tables || (!db_stat && reopen_table(table))) { my_error(ER_CANT_REOPEN_TABLE, MYF(0), - table->alias ? table->alias : table->s->table_name.str); + table->alias.ptr() ? table->alias.c_ptr() : + table->s->table_name.str); /* If we could not allocate 'tables', we may close open tables here. If a MERGE table is affected, detach the children first. @@ -3565,7 +3572,8 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) char *key= table->s->table_cache_key.str; uint key_length= table->s->table_cache_key.length; - DBUG_PRINT("loop", ("table_name: %s", table->alias ? table->alias : "")); + DBUG_PRINT("loop", ("table_name: %s", + table->alias.ptr() ? table->alias.c_ptr() : "")); HASH_SEARCH_STATE state; for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, &state); @@ -4359,7 +4367,7 @@ void detach_merge_children(TABLE *table, bool clear_refs) Set alias to "" to ensure that table is not used if we are in LOCK TABLES */ - ((char*) child_l->table->alias)[0]= 0; + child_l->table->alias.copy("", 0, child_l->table->alias.charset()); /* Clear the table reference to force new assignment at next open. */ child_l->table= NULL; @@ -4912,7 +4920,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) { - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias); + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias.c_ptr()); DBUG_RETURN(1); } if ((error=table->file->start_stmt(thd, lock_type))) @@ -6024,7 +6032,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length, Field **field_ptr, *field; uint cached_field_index= *cached_field_index_ptr; DBUG_ENTER("find_field_in_table"); - DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name)); + DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias.c_ptr(), + name)); /* We assume here that table->field < NO_CACHED_FIELD_INDEX = UINT_MAX */ if (cached_field_index < table->s->fields && diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 15c8e33f73e..a832deccd57 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2363,7 +2363,6 @@ bool select_export::send_data(List<Item> &items) { // Fill with space if (item->max_length > used_length) { - /* QQ: Fix by adding a my_b_fill() function */ if (!space_inited) { space_inited=1; @@ -4122,8 +4121,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, int errcode) { DBUG_ENTER("THD::binlog_query"); - DBUG_PRINT("enter", ("qtype: %s query: '%s'", - show_query_type(qtype), query_arg)); + DBUG_PRINT("enter", ("qtype: %s query: '%-.*s'", + show_query_type(qtype), (int) query_len, query_arg)); DBUG_ASSERT(query_arg && mysql_bin_log.is_open()); /* @@ -4159,7 +4158,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, { sql_print_warning("%s Statement: %.*s", ER(ER_BINLOG_UNSAFE_STATEMENT), - MYSQL_ERRMSG_SIZE, query_arg); + (int) min(MYSQL_ERRMSG_SIZE, query_len), query_arg); binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED; } } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3c2f90e8080..7267d73a29c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -622,8 +622,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* We can't write-delayed into a table locked with LOCK TABLES: this will lead to a deadlock, since the delayed thread will - never be able to get a lock on the table. QQQ: why not - upgrade the lock here instead? + never be able to get a lock on the table. */ if (table_list->lock_type == TL_WRITE_DELAYED && thd->locked_tables && find_locked_table(thd, table_list->db, table_list->table_name)) @@ -808,7 +807,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, be overwritten by fill_record() anyway (and fill_record() does not use default values in this case). */ - table->record[0][0]= share->default_values[0]; +#ifdef HAVE_valgrind + if (table->file->ha_table_flags() && HA_RECORD_MUST_BE_CLEAN_ON_WRITE) + restore_record(table,s->default_values); // Get empty record + else +#endif + table->record[0][0]= share->default_values[0]; /* Fix undefined null_bits. */ if (share->null_bytes > 1 && share->last_null_bit_pos) @@ -2074,6 +2078,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) TABLE *copy; TABLE_SHARE *share; uchar *bitmap; + char *copy_tmp; DBUG_ENTER("Delayed_insert::get_local_table"); /* First request insert thread to get a lock */ @@ -2106,14 +2111,15 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) the other record buffers and alignment are unnecessary. */ thd_proc_info(client_thd, "allocating local table"); - copy= (TABLE*) client_thd->alloc(sizeof(*copy)+ - (share->fields+1)*sizeof(Field**)+ - share->reclength + - share->column_bitmap_size*3); - if (!copy) + copy_tmp= (char*) client_thd->alloc(sizeof(*copy)+ + (share->fields+1)*sizeof(Field**)+ + share->reclength + + share->column_bitmap_size*3); + if (!copy_tmp) goto error; /* Copy the TABLE object. */ + copy= new (copy_tmp) TABLE; *copy= *table; /* We don't need to change the file handler here */ /* Assign the pointers for the field pointers array and the record. */ @@ -3502,7 +3508,7 @@ int select_create::write_to_binlog(bool is_trans, int errcode) Avoid to use thd->binlog_query() twice, otherwise it will print the unsafe warning twice. */ - Query_log_event ev(thd, query.c_ptr_safe(), query.length(), is_trans, + Query_log_event ev(thd, query.ptr(), query.length(), is_trans, FALSE, errcode); return mysql_bin_log.write(&ev); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 366c01b1754..48574811f54 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -604,11 +604,15 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, size_t pl= 0; List<Item> fv; Item *item, *val; - String pfield, pfields; int n; const char *tbl= table_name_arg; const char *tdb= (thd->db != NULL ? thd->db : db_arg); - String string_buf; + char name_buffer[SAFE_NAME_LEN*2]; + char command_buffer[1024]; + String string_buf(name_buffer, sizeof(name_buffer), + system_charset_info); + String pfields(command_buffer, sizeof(command_buffer), + system_charset_info); if (!thd->db || strcmp(db_arg, thd->db)) { @@ -617,7 +621,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, prefix table name with database name so that it becomes a FQ name. */ - string_buf.set_charset(system_charset_info); + string_buf.length(0); string_buf.append(db_arg); string_buf.append("`"); string_buf.append("."); @@ -638,6 +642,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, /* prepare fields-list and SET if needed; print_query won't do that for us. */ + pfields.length(0); if (!thd->lex->field_list.is_empty()) { List_iterator<Item> li(thd->lex->field_list); @@ -682,8 +687,8 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, } } - p= pfields.c_ptr_safe(); - pl= strlen(p); + p= pfields.c_ptr_safe(); + pl= pfields.length(); if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl))) return TRUE; @@ -970,7 +975,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP) ((Field_timestamp*) field)->set_time(); /* - QQ: We probably should not throw warning for each field. + TODO: We probably should not throw warning for each field. But how about intention to always have the same number of warnings in THD::cuted_fields (and get rid of cuted_fields in the end ?) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 90ebfb8a223..3887321f006 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1350,54 +1350,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, error=TRUE; // End server break; -#ifdef REMOVED - case COM_CREATE_DB: // QQ: To be removed - { - LEX_STRING db, alias; - HA_CREATE_INFO create_info; - - status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]); - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - thd->make_lex_string(&alias, db.str, db.length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0, - is_schema_db(db.str, db.length))) - break; - general_log_print(thd, command, "%.*s", db.length, db.str); - bzero(&create_info, sizeof(create_info)); - mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str), - &create_info, 0); - break; - } - case COM_DROP_DB: // QQ: To be removed - { - status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]); - LEX_STRING db; - - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, - is_schema_db(db.str, db.length))) - break; - if (thd->locked_tables || thd->active_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - break; - } - general_log_write(thd, command, "%.*s", db.length, db.str); - mysql_rm_db(thd, db.str, 0, 0); - break; - } -#endif #ifndef EMBEDDED_LIBRARY case COM_BINLOG_DUMP: { @@ -5084,9 +5036,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); thd->lex->unit.print(&str, QT_ORDINARY); - str.append('\0'); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_YES, str.ptr()); + ER_YES, str.c_ptr_safe()); } if (res) result->abort(); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index dd908e1b60e..58cc7dc93a9 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -303,7 +303,7 @@ static const char *item_val_str(struct st_mysql_value *value, Lets be nice and create a temporary string since the buffer was too small */ - return current_thd->strmake(res->c_ptr_quick(), res->length()); + return current_thd->strmake(res->ptr(), res->length()); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b4cf6a959ec..310774a49e8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2953,7 +2953,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, { start_keyuse=keyuse; key=keyuse->key; - s->keys.set_bit(key); // QQ: remove this ? + s->keys.set_bit(key); // TODO: remove this ? refs=0; const_ref.clear_all(); @@ -3900,6 +3900,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) keyuse.keypart_map= (key_part_map) 1 << part; keyuse.used_tables=key_field->val->used_tables(); keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL; + keyuse.ref_table_rows= 0; keyuse.null_rejecting= key_field->null_rejecting; keyuse.cond_guard= key_field->cond_guard; keyuse.sj_pred_no= key_field->sj_pred_no; @@ -6343,8 +6344,8 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) join_tab->table=temp_table; join_tab->cache_select= 0; join_tab->select=0; + join_tab->select_cond= 0; // Avoid valgrind warning join_tab->set_select_cond(NULL, __LINE__); - join_tab->select_cond=0; join_tab->quick=0; join_tab->type= JT_ALL; /* Map through all records */ join_tab->keys.init(); @@ -6477,7 +6478,7 @@ static void add_not_null_conds(JOIN *join) if (notnull->fix_fields(join->thd, ¬null)) DBUG_VOID_RETURN; DBUG_EXECUTE("where",print_where(notnull, - referred_tab->table->alias, + referred_tab->table->alias.c_ptr(), QT_ORDINARY);); COND *new_cond= referred_tab->select_cond; add_cond_and_fix(&new_cond, notnull); @@ -6786,7 +6787,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tmp || !cond || tab->type == JT_REF || tab->type == JT_REF_OR_NULL || tab->type == JT_EQ_REF || first_inner_tab) { - DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY);); + DBUG_EXECUTE("where", + print_where(tmp,tab->table->alias.c_ptr(), + QT_ORDINARY);); SQL_SELECT *sel= tab->select= ((SQL_SELECT*) thd->memdup((uchar*) select, sizeof(*select))); @@ -6830,7 +6833,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } sel->head=tab->table; - DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY);); + DBUG_EXECUTE("where", + print_where(tmp,tab->table->alias.c_ptr(), + QT_ORDINARY);); if (tab->quick) { /* Use quick key read if it's a constant and it's not used @@ -11289,7 +11294,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, thd->mem_root= &table->mem_root; table->field=reg_field; - table->alias= table_alias; + table->alias.set(table_alias, strlen(table_alias), table_alias_charset); + table->reginfo.lock_type=TL_WRITE; /* Will be updated */ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->map=1; @@ -11665,7 +11671,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, null_count=(null_count+7) & ~7; // move to next byte // fix table name in field entry - field->table_name= &table->alias; + field->set_table_name(&table->alias); } param->copy_field_end=copy; @@ -12482,7 +12488,7 @@ free_tmp_table(THD *thd, TABLE *entry) MEM_ROOT own_root= entry->mem_root; const char *save_proc_info; DBUG_ENTER("free_tmp_table"); - DBUG_PRINT("enter",("table: %s",entry->alias)); + DBUG_PRINT("enter",("table: %s",entry->alias.c_ptr())); save_proc_info=thd->proc_info; thd_proc_info(thd, "removing tmp table"); @@ -17497,6 +17503,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, char buff[256]; String str(buff,sizeof(buff),&my_charset_bin); str.length(0); + str.extra_allocation(1024); item->print(&str, QT_ORDINARY); item_field->name= sql_strmake(str.ptr(),str.length()); } @@ -19187,7 +19194,8 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) { - /* QQ: thd may not be set for sub queries, but this should be fixed */ + /* TODO: thd may not be set for sub queries, but this should be fixed */ + DBUG_ASSERT(thd); if (!thd) thd= current_thd; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fd0666f730f..cdfb982b372 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -816,7 +816,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) protocol->store(table_list->schema_table->table_name, system_charset_info); else - protocol->store(table_list->table->alias, system_charset_info); + protocol->store(table_list->table->alias.c_ptr(), system_charset_info); } if (table_list->view) @@ -1305,7 +1305,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, else { if (lower_case_table_names == 2) - alias= table->alias; + alias= table->alias.c_ptr(); else { alias= share->table_name.str; @@ -4330,7 +4330,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, base_type [(dimension)] [unsigned] [zerofill]. For DATA_TYPE column we extract only base type. */ - tmp_buff= strchr(type.ptr(), '('); + tmp_buff= strchr(type.c_ptr_safe(), '('); if (!tmp_buff) /* if there is no dimention part then check the presence of @@ -5662,7 +5662,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) if (et.load_from_row(thd, event_table)) { - my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias); + my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias.c_ptr()); DBUG_RETURN(1); } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index eafd8502706..b359b2a7168 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -411,7 +411,7 @@ bool String::append(const String &s) { if (s.length()) { - if (realloc(str_length+s.length())) + if (realloc_with_extra_if_needed(str_length+s.length())) return TRUE; memcpy(Ptr+str_length,s.ptr(),s.length()); str_length+=s.length(); @@ -436,7 +436,7 @@ bool String::append(const char *s,uint32 arg_length) { uint32 add_length=arg_length * str_charset->mbmaxlen; uint dummy_errors; - if (realloc(str_length+ add_length)) + if (realloc_with_extra_if_needed(str_length+ add_length)) return TRUE; str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, s, arg_length, &my_charset_latin1, @@ -447,7 +447,7 @@ bool String::append(const char *s,uint32 arg_length) /* For an ASCII compatinble string we can just append. */ - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; memcpy(Ptr+str_length,s,arg_length); str_length+=arg_length; @@ -478,14 +478,14 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) { uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen; uint dummy_errors; - if (realloc(str_length + add_length)) + if (realloc_with_extra_if_needed(str_length + add_length)) return TRUE; str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, s, arg_length, cs, &dummy_errors); } else { - if (realloc(str_length + arg_length)) + if (realloc_with_extra_if_needed(str_length + arg_length)) return TRUE; memcpy(Ptr + str_length, s, arg_length); str_length+= arg_length; @@ -497,7 +497,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) #ifdef TO_BE_REMOVED bool String::append(FILE* file, uint32 arg_length, myf my_flags) { - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; if (my_fread(file, (uchar*) Ptr + str_length, arg_length, my_flags)) { @@ -511,7 +511,7 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags) bool String::append(IO_CACHE* file, uint32 arg_length) { - if (realloc(str_length+arg_length)) + if (realloc_with_extra_if_needed(str_length+arg_length)) return TRUE; if (my_b_read(file, (uchar*) Ptr + str_length, arg_length)) { @@ -527,7 +527,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length, { int t_length= arg_length > full_length ? arg_length : full_length; - if (realloc(str_length + t_length)) + if (realloc_with_extra_if_needed(str_length + t_length)) return TRUE; t_length= full_length - arg_length; if (t_length > 0) @@ -636,7 +636,7 @@ bool String::replace(uint32 offset,uint32 arg_length, { if (diff) { - if (realloc(str_length+(uint32) diff)) + if (realloc_with_extra_if_needed(str_length+(uint32) diff)) return TRUE; bmove_upp((uchar*) Ptr+str_length+diff, (uchar*) Ptr+str_length, str_length-offset-arg_length); diff --git a/sql/sql_string.h b/sql/sql_string.h index e595de47f99..b154f0c1667 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -53,23 +53,24 @@ uint convert_to_printable(char *to, size_t to_len, class String { char *Ptr; - uint32 str_length,Alloced_length; + uint32 str_length,Alloced_length, extra_alloc; bool alloced; CHARSET_INFO *str_charset; public: String() { - Ptr=0; str_length=Alloced_length=0; alloced=0; + Ptr=0; str_length=Alloced_length=extra_alloc=0; alloced=0; str_charset= &my_charset_bin; } String(uint32 length_arg) { - alloced=0; Alloced_length=0; (void) real_alloc(length_arg); + alloced=0; Alloced_length= extra_alloc= 0; (void) real_alloc(length_arg); str_charset= &my_charset_bin; } String(const char *str, CHARSET_INFO *cs) { - Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; + Ptr=(char*) str; str_length= (uint32) strlen(str); + Alloced_length= extra_alloc= 0; alloced=0; str_charset=cs; } /* @@ -79,18 +80,18 @@ public: */ String(const char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; + Ptr=(char*) str; str_length=len; Alloced_length= extra_alloc=0; alloced=0; str_charset=cs; } String(char *str,uint32 len, CHARSET_INFO *cs) { - Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; + Ptr=(char*) str; Alloced_length=str_length=len; extra_alloc= 0; alloced=0; str_charset=cs; } String(const String &str) { Ptr=str.Ptr ; str_length=str.str_length ; - Alloced_length=str.Alloced_length; alloced=0; + Alloced_length=str.Alloced_length; extra_alloc= 0; alloced=0; str_charset=str.str_charset; } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () @@ -106,8 +107,10 @@ public: inline CHARSET_INFO *charset() const { return str_charset; } inline uint32 length() const { return str_length;} inline uint32 alloced_length() const { return Alloced_length;} + inline uint32 extra_allocation() const { return extra_alloc;} inline char& operator [] (uint32 i) const { return Ptr[i]; } inline void length(uint32 len) { str_length=len ; } + inline void extra_allocation(uint32 len) { extra_alloc= len; } inline bool is_empty() const { return (str_length == 0); } inline void mark_as_const() { Alloced_length= 0;} inline const char *ptr() const { return Ptr; } @@ -136,23 +139,21 @@ public: { DBUG_ASSERT(&str != this); free(); - Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0; + Ptr=(char*) str.ptr()+offset; str_length=arg_length; if (str.Alloced_length) Alloced_length=str.Alloced_length-offset; - else - Alloced_length=0; str_charset=str.str_charset; } inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); - Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; + Ptr=(char*) str; str_length=Alloced_length=arg_length; str_charset=cs; } inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); - Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; + Ptr=(char*) str; str_length=arg_length; str_charset=cs; } bool set_ascii(const char *str, uint32 arg_length); @@ -203,11 +204,11 @@ public: if (alloced) { alloced=0; - Alloced_length=0; my_free(Ptr,MYF(0)); - Ptr=0; - str_length=0; /* Safety */ } + Alloced_length= extra_alloc= 0; + Ptr=0; + str_length=0; /* Safety */ } inline bool alloc(uint32 arg_length) { @@ -217,9 +218,21 @@ public: } bool real_alloc(uint32 arg_length); // Empties old string bool realloc(uint32 arg_length); - inline void shrink(uint32 arg_length) // Shrink buffer + bool realloc_with_extra(uint32 arg_length) + { + if (extra_alloc < 4096) + extra_alloc= extra_alloc*2+128; + return realloc(arg_length + extra_alloc); + } + bool realloc_with_extra_if_needed(uint32 arg_length) { if (arg_length < Alloced_length) + return 0; + return realloc_with_extra(arg_length); + } + inline void shrink(uint32 arg_length) // Shrink buffer + { + if (ALIGN_SIZE(arg_length+1) < Alloced_length) { char *new_ptr; if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,MYF(0)))) @@ -246,7 +259,6 @@ public: DBUG_ASSERT(!s.uses_buffer_owned_by(this)); free(); Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; - alloced=0; } return *this; } @@ -262,6 +274,14 @@ public: bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto, uint *errors); + void move(String &s) + { + free(); + Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; + extra_alloc= s.extra_alloc; + alloced= s.alloced; + s.alloced= 0; + } bool append(const String &s); bool append(const char *s); bool append(const char *s,uint32 arg_length); @@ -281,7 +301,7 @@ public: } else { - if (realloc(str_length+1)) + if (realloc_with_extra(str_length + 1)) return 1; Ptr[str_length++]=chr; } @@ -292,6 +312,7 @@ public: friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); + friend class Field; uint32 numchars(); int charpos(int i,uint32 offset=0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0ef18a237dd..13b2ea3ae98 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2113,7 +2113,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { if (!foreign_key_error) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - wrong_tables.c_ptr()); + wrong_tables.c_ptr_safe()); else my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; @@ -6955,7 +6955,7 @@ view_err: error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias); + table->alias.c_ptr()); } VOID(pthread_mutex_lock(&LOCK_open)); @@ -7023,7 +7023,7 @@ view_err: error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias); + table->alias.c_ptr()); } if (!error) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 401a413b2dc..5bf9cd1f77e 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -57,14 +57,15 @@ print_where(COND *cond,const char *info, enum_query_type query_type) { if (cond) { - char buff[256]; + char buff[1024]; String str(buff,(uint32) sizeof(buff), system_charset_info); str.length(0); + str.extra_allocation(1024); cond->print(&str, query_type); str.append('\0'); DBUG_LOCK_FILE; (void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info); - (void) fputs(str.ptr(),DBUG_FILE); + (void) fputs(str.c_ptr_safe(),DBUG_FILE); (void) fputc('\n',DBUG_FILE); DBUG_UNLOCK_FILE; } @@ -156,7 +157,7 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length) out.append('\0'); // Purify doesn't like c_ptr() DBUG_LOCK_FILE; VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE)); - fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr()); + fprintf(DBUG_FILE,"Sortorder: %s\n",out.c_ptr_safe()); DBUG_UNLOCK_FILE; DBUG_VOID_RETURN; } @@ -191,7 +192,7 @@ TEST_join(JOIN *join) TABLE *form=tab->table; char key_map_buff[128]; fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n", - form->alias, + form->alias.c_ptr(), join_type_str[tab->type], tab->keys.print(key_map_buff), tab->ref.key_parts, @@ -215,7 +216,7 @@ TEST_join(JOIN *join) if (tab->ref.key_parts) { fprintf(DBUG_FILE, - " refs: %s\n", ref_key_parts[i].ptr()); + " refs: %s\n", ref_key_parts[i].c_ptr_safe()); } } DBUG_UNLOCK_FILE; @@ -240,11 +241,11 @@ void print_keyuse(KEYUSE *keyuse) fieldname= keyuse->table->key_info[keyuse->key].key_part[keyuse->keypart].field->field_name; longlong2str(keyuse->used_tables, buf2, 16, 0); DBUG_LOCK_FILE; - fprintf(DBUG_FILE, "KEYUSE: %s.%s=%s optimize= %d used_tables=%s " - "ref_table_rows= %lu keypart_map= %0lx\n", - keyuse->table->alias, fieldname, str.ptr(), - keyuse->optimize, buf2, (ulong)keyuse->ref_table_rows, - keyuse->keypart_map); + fprintf(DBUG_FILE, "KEYUSE: %s.%s=%s optimize: %u used_tables: %s " + "ref_table_rows: %lu keypart_map: %0lx\n", + keyuse->table->alias.c_ptr(), fieldname, str.ptr(), + (uint) keyuse->optimize, buf2, (ulong) keyuse->ref_table_rows, + (ulong) keyuse->keypart_map); DBUG_UNLOCK_FILE; //key_part_map keypart_map; --?? there can be several? } @@ -370,7 +371,7 @@ void print_sjm(SJ_MATERIALIZATION_INFO *sjm) for (uint i= 0;i < sjm->tables; i++) { fprintf(DBUG_FILE, " %s%s\n", - sjm->positions[i].table->table->alias, + sjm->positions[i].table->table->alias.c_ptr(), (i == sjm->tables -1)? "": ","); } fprintf(DBUG_FILE, " }\n"); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index f6864add19f..d1e974a2c04 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -802,7 +802,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, stmt_query->append(stmt_definition.str, stmt_definition.length); - trg_def->str= stmt_query->c_ptr(); + trg_def->str= stmt_query->c_ptr_safe(); trg_def->length= stmt_query->length(); /* Create trigger definition file. */ @@ -1039,10 +1039,7 @@ void Table_triggers_list::set_table(TABLE *new_table) { trigger_table= new_table; for (Field **field= new_table->triggers->record1_field ; *field ; field++) - { - (*field)->table= (*field)->orig_table= new_table; - (*field)->table_name= &new_table->alias; - } + (*field)->init(new_table); } diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index f6754a75284..08125f94b43 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -17,7 +17,7 @@ /** This class holds all information about triggers of table. - QQ: Will it be merged into TABLE in the future ? + TODO: Will it be merged into TABLE in the future ? */ class Table_triggers_list: public Sql_alloc diff --git a/sql/sql_update.cc b/sql/sql_update.cc index aa803d6e0dd..ec91f2c64fc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1602,7 +1602,8 @@ loop_end: do { Field_string *field= new Field_string(tbl->file->ref_length, 0, - tbl->alias, &my_charset_bin); + tbl->alias.c_ptr(), + &my_charset_bin); if (!field) DBUG_RETURN(1); field->init(tbl); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 204100f6034..8b8b7f5c90e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -848,7 +848,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, thd->variables.sql_mode|= sql_mode; } - DBUG_PRINT("info", ("View: %s", view_query.ptr())); + DBUG_PRINT("info", ("View: %s", view_query.c_ptr_safe())); /* fill structure */ view->source= thd->lex->create_view_select; @@ -1675,7 +1675,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) } if (non_existant_views.length()) { - my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); + my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr_safe()); } something_wrong= error || wrong_object_name || non_existant_views.length(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 87a8dd278c2..e8890dde6cb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -13111,7 +13111,7 @@ column_list_id: while ((point=iter++)) { if (!my_strcasecmp(system_charset_info, - point->column.ptr(), new_str->ptr())) + point->column.c_ptr(), new_str->c_ptr())) break; } lex->grant_tot_col|= lex->which_columns; diff --git a/sql/table.cc b/sql/table.cc index 1711fe8c426..17cd9c8dc34 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2085,7 +2085,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); - if (!(outparam->alias= my_strdup(alias, MYF(MY_WME)))) + if (outparam->alias.copy(alias, strlen(alias), table_alias_charset)) goto err; outparam->quick_keys.init(); outparam->covering_keys.init(); @@ -2422,7 +2422,7 @@ partititon_err: outparam->db_stat=0; thd->lex->view_prepare_mode= save_view_prepare_mode; free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root - my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); + outparam->alias.free(); DBUG_RETURN (error); } @@ -2448,8 +2448,7 @@ int closefrm(register TABLE *table, bool free_share) table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); error=table->file->close(); } - my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR)); - table->alias= 0; + table->alias.free(); if (table->expr_arena) table->expr_arena->free_items(); if (table->field) @@ -2926,7 +2925,7 @@ File create_frm(THD *thd, const char *name, const char *db, if (create_info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= O_EXCL | O_NOFOLLOW; - /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */ + /* Fix this when we have new .frm files; Current limit is 4G rows (TODO) */ if (create_info->max_rows > UINT_MAX32) create_info->max_rows= UINT_MAX32; if (create_info->min_rows > UINT_MAX32) @@ -3286,7 +3285,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) const TABLE_FIELD_TYPE *field_def= table_def->field; DBUG_ENTER("table_check_intact"); DBUG_PRINT("info",("table: %s expected_count: %d", - table->alias, table_def->count)); + table->alias.c_ptr(), table_def->count)); /* Whether the table definition has already been validated. */ if (table->s->table_field_def_cache == table_def) @@ -3301,14 +3300,15 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) { report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE), - table->alias, table_def->count, table->s->fields, + table->alias.c_ptr(), table_def->count, table->s->fields, table->s->mysql_version, MYSQL_VERSION_ID); DBUG_RETURN(TRUE); } else if (MYSQL_VERSION_ID == table->s->mysql_version) { report_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED, - ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias, + ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), + table->alias.c_ptr(), table_def->count, table->s->fields); DBUG_RETURN(TRUE); } @@ -3320,11 +3320,13 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) is backward compatible. */ } - char buffer[STRING_BUFFER_USUAL_SIZE]; + char buffer[1024]; for (i=0 ; i < table_def->count; i++, field_def++) { String sql_type(buffer, sizeof(buffer), system_charset_info); sql_type.length(0); + /* Allocate min 256 characters at once */ + sql_type.extra_allocation(256); if (i < table->s->fields) { Field *field= table->field[i]; @@ -3339,7 +3341,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) */ report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d, found '%s'.", - table->s->db.str, table->alias, field_def->name.str, i, + table->s->db.str, table->alias.c_ptr(), + field_def->name.str, i, field->field_name); } field->sql_type(sql_type); @@ -3365,7 +3368,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) { report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d to have type " - "%s, found type %s.", table->s->db.str, table->alias, + "%s, found type %s.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->type.str, sql_type.c_ptr_safe()); error= TRUE; @@ -3375,7 +3379,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected the type of column '%s' at position %d " "to have character set '%s' but the type has no " - "character set.", table->s->db.str, table->alias, + "character set.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->cset.str); error= TRUE; } @@ -3385,7 +3390,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected the type of column '%s' at position %d " "to have character set '%s' but found " - "character set '%s'.", table->s->db.str, table->alias, + "character set '%s'.", table->s->db.str, + table->alias.c_ptr(), field_def->name.str, i, field_def->cset.str, field->charset()->csname); error= TRUE; @@ -3396,7 +3402,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(0, "Incorrect definition of table %s.%s: " "expected column '%s' at position %d to have type %s " " but the column is not found.", - table->s->db.str, table->alias, + table->s->db.str, table->alias.c_ptr(), field_def->name.str, i, field_def->type.str); error= TRUE; } diff --git a/sql/table.h b/sql/table.h index 99b5601c307..ba037c27020 100644 --- a/sql/table.h +++ b/sql/table.h @@ -720,7 +720,7 @@ struct st_table { Table_triggers_list *triggers; TABLE_LIST *pos_in_table_list;/* Element referring to this table */ ORDER *group; - const char *alias; /* alias or table name */ + String alias; /* alias or table name */ uchar *null_flags; my_bitmap_map *bitmap_init_value; MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set; diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 2749034cba2..434423b78b3 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1453,7 +1453,8 @@ static void fill_server(MEM_ROOT *mem_root, FEDERATEDX_SERVER *server, key.q_append('\0'); server->password= (const char *) (intptr) key.length(); key.append(password); - + key.c_ptr_safe(); // Ensure we have end \0 + server->key_length= key.length(); server->key= (uchar *) memdup_root(mem_root, key.ptr(), key.length()+1); @@ -1583,7 +1584,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) tmp_share.table_name_length, ident_quote_char); if (!(share= (FEDERATEDX_SHARE *) memdup_root(&mem_root, (char*)&tmp_share, sizeof(*share))) || - !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length() + 1))) + !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length()))) goto error; share->mem_root= mem_root; @@ -3435,11 +3436,13 @@ bool ha_federatedx::get_error_message(int error, String* buf) buf->qs_append(remote_error_number); buf->append(STRING_WITH_LEN(": ")); buf->append(remote_error_buf); + /* Ensure string ends with \0 */ + (void) buf->c_ptr_safe(); remote_error_number= 0; remote_error_buf[0]= '\0'; } - DBUG_PRINT("exit", ("message: %s", buf->ptr())); + DBUG_PRINT("exit", ("message: %s", buf->c_ptr_safe())); DBUG_RETURN(FALSE); } diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 27958285a2e..b95a6766878 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1036,6 +1036,16 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked) if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) int_table_flags |= HA_HAS_NEW_CHECKSUM; + /* + For static size rows, tell MariaDB that we will access all bytes + in the record when writing it. This signals MariaDB to initalize + the full row to ensure we don't get any errors from valgrind and + that all bytes in the row is properly reset. + */ + if (file->s->data_file_type == STATIC_RECORD && + (file->s->has_varchar_fields | file->s->has_null_fields)) + int_table_flags|= HA_RECORD_MUST_BE_CLEAN_ON_WRITE; + for (i= 0; i < table->s->keys; i++) { plugin_ref parser= table->key_info[i].parser; @@ -1095,7 +1105,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) param.thd= thd; param.op_name= "check"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= check_opt->flags | T_CHECK | T_SILENT; param.stats_method= (enum_handler_stats_method)THDVAR(thd,stats_method); @@ -1194,7 +1204,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt) param.thd= thd; param.op_name= "analyze"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS | T_DONT_CHECK_CHECKSUM); param.using_global_keycache= 1; @@ -1488,7 +1498,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize) _ma_copy_nontrans_state_information(file); param->db_name= table->s->db.str; - param->table_name= table->alias; + param->table_name= table->alias.c_ptr(); param->tmpfile_createflag= O_RDWR | O_TRUNC; param->using_global_keycache= 1; param->thd= thd; diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 63e1801a39a..ae3a3918eee 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -763,6 +763,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->blobs[j].offset= share->columndef[i].offset; j++; } + if (share->columndef[i].type == FIELD_VARCHAR) + share->has_varchar_fields= 1; + if (share->columndef[i].null_bit) + share->has_null_fields= 1; } share->columndef[i].type= FIELD_LAST; /* End marker */ disk_pos= _ma_column_nr_read(disk_pos, share->column_nr, diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index ba97684b1aa..c39aeaabaa6 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -376,6 +376,8 @@ typedef struct st_maria_share my_bool temporary; /* Below flag is needed to make log tables work with concurrent insert */ my_bool is_log_table; + my_bool has_null_fields; + my_bool has_varchar_fields; /* If table has varchar fields */ my_bool changed, /* If changed since lock */ global_changed, /* If changed since open */ diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 368bb0bd4e3..d012ac053d8 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -745,6 +745,16 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) int_table_flags|= HA_HAS_OLD_CHECKSUM; } + /* + For static size rows, tell MariaDB that we will access all bytes + in the record when writing it. This signals MariaDB to initalize + the full row to ensure we don't get any errors from valgrind and + that all bytes in the row is properly reset. + */ + if ((file->s->options & HA_OPTION_PACK_RECORD) && + (file->s->has_varchar_fields | file->s->has_null_fields)) + int_table_flags|= HA_RECORD_MUST_BE_CLEAN_ON_WRITE; + for (i= 0; i < table->s->keys; i++) { plugin_ref parser= table->key_info[i].parser; @@ -811,7 +821,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) param.thd = thd; param.op_name = "check"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag = check_opt->flags | T_CHECK | T_SILENT; param.stats_method= (enum_handler_stats_method)thd->variables.myisam_stats_method; @@ -904,7 +914,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) param.thd = thd; param.op_name= "analyze"; param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS | T_DONT_CHECK_CHECKSUM); param.using_global_keycache = 1; @@ -1129,7 +1139,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize) DBUG_ENTER("ha_myisam::repair"); param.db_name= table->s->db.str; - param.table_name= table->alias; + param.table_name= table->alias.c_ptr(); param.tmpfile_createflag = O_RDWR | O_TRUNC; param.using_global_keycache = 1; param.thd= thd; diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index c40f894b14d..e35dd690482 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -79,7 +79,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) { int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err; uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys, - key_parts,unique_key_parts,fulltext_keys,uniques; + key_parts,unique_key_parts,base_key_parts,fulltext_keys,uniques; char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], data_name[FN_REFLEN]; uchar *disk_cache, *disk_pos, *end_pos; @@ -200,7 +200,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) keys= (uint) share->state.header.keys; uniques= (uint) share->state.header.uniques; fulltext_keys= (uint) share->state.header.fulltext_keys; - key_parts= mi_uint2korr(share->state.header.key_parts); + base_key_parts= key_parts= mi_uint2korr(share->state.header.key_parts); unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts); if (len != MI_STATE_INFO_SIZE) { @@ -298,7 +298,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) if (!my_multi_malloc(MY_WME, &share,sizeof(*share), - &share->state.rec_per_key_part,sizeof(long)*key_parts, + &share->state.rec_per_key_part, + sizeof(long)*base_key_parts, &share->keyinfo,keys*sizeof(MI_KEYDEF), &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF), &share->keyparts, @@ -322,7 +323,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) errpos=4; *share=share_buff; memcpy((char*) share->state.rec_per_key_part, - (char*) rec_per_key_part, sizeof(long)*key_parts); + (char*) rec_per_key_part, sizeof(long)*base_key_parts); memcpy((char*) share->state.key_root, (char*) key_root, sizeof(my_off_t)*keys); memcpy((char*) share->state.key_del, diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 2839d935167..42580150ed8 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -2698,16 +2698,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } -// psergey@askmonty.org: don't take the following: -#if 0 - /* init null bytes with default values as they might be - - left uninitialized in some cases and these uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); -#endif - for (i = start_field_no; i < end_field_no /* prebuilt->n_template */ ; i++) { templ = prebuilt->mysql_template + i; |