diff options
-rw-r--r-- | myisam/mi_create.c | 4 | ||||
-rw-r--r-- | mysql-test/r/type_timestamp.result | 4 | ||||
-rw-r--r-- | mysql-test/t/func_compress.test | 2 | ||||
-rw-r--r-- | mysql-test/t/type_timestamp.test | 2 | ||||
-rw-r--r-- | sql/field.h | 10 | ||||
-rw-r--r--[-rwxr-xr-x] | sql/ha_federated.cc | 0 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 8 | ||||
-rw-r--r-- | sql/sql_acl.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_show.cc | 45 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/table.cc | 33 | ||||
-rw-r--r-- | sql/table.h | 1 | ||||
-rw-r--r-- | strings/ctype-mb.c | 4 |
15 files changed, 90 insertions, 39 deletions
diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 0164555272d..1f6ed87182c 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -630,10 +630,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { HA_KEYSEG sseg; sseg.type=SPTYPE; - sseg.language= 7; + sseg.language= 7; /* Binary */ sseg.null_bit=0; sseg.bit_start=0; sseg.bit_end=0; + sseg.bit_length= 0; + sseg.bit_pos= 0; sseg.length=SPLEN; sseg.null_pos=0; sseg.start=j*SPLEN; diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 42fdc7e50c6..61c167c6264 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -35,6 +35,10 @@ UPDATE t1 SET value="my value" WHERE id="myKey"; SELECT stamp FROM t1 WHERE id="myKey"; stamp 1999-04-02 00:00:00 +UPDATE t1 SET id="myKey" WHERE value="my value"; +SELECT stamp FROM t1 WHERE id="myKey"; +stamp +1999-04-02 00:00:00 drop table t1; create table t1 (a timestamp); insert into t1 values (now()); diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index f46589e9e0e..9c32313e967 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -2,6 +2,8 @@ # # Test for compress and uncompress functions: # +# Note that this test gives error in the gzip library when running under +# valgrind, but these warnings can be ignored select @test_compress_string:='string for test compress function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa '; select length(@test_compress_string); diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index a8a0cf8703c..0a92afeb57d 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -29,6 +29,8 @@ INSERT INTO t1 VALUES ("my value", "myKey","1999-04-02 00:00:00"); SELECT stamp FROM t1 WHERE id="myKey"; UPDATE t1 SET value="my value" WHERE id="myKey"; SELECT stamp FROM t1 WHERE id="myKey"; +UPDATE t1 SET id="myKey" WHERE value="my value"; +SELECT stamp FROM t1 WHERE id="myKey"; drop table t1; create table t1 (a timestamp); diff --git a/sql/field.h b/sql/field.h index 670b778f863..ab911822c2c 100644 --- a/sql/field.h +++ b/sql/field.h @@ -952,14 +952,20 @@ public: :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg, cs), length_bytes(length_bytes_arg) - {} + { + if (table) + table->s->varchar_fields++; + } Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg, cs), length_bytes(len_arg < 256 ? 1 :2) - {} + { + if (table) + table->s->varchar_fields++; + } enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } enum ha_base_keytype key_type() const; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index abd33f2eaef..abd33f2eaef 100755..100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index aa98f1860b6..16a3e86e519 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2519,7 +2519,7 @@ longlong Item_func_regex::val_int() regfree(&preg); regex_compiled=0; } - if (regcomp(&preg,res2->c_ptr(), + if (regcomp(&preg,res2->c_ptr_safe(), ((cmp_collation.collation->state & (MY_CS_BINSORT | MY_CS_CSSORT)) ? REG_EXTENDED | REG_NOSUB : diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0e46e39960e..e75071a19b5 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3589,7 +3589,6 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, Item_func::Functype type,Item *value) { uint maybe_null=(uint) field->real_maybe_null(), copies; - uint field_length=field->pack_length()+maybe_null; bool optimize_range; SEL_ARG *tree; char *str, *str2; @@ -3639,6 +3638,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, char buff1[MAX_FIELD_WIDTH],*min_str,*max_str; String tmp(buff1,sizeof(buff1),value->collation.collation),*res; uint length,offset,min_length,max_length; + uint field_length= field->pack_length()+maybe_null; if (!optimize_range) DBUG_RETURN(0); // Can't optimize this @@ -3683,21 +3683,23 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, length+=offset; if (!(min_str= (char*) alloc_root(param->mem_root, length*2))) DBUG_RETURN(0); + max_str=min_str+length; if (maybe_null) max_str[0]= min_str[0]=0; + field_length-= maybe_null; like_error= my_like_range(field->charset(), res->ptr(), res->length(), ((Item_func_like*)(param->cond))->escape, wild_one, wild_many, - field_length-maybe_null, + field_length, min_str+offset, max_str+offset, &min_length, &max_length); if (like_error) // Can't optimize with LIKE DBUG_RETURN(0); - if (offset != maybe_null) // Blob + if (offset != maybe_null) // BLOB or VARCHAR { int2store(min_str+maybe_null,min_length); int2store(max_str+maybe_null,max_length); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 14a66d2b10f..bcad0e627f4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4800,7 +4800,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr()); + my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe()); DBUG_RETURN(result); } @@ -4905,7 +4905,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr()); + my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); DBUG_RETURN(result); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4b484500527..a0728f58372 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1911,7 +1911,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, { DBUG_ENTER("prepare_schema_table"); SELECT_LEX *sel= 0; - switch(schema_table_idx) { + switch (schema_table_idx) { case SCH_SCHEMATA: #if defined(DONT_ALLOW_SHOW_COMMANDS) my_message(ER_NOT_ALLOWED_COMMAND, @@ -1953,7 +1953,11 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, thd->priv_user, thd->priv_host, db); DBUG_RETURN(1); } - lex->select_lex.db= db; + /* + We need to do a copy to make this prepared statement safe if this + was thd->db + */ + lex->select_lex.db= thd->strdup(db); break; } #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3aa39e87614..b1fd0cbbccd 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1793,14 +1793,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; - DBUG_ENTER("fill_schema_tables"); + SELECT_LEX sel; + INDEX_FIELD_VALUES idx_field_vals; + char path[FN_REFLEN], *end, *base_name, *file_name; + uint len; + bool with_i_schema; + enum enum_schema_tables schema_table_idx; + thr_lock_type lock_type; + List<char> bases; + COND *partial_cond; + DBUG_ENTER("get_all_tables"); + + LINT_INIT(end); + LINT_INIT(len); if (lsel) { TABLE *old_open_tables= thd->open_tables; TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first; + bool res; + lex->all_selects_list= lsel; - bool res= open_and_lock_tables(thd, show_table_list); + res= open_and_lock_tables(thd, show_table_list); if (schema_table->process_table(thd, show_table_list, table, res, show_table_list->db, show_table_list->table_name)) @@ -1813,15 +1827,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } - SELECT_LEX sel; - INDEX_FIELD_VALUES idx_field_vals; - char path[FN_REFLEN], *end= 0, *base_name, *file_name; - uint len= 0; - bool with_i_schema; - List<char> bases; lex->all_selects_list= &sel; - enum enum_schema_tables schema_table_idx= get_schema_table_idx(schema_table); - thr_lock_type lock_type= TL_UNLOCK; + schema_table_idx= get_schema_table_idx(schema_table); + lock_type= TL_UNLOCK; + if (schema_table_idx == SCH_TABLES) lock_type= TL_READ; get_index_field_values(lex, &idx_field_vals); @@ -1833,9 +1842,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (mysql_find_files(thd, &bases, NullS, mysql_data_home, idx_field_vals.db_value, 1)) return 1; + List_iterator_fast<char> it(bases); - COND *partial_cond= make_cond_for_info_schema(cond, tables); - while ((base_name=it++) || + partial_cond= make_cond_for_info_schema(cond, tables); + while ((base_name= it++) || /* generate error for non existing database. (to save old behaviour for SHOW TABLES FROM db) @@ -1868,8 +1878,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(1); } - List_iterator_fast<char> it(files); - while ((file_name=it++)) + List_iterator_fast<char> it_files(files); + while ((file_name= it_files++)) { restore_record(table, s->default_values); table->field[schema_table->idx_field1]-> @@ -1889,8 +1899,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) else { my_snprintf(end, len, "/%s%s", file_name, reg_ext); - switch (mysql_frm_type(path)) - { + switch (mysql_frm_type(path)) { case FRMTYPE_ERROR: table->field[3]->store("ERROR", 5, system_charset_info); break; @@ -3188,9 +3197,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) } table->s->tmp_table= TMP_TABLE; table->grant.privilege= SELECT_ACL; - table->alias_name_used= my_strcasecmp(table_alias_charset, - table_list->table_name, - table_list->alias); + table->alias_name_used= 0; table_list->schema_table_name= table_list->table_name; table_list->table_name= (char*) table->s->table_name; table_list->table= table; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c35df041a39..d2220cd67c3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -31,7 +31,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields); static bool compare_record(TABLE *table, ulong query_id) { - if (!table->s->blob_fields) + if (table->s->blob_fields + table->s->varchar_fields == 0) return cmp_record(table,record[1]); /* Compare null bits */ if (memcmp(table->null_flags, diff --git a/sql/table.cc b/sql/table.cc index ddcb5117338..97f17ea2417 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -288,7 +288,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, records=2; else records=1; - if (prgflag & (READ_ALL+EXTRA_RECORD)) records++; + if (prgflag & (READ_ALL+EXTRA_RECORD)) + records++; /* QQ: TODO, remove the +1 from below */ rec_buff_length= ALIGN_SIZE(share->reclength + 1 + outparam->file->extra_rec_buf_length()); @@ -304,12 +305,32 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, MYF(MY_NABP))) goto err_not_open; /* purecov: inspected */ - outparam->record[0]= record+ rec_buff_length; - if (records > 2) - outparam->record[1]= record+ rec_buff_length*2; + if (records == 1) + { + /* We are probably in hard repair, and the buffers should not be used */ + outparam->record[0]= outparam->record[1]= share->default_values; + } else - outparam->record[1]= outparam->record[0]; // Safety + { + outparam->record[0]= record+ rec_buff_length; + if (records > 2) + outparam->record[1]= record+ rec_buff_length*2; + else + outparam->record[1]= outparam->record[0]; // Safety + } +#ifdef HAVE_purify + /* + We need this because when we read var-length rows, we are not updating + bytes after end of varchar + */ + if (records > 1) + { + memcpy(outparam->record[0], share->default_values, rec_buff_length); + if (records > 2) + memcpy(outparam->record[1], share->default_values, rec_buff_length); + } +#endif VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open; if (crypted) @@ -822,7 +843,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, outparam->file=0; // For easier errorchecking outparam->db_stat=0; hash_free(&share->name_hash); - free_root(&share->mem_root, MYF(0)); + free_root(&outparam->mem_root, MYF(0)); my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN (error); } /* openfrm */ diff --git a/sql/table.h b/sql/table.h index c4cb948914e..8240a3445ec 100644 --- a/sql/table.h +++ b/sql/table.h @@ -137,6 +137,7 @@ typedef struct st_table_share uint uniques; /* Number of UNIQUE index */ uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ + uint varchar_fields; /* number of varchar fields */ uint db_create_options; /* Create options from database */ uint db_options_in_use; /* Options in use */ uint db_record_offset; /* if HA_REC_IN_SEQ */ diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index ae81cefad5a..c899e2d5d38 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -561,9 +561,9 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, *min_str++= *max_str++ = *ptr; } - *min_length= *max_length = (uint) (min_str - min_org); + *min_length= *max_length = (uint) (min_str - min_org); while (min_str != min_end) - *min_str++= *max_str= ' '; /* Because if key compression */ + *min_str++= *max_str++= ' '; /* Because if key compression */ return 0; } |