diff options
-rw-r--r-- | sql/field.cc | 56 | ||||
-rw-r--r-- | sql/field.h | 55 | ||||
-rw-r--r-- | sql/item.cc | 5 | ||||
-rw-r--r-- | sql/sql_insert.cc | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 37 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/table.cc | 78 | ||||
-rw-r--r-- | sql/table.h | 13 | ||||
-rw-r--r-- | sql/unireg.cc | 5 |
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(®_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); |