summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/field.cc56
-rw-r--r--sql/field.h55
-rw-r--r--sql/item.cc5
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/sql_show.cc37
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/table.cc78
-rw-r--r--sql/table.h13
-rw-r--r--sql/unireg.cc5
9 files changed, 85 insertions, 171 deletions
diff --git a/sql/field.cc b/sql/field.cc
index b5d971d4ce2..ba0ebb253f4 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4920,12 +4920,12 @@ void Field_double::sql_type(String &res) const
field has NOW() as default and is updated when row changes, else it is
field which has 0 as default value and is not automatically updated.
TIMESTAMP_DN_FIELD - field with NOW() as default but not set on update
- automatically (TIMESTAMP DEFAULT NOW())
+ automatically (TIMESTAMP DEFAULT NOW()), not used in Field since 10.2.2
TIMESTAMP_UN_FIELD - field which is set on update automatically but has not
NOW() as default (but it may has 0 or some other const timestamp as
default) (TIMESTAMP ON UPDATE NOW()).
TIMESTAMP_DNUN_FIELD - field which has now() as default and is auto-set on
- update. (TIMESTAMP DEFAULT NOW() ON UPDATE NOW())
+ update. (TIMESTAMP DEFAULT NOW() ON UPDATE NOW()), not used in Field since 10.2.2
NONE - field which is not auto-set on update with some other than NOW()
default value (TIMESTAMP DEFAULT 0).
@@ -4956,8 +4956,8 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
this field will be automaticly updated on insert.
*/
flags|= TIMESTAMP_FLAG;
- if (unireg_check != TIMESTAMP_DN_FIELD)
- flags|= ON_UPDATE_NOW_FLAG;
+ flags|= ON_UPDATE_NOW_FLAG;
+ DBUG_ASSERT(unireg_check == TIMESTAMP_UN_FIELD);
}
}
@@ -10561,40 +10561,24 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
- The column didn't have a default expression
*/
if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
- old_field->ptr != NULL &&
- orig_field != NULL &&
- !default_value)
+ old_field->ptr != NULL && orig_field != NULL)
{
- bool default_now= false;
- if (real_type_with_now_as_default(sql_type))
- {
- // The SQL type of the new field allows a function default:
- default_now= orig_field->has_insert_default_function();
- bool update_now= orig_field->has_update_default_function();
-
- if (default_now && update_now)
- unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- else if (default_now)
- unireg_check= Field::TIMESTAMP_DN_FIELD;
- else if (update_now)
- unireg_check= Field::TIMESTAMP_UN_FIELD;
- }
- if (!default_now) // Give a constant default
+ if (orig_field->has_update_default_function())
+ unireg_check= Field::TIMESTAMP_UN_FIELD;
+
+ /* Get the value from default_values */
+ const uchar *dv= orig_field->table->s->default_values;
+ if (!default_value && !orig_field->is_null_in_record(dv))
{
- /* Get the value from default_values */
- const uchar *dv= orig_field->table->s->default_values;
- if (!orig_field->is_null_in_record(dv))
- {
- StringBuffer<MAX_FIELD_WIDTH> tmp(charset);
- String *res= orig_field->val_str(&tmp, orig_field->ptr_in_record(dv));
- char *pos= (char*) thd->strmake(res->ptr(), res->length());
- default_value= new (thd->mem_root) Virtual_column_info();
- default_value->expr_str.str= pos;
- default_value->expr_str.length= res->length();
- default_value->expr_item=
- new (thd->mem_root) Item_string(thd, pos, res->length(), charset);
- default_value->utf8= 0;
- }
+ StringBuffer<MAX_FIELD_WIDTH> tmp(charset);
+ String *res= orig_field->val_str(&tmp, orig_field->ptr_in_record(dv));
+ char *pos= (char*) thd->strmake(res->ptr(), res->length());
+ default_value= new (thd->mem_root) Virtual_column_info();
+ default_value->expr_str.str= pos;
+ default_value->expr_str.length= res->length();
+ default_value->expr_item=
+ new (thd->mem_root) Item_string(thd, pos, res->length(), charset);
+ default_value->utf8= 0;
}
}
}
diff --git a/sql/field.h b/sql/field.h
index 45d2c3a7f00..f550dad1c6c 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -474,20 +474,6 @@ inline bool is_temporal_type_with_date(enum_field_types type)
/**
- Tests if a field real type can have "DEFAULT CURRENT_TIMESTAMP"
-
- @param type Field type, as returned by field->real_type().
- @retval true If field real type can have "DEFAULT CURRENT_TIMESTAMP".
- @retval false If field real type can not have "DEFAULT CURRENT_TIMESTAMP".
-*/
-inline bool real_type_with_now_as_default(enum_field_types type)
-{
- return type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_TIMESTAMP2 ||
- type == MYSQL_TYPE_DATETIME || type == MYSQL_TYPE_DATETIME2;
-}
-
-
-/**
Recognizer for concrete data type (called real_type for some reason),
returning true if it is one of the TIMESTAMP types.
*/
@@ -928,16 +914,9 @@ public:
}
virtual void set_default();
- bool has_insert_default_function() const
- {
- return (unireg_check == TIMESTAMP_DN_FIELD ||
- unireg_check == TIMESTAMP_DNUN_FIELD);
- }
-
bool has_update_default_function() const
{
- return (unireg_check == TIMESTAMP_UN_FIELD ||
- unireg_check == TIMESTAMP_DNUN_FIELD);
+ return unireg_check == TIMESTAMP_UN_FIELD;
}
/*
@@ -2377,21 +2356,7 @@ public:
void sql_type(String &str) const;
bool zero_pack() const { return 0; }
virtual int set_time();
- virtual void set_default()
- {
- if (has_insert_default_function())
- set_time();
- else
- Field::set_default();
- }
virtual void set_explicit_default(Item *value);
- virtual int evaluate_insert_default_function()
- {
- int res= 0;
- if (has_insert_default_function())
- res= set_time();
- return res;
- }
virtual int evaluate_update_default_function()
{
int res= 0;
@@ -2821,20 +2786,6 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{ return Field_datetime::get_TIME(ltime, ptr, fuzzydate); }
virtual int set_time();
- virtual void set_default()
- {
- if (has_insert_default_function())
- set_time();
- else
- Field::set_default();
- }
- virtual int evaluate_insert_default_function()
- {
- int res= 0;
- if (has_insert_default_function())
- res= set_time();
- return res;
- }
virtual int evaluate_update_default_function()
{
int res= 0;
@@ -3813,9 +3764,7 @@ public:
bool has_default_function() const
{
- return (unireg_check == Field::TIMESTAMP_DN_FIELD ||
- unireg_check == Field::TIMESTAMP_DNUN_FIELD ||
- unireg_check == Field::TIMESTAMP_UN_FIELD ||
+ return (unireg_check == Field::TIMESTAMP_UN_FIELD ||
unireg_check == Field::NEXT_NUMBER);
}
diff --git a/sql/item.cc b/sql/item.cc
index 420e0df71bd..b955457cf32 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -956,8 +956,7 @@ bool Item_field::check_field_expression_processor(void *arg)
{
if (field->flags & NO_DEFAULT_VALUE_FLAG)
return 0;
- if ((field->default_value && field->default_value->flags)
- || field->has_insert_default_function() || field->vcol_info)
+ if ((field->default_value && field->default_value->flags) || field->vcol_info)
{
Field *org_field= (Field*) arg;
if (field == org_field ||
@@ -8258,7 +8257,7 @@ void Item_default_value::print(String *str, enum_query_type query_type)
void Item_default_value::calculate()
{
- if (field->default_value || field->has_insert_default_function())
+ if (field->default_value)
field->set_default();
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 80287793175..13943ce8d3c 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2489,8 +2489,8 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
(*field)->default_value= vcol;
*dfield_ptr++= *field;
}
- if ((*field)->has_insert_default_function() ||
- (*field)->has_update_default_function())
+ else
+ if ((*field)->has_update_default_function())
*dfield_ptr++= *field;
}
if (vfield)
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1c9d75d06eb..a446e05d427 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1634,20 +1634,11 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
bool quoted)
{
bool has_default;
- bool has_now_default;
enum enum_field_types field_type= field->type();
- /*
- We are using CURRENT_TIMESTAMP instead of NOW because it is
- more standard
- */
- has_now_default= field->has_insert_default_function();
-
has_default= (field->default_value ||
(!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
- field->unireg_check != Field::NEXT_NUMBER &&
- !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
- && has_now_default)));
+ field->unireg_check != Field::NEXT_NUMBER));
def_value->length(0);
if (has_default)
@@ -1662,17 +1653,14 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
field->default_value->expr_str.length);
def_value->append(')');
}
+ else if (field->unireg_check)
+ def_value->append(field->default_value->expr_str.str,
+ field->default_value->expr_str.length);
else
def_value->set(field->default_value->expr_str.str,
field->default_value->expr_str.length,
&my_charset_utf8mb4_general_ci);
}
- else if (has_now_default)
- {
- def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
- if (field->decimals() > 0)
- def_value->append_parenthesized(field->decimals());
- }
else if (!field->is_null())
{ // Not null by default
char tmp[MAX_FIELD_WIDTH];
@@ -1704,13 +1692,13 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
if (quoted)
append_unescaped(def_value, def_val.ptr(), def_val.length());
else
- def_value->append(def_val.ptr(), def_val.length());
+ def_value->move(def_val);
}
else if (quoted)
- def_value->append(STRING_WITH_LEN("''"));
+ def_value->set(STRING_WITH_LEN("''"), system_charset_info);
}
else if (field->maybe_null() && quoted)
- def_value->append(STRING_WITH_LEN("NULL")); // Null as default
+ def_value->set(STRING_WITH_LEN("NULL"), system_charset_info); // Null as default
else
return 0;
@@ -1797,8 +1785,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
List<Item> field_list;
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
const char *alias;
- String type(tmp, sizeof(tmp), system_charset_info);
- String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
+ String type;
+ String def_value;
Field **ptr,*field;
uint primary_key;
KEY *key_info;
@@ -1891,12 +1879,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" "));
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
packet->append(' ');
- // check for surprises from the previous call to Field::sql_type()
- if (type.ptr() != tmp)
- type.set(tmp, sizeof(tmp), system_charset_info);
- else
- type.set_charset(system_charset_info);
+ type.set(tmp, sizeof(tmp), system_charset_info);
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
@@ -1943,6 +1927,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" NULL"));
}
+ def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
if (get_field_default_value(thd, field, &def_value, 1))
{
packet->append(STRING_WITH_LEN(" DEFAULT "));
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 364d8eda773..c9194bcb276 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9670,8 +9670,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
Old fields keep their current values, and therefore should not be
present in the set of autoupdate fields.
*/
- if ((*ptr)->default_value ||
- ((*ptr)->has_insert_default_function()))
+ if ((*ptr)->default_value)
{
*(dfield_ptr++)= *ptr;
++to->s->default_fields;
diff --git a/sql/table.cc b/sql/table.cc
index 77736430fa3..cfa950f5f9c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -66,7 +66,7 @@ LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")};
Keyword added as a prefix when parsing the defining expression for a
virtual column read from the column definition saved in the frm file
*/
-LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
+static LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
static int64 last_table_id;
@@ -1551,6 +1551,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
LEX_STRING comment;
Virtual_column_info *vcol_info= 0;
uint gis_length, gis_decimals, srid= 0;
+ Field::utype unireg_check;
if (new_frm_ver >= 3)
{
@@ -1766,22 +1767,36 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos);
}
+ /* Convert pre-10.2.2 timestamps to use Field::default_value */
+ unireg_check= (Field::utype) MTYP_TYPENR(unireg_type);
+ if (unireg_check == Field::TIMESTAMP_DNUN_FIELD)
+ unireg_check= Field::TIMESTAMP_UN_FIELD;
+ if (unireg_check == Field::TIMESTAMP_DN_FIELD)
+ unireg_check= Field::NONE;
+
*field_ptr= reg_field=
- make_field(share, &share->mem_root, record+recpos,
- (uint32) field_length,
- null_pos, null_bit_pos,
- pack_flag,
- field_type,
- charset,
- geom_type, srid,
- (Field::utype) MTYP_TYPENR(unireg_type),
- (interval_nr ?
- share->intervals+interval_nr-1 :
- (TYPELIB*) 0),
+ make_field(share, &share->mem_root, record+recpos, (uint32) field_length,
+ null_pos, null_bit_pos, pack_flag, field_type, charset,
+ geom_type, srid, unireg_check,
+ (interval_nr ? share->intervals+interval_nr-1 : NULL),
share->fieldnames.type_names[i]);
if (!reg_field) // Not supported field type
goto err;
+ if (unireg_check != (Field::utype) MTYP_TYPENR(unireg_type))
+ {
+ char buf[32];
+ if (reg_field->decimals())
+ my_snprintf(buf, sizeof(buf), "CURRENT_TIMESTAMP(%d)", reg_field->decimals());
+ else
+ strmov(buf, "CURRENT_TIMESTAMP");
+
+ reg_field->default_value= new (&share->mem_root) Virtual_column_info();
+ reg_field->default_value->stored_in_db= 1;
+ thd->make_lex_string(&reg_field->default_value->expr_str, buf, strlen(buf));
+ share->default_expressions++;
+ }
+
reg_field->field_index= i;
reg_field->comment=comment;
reg_field->vcol_info= vcol_info;
@@ -1821,13 +1836,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (share->stored_rec_length>=recpos)
share->stored_rec_length= recpos-1;
}
- if (reg_field->has_insert_default_function())
- has_insert_default_function= 1;
if (reg_field->has_update_default_function())
+ {
has_update_default_function= 1;
- if (reg_field->has_insert_default_function() ||
- reg_field->has_update_default_function())
- share->default_fields++;
+ if (!reg_field->default_value)
+ share->default_fields++;
+ }
}
*field_ptr=0; // End marker
/* Sanity checks: */
@@ -2213,16 +2227,19 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
case 1: // Generated stored field
vcol_info->stored_in_db= 1;
+ DBUG_ASSERT(!reg_field->vcol_info);
reg_field->vcol_info= vcol_info;
share->virtual_fields++;
share->virtual_stored_fields++; // For insert/load data
break;
case 2: // Default expression
vcol_info->stored_in_db= 1;
+ DBUG_ASSERT(!reg_field->default_value);
reg_field->default_value= vcol_info;
share->default_expressions++;
break;
case 3: // Field check constraint
+ DBUG_ASSERT(!reg_field->check_constraint);
reg_field->check_constraint= vcol_info;
share->field_check_constraints++;
break;
@@ -2693,14 +2710,10 @@ Virtual_column_info *unpack_vcol_info_from_frm(THD *thd,
vcol_expr->length +
parse_vcol_keyword.length + 3)))
DBUG_RETURN(0);
- memcpy(vcol_expr_str,
- (char*) parse_vcol_keyword.str,
- parse_vcol_keyword.length);
+ memcpy(vcol_expr_str, parse_vcol_keyword.str, parse_vcol_keyword.length);
str_len= parse_vcol_keyword.length;
vcol_expr_str[str_len++]= '(';
- memcpy(vcol_expr_str + str_len,
- (char*) vcol_expr->str,
- vcol_expr->length);
+ memcpy(vcol_expr_str + str_len, vcol_expr->str, vcol_expr->length);
str_len+= vcol_expr->length;
vcol_expr_str[str_len++]= ')';
vcol_expr_str[str_len++]= 0;
@@ -3045,8 +3058,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
*(dfield_ptr++)= *field_ptr;
}
else
- if ((field->has_insert_default_function() ||
- field->has_update_default_function()))
+ if (field->has_update_default_function())
*(dfield_ptr++)= *field_ptr;
}
@@ -6275,7 +6287,7 @@ void TABLE::mark_columns_needed_for_update()
to compare records and detect data change.
*/
if ((file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
- default_field && has_default_function(true))
+ default_field && s->has_update_default_function)
bitmap_union(read_set, write_set);
DBUG_VOID_RETURN;
}
@@ -6573,17 +6585,13 @@ void TABLE::mark_default_fields_for_write(bool is_insert)
for (field_ptr= default_field; *field_ptr; field_ptr++)
{
field= (*field_ptr);
- if (field->default_value)
+ if (is_insert && field->default_value)
{
- if (is_insert)
- {
- bitmap_set_bit(write_set, field->field_index);
- field->default_value->expr_item->
- walk(&Item::register_field_in_read_map, 1, 0);
- }
+ bitmap_set_bit(write_set, field->field_index);
+ field->default_value->expr_item->
+ walk(&Item::register_field_in_read_map, 1, 0);
}
- else if ((is_insert && field->has_insert_default_function()) ||
- (!is_insert && field->has_update_default_function()))
+ else if (!is_insert && field->has_update_default_function())
bitmap_set_bit(write_set, field->field_index);
}
DBUG_VOID_RETURN;
diff --git a/sql/table.h b/sql/table.h
index 4a86fc455a2..af3990a6882 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -685,7 +685,6 @@ struct TABLE_SHARE
bool virtual_stored_fields;
bool check_set_initialized;
bool has_update_default_function;
- bool has_insert_default_function;
ulong table_map_id; /* for row-based replication */
/*
@@ -1311,18 +1310,6 @@ public:
void mark_columns_used_by_check_constraints(void);
void mark_check_constraint_columns_for_read(void);
int verify_constraints(bool ignore_failure);
- /**
- 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
- */
- inline bool has_default_function(bool is_update)
- {
- return (is_update ?
- s->has_update_default_function :
- s->has_insert_default_function);
- }
inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
MY_BITMAP *write_set_arg)
{
diff --git a/sql/unireg.cc b/sql/unireg.cc
index add09411acb..d3a9b832aaf 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1039,7 +1039,10 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
field->sql_type,
field->charset,
field->geom_type, field->srid,
- field->unireg_check,
+ field->unireg_check == Field::TIMESTAMP_DNUN_FIELD
+ ? Field::TIMESTAMP_UN_FIELD
+ : field->unireg_check == Field::TIMESTAMP_DN_FIELD
+ ? Field::NONE : field->unireg_check,
field->save_interval ? field->save_interval :
field->interval,
field->field_name);