diff options
author | unknown <monty@donna.mysql.com> | 2001-01-28 21:35:50 +0200 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2001-01-28 21:35:50 +0200 |
commit | 184e24b2253a81b03476e3d4d8cf56d5eb9dbf18 (patch) | |
tree | fabb5447e17b9f0959cb83b6d88351367ca53645 /sql | |
parent | 298ba0d39d6d38d5be860a3ad8a55b469b67e7d8 (diff) | |
download | mariadb-git-184e24b2253a81b03476e3d4d8cf56d5eb9dbf18.tar.gz |
Fixed ALTER TABLE on MERGE tables
Fixed bug in DISTINCT
Docs/manual.texi:
Updated Changelog
Cleaned up adding character sets
merge/open.c:
skip comments
myisam/mi_check.c:
Fixed bug when sorting index on Windows
myisammrg/myrg_info.c:
Use only portable printf arguments
myisammrg/myrg_rrnd.c:
Use only portable printf arguments
mysql-test/r/distinct.result:
Added test case for bug in distinct
mysql-test/r/merge.result:
Added test for ALTER TABLE
mysql-test/t/distinct.test:
Added test case for bug in distinct
mysql-test/t/merge.test:
Added test for ALTER TABLE
sql-bench/crash-me.sh:
Fixed portability issues
sql/ha_myisammrg.cc:
Fixed for ALTER TABLE on MERGE tables
sql/item_sum.cc:
Fixed bug in DISTINCT
sql/sql_db.cc:
Added test of namelen in check_db_name
sql/sql_select.cc:
Fixed bug in DISTINCT
sql/sql_select.h:
Fixed bug in DISTINCT
sql/sql_table.cc:
Fixed ALTER TABLE on MERGE tables
sql/table.cc:
Added test of namelen in check_db_name
sql/table.h:
Fixed ALTER TABLE on MERGE tables
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_myisammrg.cc | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/sql_db.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 97 | ||||
-rw-r--r-- | sql/sql_select.h | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 9 | ||||
-rw-r--r-- | sql/table.cc | 3 | ||||
-rw-r--r-- | sql/table.h | 1 |
8 files changed, 92 insertions, 33 deletions
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 863054b4837..4c562282090 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -177,6 +177,7 @@ void ha_myisammrg::info(uint flag) errkey = info.errkey; table->keys_in_use=(((key_map) 1) << table->keys)- (key_map) 1; table->db_options_in_use = info.options; + table->is_view=1; mean_rec_length=info.reclength; block_size=0; update_time=0; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 1c236e19bda..375ba081f80 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -811,7 +811,7 @@ bool Item_sum_count_distinct::setup(THD *thd) for (uint i=0; i < arg_count ; i++) if (list.push_back(args[i])) return 1; - count_field_types(tmp_table_param,list); + count_field_types(tmp_table_param,list,0); if (table) { free_tmp_table(thd, table); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 89e7faa237c..25bbe75e944 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -35,7 +35,7 @@ void mysql_create_db(THD *thd, char *db, uint create_options) long result=1; DBUG_ENTER("mysql_create_db"); - if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) + if (!stripp_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db); DBUG_VOID_RETURN; @@ -103,7 +103,7 @@ void mysql_rm_db(THD *thd,char *db,bool if_exists) MY_DIR *dirp; DBUG_ENTER("mysql_rm_db"); - if (!stripp_sp(db) || strlen(db) > NAME_LEN || check_db_name(db)) + if (!stripp_sp(db) || check_db_name(db)) { net_printf(&thd->net,ER_WRONG_DB_NAME, db); DBUG_VOID_RETURN; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2d8373ec067..526c78e0856 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -268,7 +268,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, join.first_record=join.sort_and_group=0; join.select_options=select_options; join.result=result; - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); join.const_tables=0; join.having=0; join.group= group != 0; @@ -632,9 +632,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, /* ** If we have different sort & group then we must sort the data by group ** and copy it to another tmp table + ** This code is also used if we are using distinct something + ** we haven't been able to store in the temporary table yet + ** like SEC_TO_TIME(SUM(...)). */ - if (group && (!test_if_subpart(group,order) || select_distinct)) + if (group && (!test_if_subpart(group,order) || select_distinct) || + (select_distinct && + join.tmp_table_param.using_indirect_summary_function)) { /* Must copy to another table */ TABLE *tmp_table2; DBUG_PRINT("info",("Creating group table")); @@ -644,11 +649,16 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (make_simple_join(&join,tmp_table)) goto err; calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields, + select_distinct && !group); + join.tmp_table_param.hidden_field_count=(all_fields.elements- + fields.elements); /* group data to new table */ if (!(tmp_table2 = create_tmp_table(thd,&join.tmp_table_param,all_fields, - (ORDER*) 0, 0 , 1, 0, + (ORDER*) 0, + select_distinct && !group, + 1, 0, join.select_options))) goto err; /* purecov: inspected */ if (group) @@ -657,7 +667,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (create_sort_index(join.join_tab,group,HA_POS_ERROR) || alloc_group_fields(&join,group)) { - free_tmp_table(thd,tmp_table2); /* purecov: inspected */ + free_tmp_table(thd,tmp_table2); /* purecov: inspected */ goto err; /* purecov: inspected */ } group=0; @@ -696,14 +706,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (make_simple_join(&join,tmp_table)) goto err; calc_group_buffer(&join,group); - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); } if (procedure) { if (procedure->change_columns(fields) || result->prepare(fields)) goto err; - count_field_types(&join.tmp_table_param,all_fields); + count_field_types(&join.tmp_table_param,all_fields,0); } if (join.group || join.tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) @@ -3265,6 +3275,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, { TABLE *table; uint i,field_count,reclength,null_count,null_pack_length, + hidden_null_count, hidden_null_pack_length, hidden_field_count, blob_count,group_null_items; bool using_unique_constraint=0; char *tmpname,path[FN_REFLEN]; @@ -3292,9 +3303,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, (*tmp->item)->marker=4; // Store null in key if (param->group_length >= MAX_BLOB_WIDTH) using_unique_constraint=1; + if (group) + distinct=0; // Can't use distinct } field_count=param->field_count+param->func_count+param->sum_func_count; + hidden_field_count=param->hidden_field_count; if (!my_multi_malloc(MYF(MY_WME), &table,sizeof(*table), ®_field,sizeof(Field*)*(field_count+1), @@ -3334,9 +3348,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->tmp_table=1; table->db_low_byte_first=1; // True for HEAP and MyISAM - /* Calculate with type of fields we will need in heap table */ + /* Calculate which type of fields we will store in the temporary table */ - reclength=blob_count=null_count=group_null_items=0; + reclength=blob_count=null_count=hidden_null_count=group_null_items=0; + param->using_indirect_summary_function=0; List_iterator<Item> li(fields); Item *item; @@ -3344,8 +3359,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, while ((item=li++)) { Item::Type type=item->type(); - if (item->with_sum_func && type != Item::SUM_FUNC_ITEM || - item->const_item()) + if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) + { + /* + Mark that the we have ignored an item that refers to a summary + function. We need to know this if someone is going to use + DISTINCT on the result. + */ + param->using_indirect_summary_function=1; + continue; + } + if (item->const_item()) // We don't have to store this continue; if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) { /* Can't calc group yet */ @@ -3396,6 +3420,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } *(reg_field++) =new_field; } + if (!--hidden_field_count) + hidden_null_count=null_count; } field_count= (uint) (reg_field - table->field); @@ -3420,8 +3446,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->blob_fields=blob_count; if (blob_count == 0) - null_count++; // For delete link - reclength+=(null_pack_length=(null_count+7)/8); + { + /* We need to ensure that first byte is not 0 for the delete link */ + if (hidden_null_count) + hidden_null_count++; + else + null_count++; + } + hidden_null_pack_length=(hidden_null_count+7)/8; + null_pack_length=hidden_null_count+(null_count+7)/8; + reclength+=null_pack_length; if (!reclength) reclength=1; // Dummy select @@ -3449,6 +3483,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, bfill(null_flags,null_pack_length,255); // Set null fields } null_count= (blob_count == 0) ? 1 : 0; + hidden_field_count=param->hidden_field_count; for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++) { Field *field= *reg_field; @@ -3496,6 +3531,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, recinfo->type=FIELD_SKIPP_ENDSPACE; else recinfo->type=FIELD_NORMAL; + if (!--hidden_field_count) + null_count=(null_count+7) & ~7; // move to next byte } param->copy_field_count=(uint) (copy - param->copy_field); @@ -3559,11 +3596,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } } - if (distinct && !group) + if (distinct) { - /* Create an unique key or an unique constraint over all columns */ - keyinfo->key_parts=field_count+ test(null_count); - if (distinct && allow_distinct_limit) + /* + Create an unique key or an unique constraint over all columns + that should be in the result. In the temporary table, there are + 'param->hidden_field_count' extra columns, whose null bits are stored + in the first 'hidden_null_pack_length' bytes of the row. + */ + null_pack_length-=hidden_null_pack_length; + keyinfo->key_parts=field_count+ test(null_pack_length); + if (allow_distinct_limit) { set_if_smaller(table->max_rows,thd->select_limit); param->end_write_records=thd->select_limit; @@ -3585,11 +3628,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, keyinfo->flags=HA_NOSAME; keyinfo->key_length=(uint16) reclength; keyinfo->name=(char*) "tmp"; - if (null_count) + if (null_pack_length) { key_part_info->null_bit=0; - key_part_info->offset=0; - key_part_info->length=(null_count+7)/8; + key_part_info->offset=hidden_null_pack_length; + key_part_info->length=null_pack_length; key_part_info->field=new Field_string((char*) table->record[0], (uint32) key_part_info->length, (uchar*) 0, @@ -3600,7 +3643,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, key_part_info->type= HA_KEYTYPE_BINARY; key_part_info++; } - for (i=0,reg_field=table->field; i < field_count; + for (i=param->hidden_field_count, reg_field=table->field + i ; + i < field_count; i++, reg_field++, key_part_info++) { key_part_info->null_bit=0; @@ -5917,13 +5961,14 @@ create_distinct_group(ORDER *order_list,List<Item> &fields) *****************************************************************************/ void -count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) +count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, + bool reset_with_sum_func) { List_iterator<Item> li(fields); Item *field; - param->field_count=param->sum_func_count= - param->func_count=0; + param->field_count=param->sum_func_count=param->func_count= + param->hidden_field_count=0; param->quick_group=1; while ((field=li++)) { @@ -5949,7 +5994,11 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields) } } else + { param->func_count++; + if (reset_with_sum_func) + field->with_sum_func=0; + } } } diff --git a/sql/sql_select.h b/sql/sql_select.h index 8ac00dde4c5..2f7454e4059 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -124,10 +124,13 @@ class TMP_TABLE_PARAM { KEY *keyinfo; ha_rows end_write_records; uint copy_field_count,field_count,sum_func_count,func_count; + uint hidden_field_count; uint group_parts,group_length; uint quick_group; + bool using_indirect_summary_function; - TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) {} + TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0) + {} ~TMP_TABLE_PARAM() { cleanup(); @@ -178,7 +181,8 @@ TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ORDER *group, bool distinct, bool save_sum_fields, bool allow_distinct_limit, uint select_options); void free_tmp_table(THD *thd, TABLE *entry); -void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields); +void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, + bool reset_with_sum_func); bool setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields); void copy_fields(TMP_TABLE_PARAM *param); void copy_funcs(Item_result_field **func_ptr); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 954a1f8efd7..9e720558456 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1443,10 +1443,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->cuted_fields=0L; thd->proc_info="copy to tmp table"; next_insert_id=thd->next_insert_id; // Remember for loggin - error=copy_data_between_tables(table,new_table,create_list,handle_duplicates, - order, &copied,&deleted); + copied=deleted=0; + if (!new_table->is_view) + error=copy_data_between_tables(table,new_table,create_list, + handle_duplicates, + order, &copied, &deleted); thd->last_insert_id=next_insert_id; // Needed for correct log - thd->count_cuted_fields=0; /* Don`t calc cuted fields */ + thd->count_cuted_fields=0; // Don`t calc cuted fields new_table->time_stamp=save_time_stamp; if (table->tmp_table) diff --git a/sql/table.cc b/sql/table.cc index 762c28b0fbf..8ee6ee02d68 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1033,6 +1033,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) bool check_db_name(const char *name) { + const char *start=end; while (*name) { #if defined(USE_MB) && defined(USE_MB_IDENT) @@ -1050,7 +1051,7 @@ bool check_db_name(const char *name) return 1; name++; } - return 0; + return (uint) (name - start) > NAME_LEN; } diff --git a/sql/table.h b/sql/table.h index 8121271b479..c17a1eca830 100644 --- a/sql/table.h +++ b/sql/table.h @@ -93,6 +93,7 @@ struct st_table { my_bool locked_by_flush; my_bool locked_by_name; my_bool crashed; + my_bool is_view; Field *next_number_field, /* Set if next_number is activated */ *found_next_number_field, /* Set on open */ *rowid_field; |