summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc138
1 files changed, 126 insertions, 12 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 47b2cae1a04..09d407baad6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1250,6 +1250,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
com_length= uint2korr(forminfo+284);
vcol_screen_length= uint2korr(forminfo+286);
share->vfields= 0;
+ share->default_fields= 0;
share->stored_fields= share->fields;
if (forminfo[46] != (uchar)255)
{
@@ -1581,8 +1582,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (reg_field->unireg_check == Field::NEXT_NUMBER)
share->found_next_number_field= field_ptr;
- if (share->timestamp_field == reg_field)
- share->timestamp_field_offset= i;
if (use_hash)
{
@@ -1604,6 +1603,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (share->stored_rec_length>=recpos)
share->stored_rec_length= recpos-1;
}
+ if (reg_field->has_insert_default_function() ||
+ reg_field->has_update_default_function())
+ ++share->default_fields;
}
*field_ptr=0; // End marker
/* Sanity checks: */
@@ -2315,7 +2317,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint records, i, bitmap_size;
bool error_reported= FALSE;
uchar *record, *bitmaps;
- Field **field_ptr, **vfield_ptr;
+ Field **field_ptr, **vfield_ptr, **dfield_ptr;
uint8 save_context_analysis_only= thd->lex->context_analysis_only;
DBUG_ENTER("open_table_from_share");
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
@@ -2419,9 +2421,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
if (share->found_next_number_field)
outparam->found_next_number_field=
outparam->field[(uint) (share->found_next_number_field - share->field)];
- if (share->timestamp_field)
- outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
-
/* Fix key->name and key_part->field */
if (share->key_parts)
@@ -2472,7 +2471,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
}
/*
- Process virtual columns, if any.
+ Process virtual and default columns, if any.
*/
if (!share->vfields)
outparam->vfield= NULL;
@@ -2484,10 +2483,26 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
goto err;
outparam->vfield= vfield_ptr;
+ }
+
+ if (!share->default_fields)
+ outparam->default_field= NULL;
+ else
+ {
+ if (!(dfield_ptr = (Field **) alloc_root(&outparam->mem_root,
+ (uint) ((share->default_fields+1)*
+ sizeof(Field*)))))
+ goto err;
+ outparam->default_field= dfield_ptr;
+ }
+
+ if (share->vfields || share->default_fields)
+ {
+ /* Reuse the same loop both for virtual and default fields. */
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
{
- if ((*field_ptr)->vcol_info)
+ if (share->vfields && (*field_ptr)->vcol_info)
{
if (unpack_vcol_info_from_frm(thd,
outparam,
@@ -2500,8 +2515,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
}
*(vfield_ptr++)= *field_ptr;
}
+ if (share->default_fields &&
+ ((*field_ptr)->has_insert_default_function() ||
+ (*field_ptr)->has_update_default_function()))
+ *(dfield_ptr++)= *field_ptr;
}
- *vfield_ptr= 0; // End marker
+ if (share->vfields)
+ *vfield_ptr= 0; // End marker
+ if (share->default_fields)
+ *dfield_ptr= 0; // End marker
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -3924,9 +3946,6 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
DBUG_ASSERT(!auto_increment_field_not_null);
auto_increment_field_not_null= FALSE;
- if (timestamp_field)
- timestamp_field_type= timestamp_field->get_auto_set_type();
-
pos_in_table_list= tl;
clear_column_bitmaps();
@@ -5843,6 +5862,51 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl)
/**
+ Check if a table has a default function either for INSERT or UPDATE-like
+ operation
+ @retval true there is a default function
+ @retval false there is no default function
+*/
+
+bool TABLE::has_default_function(bool is_update)
+{
+ Field **dfield_ptr, *dfield;
+ bool res= false;
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ if (is_update)
+ res= dfield->has_update_default_function();
+ else
+ res= dfield->has_insert_default_function();
+ if (res)
+ return res;
+ }
+ return res;
+}
+
+
+/**
+ Add all fields that have a default function to the table write set.
+*/
+
+void TABLE::mark_default_fields_for_write()
+{
+ Field **dfield_ptr, *dfield;
+ enum_sql_command cmd= in_use->lex->sql_command;
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ if (((sql_command_flags[cmd] & CF_INSERTS_DATA) &&
+ dfield->has_insert_default_function()) ||
+ ((sql_command_flags[cmd] & CF_UPDATES_DATA) &&
+ dfield->has_update_default_function()))
+ bitmap_set_bit(write_set, dfield->field_index);
+ }
+}
+
+
+/**
@brief
Allocate space for keys
@@ -6448,6 +6512,56 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
DBUG_RETURN(0);
}
+
+/**
+ Update all DEFAULT and/or ON INSERT fields.
+
+ @details
+ Compute and set the default value of all fields with a default function.
+ There are two kinds of default functions - one is used for INSERT-like
+ operations, the other for UPDATE-like operations. Depending on the field
+ definition and the current operation one or the other kind of update
+ function is evaluated.
+
+ @retval
+ 0 Success
+ @retval
+ >0 Error occurred when storing a virtual field value
+*/
+
+int TABLE::update_default_fields()
+{
+ DBUG_ENTER("update_default_fields");
+ Field **dfield_ptr, *dfield;
+ int res= 0;
+ enum_sql_command cmd= in_use->lex->sql_command;
+
+ DBUG_ASSERT(default_field);
+
+ /* Iterate over virtual fields in the table */
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ /*
+ If an explicit default value for a filed overrides the default,
+ do not update the field with its automatic default value.
+ */
+ if (!(dfield->flags & HAS_EXPLICIT_DEFAULT))
+ {
+ if (sql_command_flags[cmd] & CF_INSERTS_DATA)
+ res= dfield->evaluate_insert_default_function();
+ if (sql_command_flags[cmd] & CF_UPDATES_DATA)
+ res= dfield->evaluate_update_default_function();
+ if (res)
+ DBUG_RETURN(res);
+ }
+ /* Unset the explicit default flag for the next record. */
+ dfield->flags&= ~HAS_EXPLICIT_DEFAULT;
+ }
+ DBUG_RETURN(res);
+}
+
+
/*
@brief Reset const_table flag