From 12a0f4ff14d4700898a10cd95ada901ed19e2ed2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 May 2006 11:56:59 +0300 Subject: [PATCH] Remove dflt_field from field structure as this was only needed when createing temporary table and I found another soultion that doesn't increase the size of the field structure for all table instances. (Better fix for bug #19089) Fixed compiler warnings Fixed valgrind warning in Item_date_add_intervall::eq. (Recoding of bugfix #19490) sql/field.cc: remove dflt_field from field structure (not needed) Simple cleanup of code that been copied elsewhere sql/field.h: remove dflt_field from field structure (not needed) sql/item.h: Removed compiler warnings sql/item_timefunc.cc: Fixed Item_date_add_intervall::eq The problem was that when we call 'eq' 'this' is not fixed, which means we can't call const_item() or a value function. I fixed this so that we check eq for all arguments and that the sign and type are identical. (The original code gave a 'accessing uninitialized data' in valgrind. sql/mysql_priv.h: Added default fields to create_tmp_field sql/sql_insert.cc: New default_field parameter to create_tmp_field() sql/sql_select.cc: New default_field parameter to create_tmp_field() Use this in create_tmp_table() to set right default value for a field --- sql/field.cc | 15 ++++++------ sql/field.h | 6 ----- sql/item.h | 2 ++ sql/item_timefunc.cc | 36 ++++------------------------- sql/mysql_priv.h | 1 + sql/sql_insert.cc | 9 ++++---- sql/sql_select.cc | 54 ++++++++++++++++++++++++++------------------ 7 files changed, 51 insertions(+), 72 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index c31fbacc25e..a920d6d91b1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1222,13 +1222,13 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) - :ptr(ptr_arg),null_ptr(null_ptr_arg), + :ptr(ptr_arg), null_ptr(null_ptr_arg), table(table_arg),orig_table(table_arg), table_name(table_arg ? &table_arg->alias : &unknown_table_name), field_name(field_name_arg), query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0), unireg_check(unireg_check_arg), - field_length(length_arg), null_bit(null_bit_arg), dflt_field(0) + field_length(length_arg), null_bit(null_bit_arg) { flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; @@ -8964,22 +8964,21 @@ create_field::create_field(Field *old_field,Field *orig_field) old_field->table->timestamp_field != old_field || /* timestamp field */ unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */ { - char buff[MAX_FIELD_WIDTH],*pos; - String tmp(buff,sizeof(buff), charset), *res; my_ptrdiff_t diff; /* Get the value from default_values */ diff= (my_ptrdiff_t) (orig_field->table->s->default_values- orig_field->table->record[0]); orig_field->move_field(diff); // Points now at default_values - bool is_null=orig_field->is_real_null(); - res= orig_field->val_str(&tmp); - orig_field->move_field(-diff); // Back to record[0] - if (!is_null) + if (!orig_field->is_real_null()) { + char buff[MAX_FIELD_WIDTH],*pos; + String tmp(buff,sizeof(buff), charset), *res; + res= orig_field->val_str(&tmp); pos= (char*) sql_strmake(res->ptr(), res->length()); def= new Item_string(pos, res->length(), charset); } + orig_field->move_field(-diff); // Back to record[0] } } diff --git a/sql/field.h b/sql/field.h index 4c3f6cd0709..f4d27e46877 100644 --- a/sql/field.h +++ b/sql/field.h @@ -53,12 +53,6 @@ public: char *ptr; // Position to field in record uchar *null_ptr; // Byte where null_bit is - /* - dflt_field is used only for the fields of temporary tables. - It points to the default value of the field in another table - from which this field has been created. - */ - Field *dflt_field; // Field to copy default value from /* Note that you can use table->in_use as replacement for current_thd member only inside of val_*() and store() members (e.g. you can't use it in cons) diff --git a/sql/item.h b/sql/item.h index 28b1f54add7..de9e9737187 100644 --- a/sql/item.h +++ b/sql/item.h @@ -388,6 +388,8 @@ public: required, otherwise we only reading it and SELECT privilege might be required. */ + Settable_routine_parameter() {} + virtual ~Settable_routine_parameter() {} virtual void set_required_privilege(bool rw) {}; /* diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 72c53272e0c..ca7028dae1e 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2130,39 +2130,11 @@ longlong Item_date_add_interval::val_int() bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const { - INTERVAL interval, other_interval; - String val= value; // Because of const - - if (this == item) - return TRUE; - - if ((item->type() != FUNC_ITEM) || - (arg_count != ((Item_func*) item)->arg_count) || - (func_name() != ((Item_func*) item)->func_name())) - return FALSE; - Item_date_add_interval *other= (Item_date_add_interval*) item; - - if ((int_type != other->int_type) || - (!args[0]->eq(other->args[0], binary_cmp))) - return FALSE; - - if (!args[1]->const_item() || !other->args[1]->const_item()) - return (args[1]->eq(other->args[1], binary_cmp)); - - if (get_interval_value(args[1], int_type, &val, &interval)) - return FALSE; - - val= other->value; - - if ((get_interval_value(other->args[1], other->int_type, &val, - &other_interval)) || - ((date_sub_interval ^ interval.neg) ^ - (other->date_sub_interval ^ other_interval.neg))) - return FALSE; - - // Assume comparing same types here due to earlier check - return memcmp(&interval, &other_interval, sizeof(INTERVAL)) == 0; + if (!Item_func::eq(item, binary_cmp)) + return 0; + return ((int_type == other->int_type) && + (date_sub_interval == other->date_sub_interval)); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 707a474b754..d1781c0ebbf 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -704,6 +704,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t); bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, + Field **def_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, bool make_copy_field, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c054499ecd8..f57856dc4b3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2500,12 +2500,13 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, while ((item=it++)) { create_field *cr_field; - Field *field; + Field *field, *def_field; if (item->type() == Item::FUNC_ITEM) - field=item->tmp_table_field(&tmp_table); + field= item->tmp_table_field(&tmp_table); else - field=create_tmp_field(thd, &tmp_table, item, item->type(), - (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0); + field= create_tmp_field(thd, &tmp_table, item, item->type(), + (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0, + 0); if (!field || !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? ((Item_field *)item)->field : diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d6e1650ba83..e5cf69f399b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8116,6 +8116,7 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table) in this array from_field if field will be created using other field as example, pointer example field will be written here + default_field If field has a default value field, store it here group 1 if we are going to do a relative group by on result modify_item 1 if item->result_field should point to new item. This is relevent for how fill_record() is going to @@ -8134,6 +8135,7 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table) Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, + Field **default_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, bool make_copy_field, @@ -8200,7 +8202,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, if (orig_type == Item::REF_ITEM && orig_modify) ((Item_ref*)orig_item)->set_result_field(result); if (field->field->eq_def(result)) - result->dflt_field= field->field; + *default_field= field->field; return result; } /* Fall through */ @@ -8288,7 +8290,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, char *tmpname,path[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; - Field **reg_field, **from_field; + Field **reg_field, **from_field, **default_field; uint *blob_field; Copy_field *copy=0; KEY *keyinfo; @@ -8357,6 +8359,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, if (!multi_alloc_root(&own_root, &table, sizeof(*table), ®_field, sizeof(Field*) * (field_count+1), + &default_field, sizeof(Field*) * (field_count), &blob_field, sizeof(uint)*(field_count+1), &from_field, sizeof(Field*)*field_count, ©_func, sizeof(*copy_func)*(copy_func_count+1), @@ -8386,6 +8389,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, bzero((char*) table,sizeof(*table)); bzero((char*) reg_field,sizeof(Field*)*(field_count+1)); + bzero((char*) default_field, sizeof(Field*) * (field_count)); bzero((char*) from_field,sizeof(Field*)*field_count); table->mem_root= own_root; @@ -8417,7 +8421,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, /* For easier error reporting */ table->s->table_cache_key= (char*) (table->s->db= ""); - /* Calculate which type of fields we will store in the temporary table */ reclength= string_total_length= 0; @@ -8454,9 +8457,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, Item *arg= *argp; if (!arg->const_item()) { + uint field_index= (uint) (reg_field - table->field); Field *new_field= create_tmp_field(thd, table, arg, arg->type(), ©_func, - tmp_from_field, group != 0,not_all_columns, + tmp_from_field, &default_field[field_index], + group != 0,not_all_columns, distinct, 0, param->convert_blob_length); if (!new_field) @@ -8465,12 +8470,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, reclength+=new_field->pack_length(); if (new_field->flags & BLOB_FLAG) { - *blob_field++= (uint) (reg_field - table->field); + *blob_field++= field_index; blob_count++; } if (new_field->type() == FIELD_TYPE_BIT) total_uneven_bit_length+= new_field->field_length & 7; - new_field->field_index= (uint) (reg_field - table->field); + new_field->field_index= field_index; *(reg_field++)= new_field; if (new_field->real_type() == MYSQL_TYPE_STRING || new_field->real_type() == MYSQL_TYPE_VARCHAR) @@ -8496,6 +8501,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } else { + uint field_index= (uint) (reg_field - table->field); /* The last parameter to create_tmp_field() is a bit tricky: @@ -8512,7 +8518,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, Field *new_field= (param->schema_table) ? create_tmp_field_for_schema(thd, item, table) : create_tmp_field(thd, table, item, type, ©_func, - tmp_from_field, group != 0, + tmp_from_field, &default_field[field_index], + group != 0, !force_copy_fields && (not_all_columns || group !=0), item->marker == 4, force_copy_fields, @@ -8534,7 +8541,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, total_uneven_bit_length+= new_field->field_length & 7; if (new_field->flags & BLOB_FLAG) { - *blob_field++= (uint) (reg_field - table->field); + *blob_field++= field_index; blob_count++; } if (item->marker == 4 && item->maybe_null) @@ -8543,7 +8550,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, new_field->flags|= GROUP_FLAG; } new_field->query_id= thd->query_id; - new_field->field_index= (uint) (reg_field - table->field); + new_field->field_index= field_index; *(reg_field++) =new_field; } if (!--hidden_field_count) @@ -8563,6 +8570,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); field_count= (uint) (reg_field - table->field); + *reg_field= 0; *blob_field= 0; // End marker /* If result table is small; use a heap */ @@ -8678,31 +8686,33 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } field->reset(); - if (field->dflt_field && field->dflt_field->ptr) + /* + Test if there is a default field value. The test for ->ptr is to skip + 'offset' fields generated by initalize_tables + */ + if (default_field[i] && default_field[i]->ptr) { - /* - field->dflt_field is set only in the cases when 'field' can + /* + default_field[i] is set only in the cases when 'field' can inherit the default value that is defined for the field referred by the Item_field object from which 'field' has been created. - For a field created not from a Item_field item dflt_field == 0. */ my_ptrdiff_t diff; - Field *orig_field= field->dflt_field; + Field *orig_field= default_field[i]; + /* Get the value from default_values */ diff= (my_ptrdiff_t) (orig_field->table->s->default_values- orig_field->table->record[0]); orig_field->move_field(diff); // Points now at default_values - bool is_null= orig_field->is_real_null(); - char *from= orig_field->ptr; - orig_field->move_field(-diff); // Back to record[0] - if (is_null) + if (orig_field->is_real_null()) field->set_null(); else { field->set_notnull(); - memcpy(field->ptr, from, field->pack_length()); + memcpy(field->ptr, orig_field->ptr, field->pack_length()); } - } + orig_field->move_field(-diff); // Back to record[0] + } if (from_field[i]) { /* Not a table Item */ @@ -12233,6 +12243,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, Item::Type order_item_type; Item **select_item; /* The corresponding item from the SELECT clause. */ Field *from_field; /* The corresponding field from the FROM clause. */ + uint counter; + bool unaliased; /* Local SP variables may be int but are expressions, not positions. @@ -12254,8 +12266,6 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, return FALSE; } /* Lookup the current GROUP/ORDER field in the SELECT clause. */ - uint counter; - bool unaliased; select_item= find_item_in_list(order_item, fields, &counter, REPORT_EXCEPT_NOT_FOUND, &unaliased); if (!select_item)