From 93cf297fcb932aaaf1c006d7066ec453c9a907cb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 14:43:51 +0200 Subject: Cleanups during review stage Added auto-correct of field length for enum/set tables for ALTER TABLE This is becasue of a bug in previous MySQL 4.1 versions where the length for enum/set was set incorrectly after ALTER TABLE mysql-test/r/rpl_start_stop_slave.result: Fixed wrong test mysql-test/r/type_enum.result: Added test for wrong enum/set length after alter table mysql-test/t/ps.test: removed empty line mysql-test/t/type_enum.test: Added test for wrong enum/set length after alter table sql/field.cc: Added auto-correct of field length for enum/set tables. This is becasue of a bug in previous MySQL 4.1 versions where the length for enum/set was set incorrectly after ALTER TABLE sql/item_cmpfunc.cc: Simple optimization sql/mysql_priv.h: Made local function global sql/set_var.cc: Simple cleanup sql/sql_table.cc: Simple cleanups & optimizations --- sql/field.cc | 60 +++++++++++++++++++++++++++++++++++++---------------- sql/item_cmpfunc.cc | 12 +++++------ sql/mysql_priv.h | 2 ++ sql/set_var.cc | 9 ++++---- sql/sql_table.cc | 14 ++++--------- 5 files changed, 58 insertions(+), 39 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 72c27b6adf9..eee7f6f1684 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5842,25 +5842,47 @@ bool Field_num::eq_def(Field *field) void create_field::create_length_to_internal_length(void) { - switch (sql_type) + switch (sql_type) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + length*= charset->mbmaxlen; + pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? + FIELD_TYPE_STRING : sql_type, length); + break; +#ifdef CORRECT_CODE_BUT_CANT_YET_BE_USED + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + length*= charset->mbmaxlen; + break; +#else + /* + Because of a bug in MySQL 4.1 where length was extended for ENUM and SET + fields for every ALTER TABLE, we have to recalculate lengths here + */ + case MYSQL_TYPE_ENUM: { - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - length*= charset->mbmaxlen; - pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? - FIELD_TYPE_STRING : sql_type, length); - break; - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - length*= charset->mbmaxlen; - break; - default: - /* do nothing */ - break; + uint32 tot_length, max_length; + calculate_interval_lengths(current_thd, interval, + &max_length, &tot_length); + length= max_length * charset->mbmaxlen; + break; + } + case MYSQL_TYPE_SET: + { + uint32 tot_length, max_length; + calculate_interval_lengths(current_thd, interval, + &max_length, &tot_length); + length= (tot_length + (interval->count - 1)) * charset->mbmaxlen; + break; + } +#endif + default: + /* do nothing */ + break; } } @@ -6085,6 +6107,8 @@ create_field::create_field(Field *old_field,Field *orig_field) } length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed break; + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4970517de87..c7481192be8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2365,10 +2365,10 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } int error; if ((error= regcomp(&preg,res->c_ptr(), - ((cmp_collation.collation->state & MY_CS_BINSORT) || - (cmp_collation.collation->state & MY_CS_CSSORT)) ? + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE, + REG_EXTENDED | REG_NOSUB | REG_ICASE), cmp_collation.collation))) { (void) regerror(error,&preg,buff,sizeof(buff)); @@ -2417,10 +2417,10 @@ longlong Item_func_regex::val_int() regex_compiled=0; } if (regcomp(&preg,res2->c_ptr(), - ((cmp_collation.collation->state & MY_CS_BINSORT) || - (cmp_collation.collation->state & MY_CS_CSSORT)) ? + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE, + REG_EXTENDED | REG_NOSUB | REG_ICASE), cmp_collation.collation)) { null_value=1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3f55a88b262..331dc43f9ad 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -370,6 +370,8 @@ int insert_precheck(THD *thd, TABLE_LIST *tables); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); +void calculate_interval_lengths(THD *thd, TYPELIB *interval, + uint *max_length, uint *tot_length); #include "sql_class.h" #include "opt_range.h" diff --git a/sql/set_var.cc b/sql/set_var.cc index 2031ac15412..79be4dc1c46 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2725,24 +2725,23 @@ sys_var *find_sys_var(const char *str, uint length) int sql_set_variables(THD *thd, List *var_list) { - int error= 0; + int error; List_iterator_fast it(*var_list); DBUG_ENTER("sql_set_variables"); set_var_base *var; while ((var=it++)) { - if ((error=var->check(thd))) + if ((error= var->check(thd))) goto err; } - if (!thd->net.report_error) + if (!(error= test(thd->net.report_error))) { it.rewind(); while ((var= it++)) error|= var->update(thd); // Returns 0, -1 or 1 } - else - error= 1; + err: free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(error); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eedd9388877..2260877fc05 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -814,8 +814,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(-1); } } - else - if (key_info->algorithm == HA_KEY_ALG_RTREE) + else if (key_info->algorithm == HA_KEY_ALG_RTREE) { #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) @@ -839,6 +838,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, CHARSET_INFO *ft_key_charset=0; // for FULLTEXT for (uint column_nr=0 ; (column=cols++) ; column_nr++) { + key_part_spec *dup_column; + it.rewind(); field=0; while ((sql_field=it++) && @@ -853,9 +854,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, column->field_name); DBUG_RETURN(-1); } - for (uint dup_nr= 0; dup_nr < column_nr; dup_nr++) + while ((dup_column= cols2++) != column) { - key_part_spec *dup_column= cols2++; if (!my_strcasecmp(system_charset_info, column->field_name, dup_column->field_name)) { @@ -866,12 +866,6 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } } cols2.rewind(); - /* for fulltext keys keyseg length is 1 for blobs (it's ignored in - ft code anyway, and 0 (set to column width later) for char's. - it has to be correct col width for char's, as char data are not - prefixed with length (unlike blobs, where ft code takes data length - from a data prefix, ignoring column->length). - */ if (key->type == Key::FULLTEXT) { if ((sql_field->sql_type != FIELD_TYPE_STRING && -- cgit v1.2.1