diff options
-rw-r--r-- | sql/field.h | 5 | ||||
-rw-r--r-- | sql/item.cc | 31 | ||||
-rw-r--r-- | sql/item.h | 15 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 | ||||
-rw-r--r-- | sql/table.cc | 2 | ||||
-rw-r--r-- | sql/table.h | 1 |
6 files changed, 54 insertions, 6 deletions
diff --git a/sql/field.h b/sql/field.h index 40578d19c82..359db63b0ac 100644 --- a/sql/field.h +++ b/sql/field.h @@ -78,10 +78,11 @@ public: virtual void reset_fields() {} virtual void set_default() { - memcpy(ptr, ptr + table->rec_buff_length, pack_length()); + my_ptrdiff_t offset = table->default_values - table->record[0]; + memcpy(ptr, ptr + offset, pack_length()); if (null_ptr) *null_ptr= ((*null_ptr & (uchar) ~null_bit) | - null_ptr[table->rec_buff_length] & null_bit); + null_ptr[offset] & null_bit); } virtual bool binary() const { return 1; } virtual bool zero_pack() const { return 1; } diff --git a/sql/item.cc b/sql/item.cc index feb318f829d..a1514892035 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1120,6 +1120,37 @@ bool Item_ref::check_loop(uint id) DBUG_RETURN((*ref)->check_loop(id)); } +bool Item_default_value::eq(const Item *item, bool binary_cmp) const +{ + return item->type() == DEFAULT_VALUE_ITEM && + ((Item_default_value *)item)->arg->eq(arg, binary_cmp); +} + +bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items) +{ + bool res= arg->fix_fields(thd, table_list, items); + if (res) + return res; + if (arg->type() == REF_ITEM) + { + Item_ref *ref= (Item_ref *)arg; + if (ref->ref[0]->type() != FIELD_ITEM) + { + return 1; + } + arg= ref->ref[0]; + } + Item_field *field_arg= (Item_field *)arg; + Field *def_field= (Field*) sql_alloc(field_arg->field->size_of()); + if (!def_field) + return 1; + memcpy(def_field, field_arg->field, field_arg->field->size_of()); + def_field->move_field(def_field->table->default_values - + def_field->table->record[0]); + set_field(def_field); + return 0; +} + /* If item is a const function, calculate it and return a const item diff --git a/sql/item.h b/sql/item.h index 1ea76731fd3..c8aac5d4130 100644 --- a/sql/item.h +++ b/sql/item.h @@ -36,7 +36,7 @@ public: COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM, PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, FIELD_VARIANCE_ITEM,CONST_ITEM, - SUBSELECT_ITEM, ROW_ITEM}; + SUBSELECT_ITEM, ROW_ITEM, DEFAULT_VALUE_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; String str_value; /* used to store value */ @@ -216,9 +216,9 @@ public: bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } + friend class Item_default_value; }; - class Item_null :public Item { public: @@ -706,6 +706,17 @@ public: bool cmp(void); }; +class Item_default_value : public Item_field +{ +public: + Item *arg; + Item_default_value(Item *a) : + Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {} + enum Type type() const { return DEFAULT_VALUE_ITEM; } + bool eq(const Item *item, bool binary_cmp) const; + bool fix_fields(THD *, struct st_table_list *, Item **); +}; + extern Item_buff *new_Item_buff(Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item *resolve_const_item(Item *item,Item *cmp_item); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 55f165c0739..4db064150ea 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2037,6 +2037,8 @@ simple_expr: { $$= new Item_func_conv_charset3($3,$7,$5); } | FUNC_ARG0 '(' ')' { $$= ((Item*(*)(void))($1.symbol->create_func))();} + | DEFAULT '(' simple_ident ')' + { $$= new Item_default_value($3); } | FUNC_ARG1 '(' expr ')' { $$= ((Item*(*)(Item*))($1.symbol->create_func))($3);} | FUNC_ARG2 '(' expr ',' expr ')' @@ -3136,12 +3138,12 @@ update: ; update_list: - update_list ',' simple_ident equal expr + update_list ',' simple_ident equal expr_or_default { if (add_item_to_list(YYTHD, $3) || add_value_to_list(YYTHD, $5)) YYABORT; } - | simple_ident equal expr + | simple_ident equal expr_or_default { if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3)) YYABORT; diff --git a/sql/table.cc b/sql/table.cc index 84a072c886d..2fcf19fddae 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -260,6 +260,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (db_stat & HA_READ_ONLY) outparam->record[1]=outparam->record[0]; /* purecov: inspected */ } + + outparam->default_values= outparam->record[2]; VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0))); if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open; diff --git a/sql/table.h b/sql/table.h index d24e4e1e422..75f16797050 100644 --- a/sql/table.h +++ b/sql/table.h @@ -54,6 +54,7 @@ struct st_table { Field_blob **blob_field; /* Pointer to blob fields */ HASH name_hash; /* hash of field names */ byte *record[3]; /* Pointer to records */ + byte *default_values; uint fields; /* field count */ uint reclength; /* Recordlength */ uint rec_buff_length; |