summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/field.h5
-rw-r--r--sql/item.cc31
-rw-r--r--sql/item.h15
-rw-r--r--sql/sql_yacc.yy6
-rw-r--r--sql/table.cc2
-rw-r--r--sql/table.h1
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;