diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-06-29 21:27:34 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-06-30 11:43:02 +0200 |
commit | f93a2a3b3b5c781c164805f352e9dea948500628 (patch) | |
tree | e5a6cda5f361102c4f086594100c4d4301d4999b | |
parent | 047d762d515524a6cd572b53179ff50aeb25b0d0 (diff) | |
download | mariadb-git-f93a2a3b3b5c781c164805f352e9dea948500628.tar.gz |
various cleanups
* remove a confusing method name - Field::set_default_expression()
* remove handler::register_columns_for_write()
* rename stuff
* add asserts
* remove unlikely unlikely
* remove redundant if() conditions
* fix mark_unsupported_function() to report the most important violation
* don't scan vfield list for default values (vfields don't have defaults)
* move handling for DROP CONSTRAINT IF EXIST where it belongs
* don't protect engines from Alter_inplace_info::ALTER_ADD_CONSTRAINT
* comments
-rw-r--r-- | sql/field.cc | 22 | ||||
-rw-r--r-- | sql/field.h | 17 | ||||
-rw-r--r-- | sql/ha_partition.cc | 15 | ||||
-rw-r--r-- | sql/ha_partition.h | 1 | ||||
-rw-r--r-- | sql/handler.h | 8 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/procedure.h | 1 | ||||
-rw-r--r-- | sql/sql_alter.cc | 2 | ||||
-rw-r--r-- | sql/sql_alter.h | 8 | ||||
-rw-r--r-- | sql/sql_base.cc | 12 | ||||
-rw-r--r-- | sql/sql_base.h | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 6 | ||||
-rw-r--r-- | sql/sql_insert.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 55 | ||||
-rw-r--r-- | sql/sql_table.cc | 51 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 25 | ||||
-rw-r--r-- | sql/table.cc | 49 | ||||
-rw-r--r-- | sql/table.h | 3 | ||||
-rw-r--r-- | sql/unireg.cc | 42 |
20 files changed, 145 insertions, 183 deletions
diff --git a/sql/field.cc b/sql/field.cc index 5c9ea0ee5cd..36a5daaa165 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2291,11 +2291,22 @@ Field *Field::clone(MEM_ROOT *root, my_ptrdiff_t diff) return tmp; } -void Field::set_default_expression() +void Field::set_default() { - table->in_use->reset_arena_for_cached_items(table->expr_arena); - (void) default_value->expr_item->save_in_field(this, 0); - table->in_use->reset_arena_for_cached_items(0); + if (default_value) + { + table->in_use->reset_arena_for_cached_items(table->expr_arena); + (void) default_value->expr_item->save_in_field(this, 0); + table->in_use->reset_arena_for_cached_items(0); + return; + } + /* Copy constant value stored in s->default_values */ + my_ptrdiff_t l_offset= (my_ptrdiff_t) (table->s->default_values - + table->record[0]); + memcpy(ptr, ptr + l_offset, pack_length()); + if (maybe_null_in_table()) + *null_ptr= ((*null_ptr & (uchar) ~null_bit) | + (null_ptr[l_offset] & null_bit)); } @@ -9797,6 +9808,7 @@ bool Column_definition::check(THD *thd) /* Initialize data for a computed field */ if (vcol_info) { + DBUG_ASSERT(vcol_info->expr_item); vcol_info->set_field_type(sql_type); if (check_expression(vcol_info, "GENERATED ALWAYS AS", field_name, vcol_info->stored_in_db)) @@ -10636,7 +10648,7 @@ Create_field *Create_field::clone(MEM_ROOT *mem_root) const bool Column_definition::has_default_expression() { - return (unlikely(default_value) && + return (default_value && (!default_value->expr_item->basic_const_item() || (flags & BLOB_FLAG))); } diff --git a/sql/field.h b/sql/field.h index c19d35eb9ab..08d125d051b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -891,22 +891,7 @@ public: my_ptrdiff_t l_offset= (my_ptrdiff_t) (record - table->record[0]); return ptr + l_offset; } - void set_default_expression(); - virtual void set_default() - { - if (default_value) - { - set_default_expression(); - return; - } - /* Copy constant value stored in s->default_values */ - my_ptrdiff_t l_offset= (my_ptrdiff_t) (table->s->default_values - - table->record[0]); - memcpy(ptr, ptr + l_offset, pack_length()); - if (maybe_null_in_table()) - *null_ptr= ((*null_ptr & (uchar) ~null_bit) | - (null_ptr[l_offset] & null_bit)); - } + virtual void set_default(); bool has_insert_default_function() const { diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 09f7deb805b..400ca6129d6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3793,6 +3793,8 @@ int ha_partition::external_lock(THD *thd, int lock_type) (void) (*file)->ha_external_lock(thd, lock_type); } while (*(++file)); } + if (lock_type == F_WRLCK && m_part_info->part_expr) + m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); DBUG_RETURN(0); err_handler: @@ -3927,6 +3929,8 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type) /* Add partition to be called in reset(). */ bitmap_set_bit(&m_partitions_to_reset, i); } + if (lock_type == F_WRLCK && m_part_info->part_expr) + m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); DBUG_RETURN(error); } @@ -8459,17 +8463,6 @@ uint ha_partition::min_record_length(uint options) const return max; } -/* - Register that we want to read partition columns. This is needed to ensure - that virtual columns are properly updated before we access them. -*/ - -void ha_partition::register_columns_for_write() -{ - if (m_part_info->part_expr) - m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0); -} - /**************************************************************************** MODULE compare records ****************************************************************************/ diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 2d7e26ce724..3ea8d4a855d 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -356,7 +356,6 @@ public: virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share); virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info, uint table_changes); - virtual void register_columns_for_write(); private: int copy_partitions(ulonglong * const copied, ulonglong * const deleted); void cleanup_new_partition(uint part_count); diff --git a/sql/handler.h b/sql/handler.h index 6e16df99827..56c2c87dfd7 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1679,11 +1679,12 @@ struct Table_scope_and_contents_source_st enum_stats_auto_recalc stats_auto_recalc; bool varchar; ///< 1 if table has a VARCHAR + List<Virtual_column_info> *check_constraint_list; + /* the following three are only for ALTER TABLE, check_if_incompatible_data() */ ha_table_option_struct *option_struct; ///< structure with parsed table options ha_field_option_struct **fields_option_struct; ///< array of field option structures ha_index_option_struct **indexes_option_struct; ///< array of index option structures - List<Virtual_column_info> *constraint_list; /* The following is used to remember the old state for CREATE OR REPLACE */ TABLE *table; @@ -1937,9 +1938,9 @@ public: // ALTER TABLE for a partitioned table static const HA_ALTER_FLAGS ALTER_PARTITIONED = 1L << 31; - static const HA_ALTER_FLAGS ALTER_ADD_CONSTRAINT = 1LL << 32; + static const HA_ALTER_FLAGS ALTER_ADD_CHECK_CONSTRAINT = 1LL << 32; - static const HA_ALTER_FLAGS ALTER_DROP_CONSTRAINT = 1LL << 33; + static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1LL << 33; /** Create options (like MAX_ROWS) for the new version of table. @@ -2865,7 +2866,6 @@ public: size_t pack_frm_len); int ha_drop_partitions(const char *path); int ha_rename_partitions(const char *path); - virtual void register_columns_for_write() {} void adjust_next_insert_id_after_explicit_value(ulonglong nr); int update_auto_increment(); diff --git a/sql/item.cc b/sql/item.cc index 82c0ea7575c..7276534a7ae 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -897,7 +897,7 @@ bool Item_field::register_field_in_read_map(void *arg) TABLE *table= (TABLE *) arg; if (field->table == table || !table) bitmap_set_bit(field->table->read_set, field->field_index); - if (field->vcol_info && field->vcol_info->expr_item && + if (field->vcol_info && !bitmap_is_set(field->table->vcol_set, field->field_index)) { /* Ensure that the virtual fields is updated on read or write */ @@ -1417,7 +1417,7 @@ bool mark_unsupported_function(const char *where, void *store, uint result) mark_unsupported_func(where, "check_vcol_func_processor"); res->errors|= result; /* Store type of expression */ /* Store the name to the highest violation (normally VCOL_IMPOSSIBLE) */ - if (res->errors > old_errors) + if (result > old_errors) res->name= where ? where : ""; return false; } diff --git a/sql/procedure.h b/sql/procedure.h index b7a878344d1..be631675d5c 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -55,6 +55,7 @@ public: unsigned int size_of() { return sizeof(*this);} bool check_vcol_func_processor(void *arg) { + DBUG_ASSERT(0); // impossible return mark_unsupported_function("proc", arg, VCOL_IMPOSSIBLE); } }; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 8c14b4d3733..3592fa3cfbd 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -25,7 +25,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) alter_list(rhs.alter_list, mem_root), key_list(rhs.key_list, mem_root), create_list(rhs.create_list, mem_root), - constraint_list(rhs.constraint_list, mem_root), + check_constraint_list(rhs.check_constraint_list, mem_root), flags(rhs.flags), keys_onoff(rhs.keys_onoff), partition_names(rhs.partition_names, mem_root), diff --git a/sql/sql_alter.h b/sql/sql_alter.h index b9dc01b1e42..9e5fbaa425f 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -124,8 +124,8 @@ public: // Set for ADD [COLUMN] FIRST | AFTER static const uint ALTER_COLUMN_ORDER = 1L << 26; - static const uint ALTER_ADD_CONSTRAINT = 1L << 27; - static const uint ALTER_DROP_CONSTRAINT = 1L << 28; + static const uint ALTER_ADD_CHECK_CONSTRAINT = 1L << 27; + static const uint ALTER_DROP_CHECK_CONSTRAINT = 1L << 28; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; @@ -174,7 +174,7 @@ public: List<Key> key_list; // List of columns, used by both CREATE and ALTER TABLE. List<Create_field> create_list; - List<Virtual_column_info> constraint_list; + List<Virtual_column_info> check_constraint_list; // Type of ALTER TABLE operation. uint flags; // Enable or disable keys. @@ -203,7 +203,7 @@ public: alter_list.empty(); key_list.empty(); create_list.empty(); - constraint_list.empty(); + check_constraint_list.empty(); flags= 0; keys_onoff= LEAVE_AS_IS; num_parts= 0; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 93d21f669d1..f4af7dae207 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7817,15 +7817,17 @@ void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *table) table->field_to_fill(), if needed. */ -void switch_to_nullable_trigger_fields(Field **info, TABLE *table) +void switch_defaults_to_nullable_trigger_fields(TABLE *table) { + if (!table->default_field) + return; // no defaults + Field **trigger_field= table->field_to_fill(); - /* True if we have virtual fields and non_null fields and before triggers */ - if (info && trigger_field != table->field) + /* True if we have NOT NULL fields and BEFORE triggers */ + if (trigger_field != table->field) { - Field **field_ptr; - for (field_ptr= info; *field_ptr ; field_ptr++) + for (Field **field_ptr= table->default_field; *field_ptr ; field_ptr++) { Field *field= (*field_ptr); field->default_value->expr_item->walk(&Item::switch_to_nullable_fields_processor, 1, trigger_field); diff --git a/sql/sql_base.h b/sql/sql_base.h index b76e36d92b6..f487887ddc9 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -139,7 +139,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, const char *table_name); void close_thread_tables(THD *thd); void switch_to_nullable_trigger_fields(List<Item> &items, TABLE *); -void switch_to_nullable_trigger_fields(Field **info, TABLE *table); +void switch_defaults_to_nullable_trigger_fields(TABLE *table); bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, List<Item> &fields, List<Item> &values, diff --git a/sql/sql_class.h b/sql/sql_class.h index 31390866533..0b952203a6c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -257,7 +257,7 @@ public: class Alter_drop :public Sql_alloc { public: - enum drop_type {KEY, COLUMN, FOREIGN_KEY, CONSTRAINT_CHECK }; + enum drop_type {KEY, COLUMN, FOREIGN_KEY, CHECK_CONSTRAINT }; const char *name; enum drop_type type; bool drop_if_exists; @@ -279,8 +279,8 @@ class Alter_column :public Sql_alloc { public: const char *name; Virtual_column_info *default_value; - Alter_column(const char *par_name, Virtual_column_info *literal) - :name(par_name), default_value(literal) {} + Alter_column(const char *par_name, Virtual_column_info *expr) + :name(par_name), default_value(expr) {} /** Used to make a clone of this object for ALTER/CREATE TABLE @sa comment for Key_part_spec::clone diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7744100e78b..fcfac2ed6af 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2498,8 +2498,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) *dfield_ptr= 0; } - switch_to_nullable_trigger_fields(copy->vfield, copy); - switch_to_nullable_trigger_fields(copy->default_field, copy); + switch_defaults_to_nullable_trigger_fields(copy); /* Adjust in_use for pointing to client thread */ copy->in_use= client_thd; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index bca650105a9..bc3e06c6192 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2991,7 +2991,7 @@ public: bool add_constraint(LEX_STRING *name, Virtual_column_info *constr) { constr->name= *name; - alter_info.constraint_list.push_back(constr); + alter_info.check_constraint_list.push_back(constr); return false; } void set_command(enum_sql_command command, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index d0766f41fea..b45f85528a6 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -104,46 +104,21 @@ static const char *end_paren_str= ")"; static const char *begin_paren_str= "("; static const char *comma_str= ","; -int get_partition_id_list_col(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_list(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_range_col(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_range(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -static int get_part_id_charset_func_part(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -static int get_part_id_charset_func_subpart(partition_info *part_info, - uint32 *part_id); -int get_partition_id_hash_nosub(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_key_nosub(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_linear_hash_nosub(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_linear_key_nosub(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_with_sub(partition_info *part_info, - uint32 *part_id, - longlong *func_value); -int get_partition_id_hash_sub(partition_info *part_info, - uint32 *part_id); -int get_partition_id_key_sub(partition_info *part_info, - uint32 *part_id); -int get_partition_id_linear_hash_sub(partition_info *part_info, - uint32 *part_id); -int get_partition_id_linear_key_sub(partition_info *part_info, - uint32 *part_id); +static int get_partition_id_list_col(partition_info *, uint32 *, longlong *); +static int get_partition_id_list(partition_info *, uint32 *, longlong *); +static int get_partition_id_range_col(partition_info *, uint32 *, longlong *); +static int get_partition_id_range(partition_info *, uint32 *, longlong *); +static int get_part_id_charset_func_part(partition_info *, uint32 *, longlong *); +static int get_part_id_charset_func_subpart(partition_info *, uint32 *); +static int get_partition_id_hash_nosub(partition_info *, uint32 *, longlong *); +static int get_partition_id_key_nosub(partition_info *, uint32 *, longlong *); +static int get_partition_id_linear_hash_nosub(partition_info *, uint32 *, longlong *); +static int get_partition_id_linear_key_nosub(partition_info *, uint32 *, longlong *); +static int get_partition_id_with_sub(partition_info *, uint32 *, longlong *); +static int get_partition_id_hash_sub(partition_info *part_info, uint32 *part_id); +static int get_partition_id_key_sub(partition_info *part_info, uint32 *part_id); +static int get_partition_id_linear_hash_sub(partition_info *part_info, uint32 *part_id); +static int get_partition_id_linear_key_sub(partition_info *part_info, uint32 *part_id); static uint32 get_next_partition_via_walking(PARTITION_ITERATOR*); static void set_up_range_analysis_info(partition_info *part_info); static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 30589b80fe2..83aae3f5038 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4168,16 +4168,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } /* Check table level constraints */ - create_info->constraint_list= &alter_info->constraint_list; + create_info->check_constraint_list= &alter_info->check_constraint_list; { uint nr= 1; - List_iterator_fast<Virtual_column_info> c_it(alter_info->constraint_list); + List_iterator_fast<Virtual_column_info> c_it(alter_info->check_constraint_list); Virtual_column_info *check; while ((check= c_it++)) { if (!check->name.length) make_unique_constraint_name(thd, &check->name, - &alter_info->constraint_list, + &alter_info->check_constraint_list, &nr); if (check_string_char_length(&check->name, 0, NAME_CHAR_LEN, @@ -5861,7 +5861,19 @@ drop_create_field: } } } - else /* Alter_drop::KEY */ + else if (drop->type == Alter_drop::CHECK_CONSTRAINT) + { + for (uint i=0; i < table->s->table_check_constraints; i++) + { + if (my_strcasecmp(system_charset_info, drop->name, + table->check_constraints[i]->name.str) == 0) + { + remove_drop= FALSE; + break; + } + } + } + else /* Alter_drop::KEY and Alter_drop::FOREIGN_KEY */ { uint n_key; if (drop->type != Alter_drop::FOREIGN_KEY) @@ -6237,10 +6249,10 @@ static bool fill_alter_inplace_info(THD *thd, /* Check for: ALTER TABLE FORCE, ALTER TABLE ENGINE and OPTIMIZE TABLE. */ if (alter_info->flags & Alter_info::ALTER_RECREATE) ha_alter_info->handler_flags|= Alter_inplace_info::RECREATE_TABLE; - if (alter_info->flags & Alter_info::ALTER_ADD_CONSTRAINT) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_ADD_CONSTRAINT; - if (alter_info->flags & Alter_info::ALTER_DROP_CONSTRAINT) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_CONSTRAINT; + if (alter_info->flags & Alter_info::ALTER_ADD_CHECK_CONSTRAINT) + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_ADD_CHECK_CONSTRAINT; + if (alter_info->flags & Alter_info::ALTER_DROP_CHECK_CONSTRAINT) + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_DROP_CHECK_CONSTRAINT; /* If we altering table with old VARCHAR fields we will be automatically @@ -7838,7 +7850,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, drop_it.rewind(); while ((drop=drop_it++)) { - if (drop->type == Alter_drop::CONSTRAINT_CHECK && + if (drop->type == Alter_drop::CHECK_CONSTRAINT && !my_strcasecmp(system_charset_info, check->name.str, drop->name)) { drop_it.remove(); @@ -7850,7 +7862,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } /* Add new constraints */ - new_constraint_list.append(&alter_info->constraint_list); + new_constraint_list.append(&alter_info->check_constraint_list); if (alter_info->drop_list.elements) { @@ -7860,13 +7872,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, switch (drop->type) { case Alter_drop::KEY: case Alter_drop::COLUMN: - case Alter_drop::CONSTRAINT_CHECK: - if (drop->drop_if_exists) - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_CANT_DROP_FIELD_OR_KEY, - ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY), - drop->name); - else + case Alter_drop::CHECK_CONSTRAINT: my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), alter_info->drop_list.head()->name); goto err; @@ -7914,7 +7920,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, rc= FALSE; alter_info->create_list.swap(new_create_list); alter_info->key_list.swap(new_key_list); - alter_info->constraint_list.swap(new_constraint_list); + alter_info->check_constraint_list.swap(new_constraint_list); err: DBUG_RETURN(rc); } @@ -8960,13 +8966,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, // Ask storage engine whether to use copy or in-place enum_alter_inplace_result inplace_supported= - HA_ALTER_INPLACE_NOT_SUPPORTED; - if (!(ha_alter_info.handler_flags & - Alter_inplace_info::ALTER_ADD_CONSTRAINT) || - (thd->variables.option_bits & OPTION_NO_CHECK_CONSTRAINT_CHECKS)) - inplace_supported= - table->file->check_if_supported_inplace_alter(altered_table, - &ha_alter_info); + table->file->check_if_supported_inplace_alter(altered_table, + &ha_alter_info); switch (inplace_supported) { case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2e3d2b86eb1..d1b8ac690d2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1857,7 +1857,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr expr_or_default set_expr_or_default - geometry_function signed_literal + geometry_function signed_literal expr_or_literal opt_escape sp_opt_default simple_ident_nospvar simple_ident_q @@ -6174,7 +6174,7 @@ field_list_item: column_def: field_spec opt_check_constraint - { $$= $1; Lex->last_field->check_constraint= $2; } + { $$= $1; $$->check_constraint= $2; } | field_spec references { $$= $1; } ; @@ -6399,11 +6399,7 @@ parse_vcol_expr: when reading a '*.frm' file. Prevent the end user from invoking this command. */ - if (!Lex->parse_vcol_expr) - { - my_message(ER_SYNTAX_ERROR, ER_THD(thd, ER_SYNTAX_ERROR), MYF(0)); - MYSQL_YYABORT; - } + MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr); Lex->last_field->vcol_info= $2; } ; @@ -6438,18 +6434,15 @@ virtual_column_func: } ; +expr_or_literal: column_default_non_parenthesized_expr | signed_literal ; + column_default_expr: virtual_column_func - | remember_name column_default_non_parenthesized_expr opt_impossible_action remember_end + | remember_name expr_or_literal opt_impossible_action remember_end { if (!($$= add_virtual_expression(thd, $1, (uint) ($4- $1), $2))) MYSQL_YYABORT; } - | signed_literal - { - if (!($$= add_virtual_expression(thd, "literal", 6, $1))) - MYSQL_YYABORT; - } ; /* This is to force remember_end to look at next token */ @@ -7792,7 +7785,7 @@ alter_list_item: } | ADD constraint_def { - Lex->alter_info.flags|= Alter_info::ALTER_ADD_CONSTRAINT; + Lex->alter_info.flags|= Alter_info::ALTER_ADD_CHECK_CONSTRAINT; } | CHANGE opt_column opt_if_exists_table_element field_ident field_spec opt_place @@ -7824,12 +7817,12 @@ alter_list_item: { LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) - Alter_drop(Alter_drop::CONSTRAINT_CHECK, + Alter_drop(Alter_drop::CHECK_CONSTRAINT, $4.str, $3)); if (ad == NULL) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); - lex->alter_info.flags|= Alter_info::ALTER_DROP_CONSTRAINT; + lex->alter_info.flags|= Alter_info::ALTER_DROP_CHECK_CONSTRAINT; } | DROP FOREIGN KEY_SYM opt_if_exists_table_element field_ident { diff --git a/sql/table.cc b/sql/table.cc index eff6955b278..1236666a5c6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -930,7 +930,7 @@ static void mysql57_calculate_null_position(TABLE_SHARE *share, if ((strpos[10] & MYSQL57_GENERATED_FIELD)) { - /* Skip virtual not stored field */ + /* Skip virtual (not stored) generated field */ bool stored_in_db= (bool) (uint) (vcol_screen_pos[3]); vcol_screen_pos+= (uint2korr(vcol_screen_pos + 1) + MYSQL57_GCOL_HEADER_SIZE); @@ -980,14 +980,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, uint new_frm_ver, field_pack_length, new_field_pack_flag; uint interval_count, interval_parts, read_length, int_length; uint db_create_options, keys, key_parts, n_length; - uint com_length, null_bit_pos, mysql_vcol_null_bit_pos, bitmap_count; + uint com_length, null_bit_pos, mysql57_vcol_null_bit_pos, bitmap_count; uint extra_rec_buf_length; uint i; bool use_hash, mysql57_null_bits= 0; char *keynames, *names, *comment_pos; const uchar *forminfo, *extra2; const uchar *frm_image_end = frm_image + frm_length; - uchar *record, *null_flags, *null_pos, *mysql_vcol_null_pos; + uchar *record, *null_flags, *null_pos, *mysql57_vcol_null_pos; const uchar *disk_buff, *strpos; ulong pos, record_offset; ulong rec_buff_length; @@ -1542,10 +1542,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, Calculate the position for them. */ mysql57_null_bits= 1; - mysql_vcol_null_pos= null_pos; - mysql_vcol_null_bit_pos= null_bit_pos; - mysql57_calculate_null_position(share, &mysql_vcol_null_pos, - &mysql_vcol_null_bit_pos, + mysql57_vcol_null_pos= null_pos; + mysql57_vcol_null_bit_pos= null_bit_pos; + mysql57_calculate_null_position(share, &mysql57_vcol_null_pos, + &mysql57_vcol_null_bit_pos, strpos, vcol_screen_pos); } @@ -1693,7 +1693,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (opt_interval_id) interval_nr= (uint) vcol_screen_pos[3]; vcol_info->expr_str.length= vcol_expr_length; - vcol_info->utf8= 0; + vcol_info->utf8= 0; // before 10.2.1 the charset was unknown vcol_screen_pos+= vcol_info_length; share->virtual_fields++; } @@ -1772,8 +1772,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (mysql57_null_bits && vcol_info && !vcol_info->stored_in_db) { - swap_variables(uchar*, null_pos, mysql_vcol_null_pos); - swap_variables(uint, null_bit_pos, mysql_vcol_null_bit_pos); + swap_variables(uchar*, null_pos, mysql57_vcol_null_pos); + swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos); } *field_ptr= reg_field= @@ -1813,8 +1813,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (mysql57_null_bits && vcol_info && !vcol_info->stored_in_db) { /* MySQL 5.7 has null bits last */ - swap_variables(uchar*, null_pos, mysql_vcol_null_pos); - swap_variables(uint, null_bit_pos, mysql_vcol_null_bit_pos); + swap_variables(uchar*, null_pos, mysql57_vcol_null_pos); + swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos); } if (f_no_default(pack_flag)) @@ -1847,8 +1847,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (mysql57_null_bits) { /* We want to store the value for the last bits */ - swap_variables(uchar*, null_pos, mysql_vcol_null_pos); - swap_variables(uint, null_bit_pos, mysql_vcol_null_bit_pos); + swap_variables(uchar*, null_pos, mysql57_vcol_null_pos); + swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos); DBUG_ASSERT((null_pos + (null_bit_pos + 7) / 8) <= share->field[0]->ptr); } @@ -2212,7 +2212,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, vcol_info->stored_in_db= 0; switch (type) { - case 0: // Virtual computed field + case 0: // Generated virtual field { uint recpos; reg_field->vcol_info= vcol_info; @@ -2224,7 +2224,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->stored_rec_length= recpos-1; break; } - case 1: // Virtual stored field + case 1: // Generated stored field vcol_info->stored_in_db= 1; reg_field->vcol_info= vcol_info; share->virtual_fields++; @@ -2542,9 +2542,7 @@ void TABLE_SHARE::free_frm_image(const uchar *frm) FALSE Otherwise */ -static bool fix_vcol_expr(THD *thd, - TABLE *table, - Field *field, +static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field, Virtual_column_info *vcol) { Item* func_expr= vcol->expr_item; @@ -2575,7 +2573,7 @@ static bool fix_vcol_expr(THD *thd, my_error(ER_ERROR_EVALUATING_EXPRESSION, MYF(0), vcol->expr_str); goto end; } - /* fix_fields could change the expression */ + /* fix_fields could've changed the expression */ func_expr= vcol->expr_item; /* Number of columns will be checked later */ @@ -2649,8 +2647,8 @@ end: special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED @note - Before passing 'vcol_expr" to the parser the function embraces it in - parenthesis and prepands it a special keyword. + Before passing 'vcol_expr' to the parser the function wraps it in + parentheses and prepends a special keyword. @retval Virtual_column_info* If a success @@ -3072,8 +3070,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, *dfield_ptr= 0; // End marker /* Update to use trigger fields */ - switch_to_nullable_trigger_fields(outparam->vfield, outparam); - switch_to_nullable_trigger_fields(outparam->default_field, outparam); + switch_defaults_to_nullable_trigger_fields(outparam); /* Copy table level constraints to check_constraint_ptr */ for (i= 0 ; @@ -3695,7 +3692,7 @@ void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, fileinfo[41]= (uchar) (csid >> 8); int2store(fileinfo+42, create_info->stats_sample_pages & 0xffff); fileinfo[44]= (uchar) create_info->stats_auto_recalc; - int2store(fileinfo+45, (create_info->constraint_list->elements+ + int2store(fileinfo+45, (create_info->check_constraint_list->elements+ create_info->field_check_constraints)); int4store(fileinfo+47, key_length); tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store @@ -6269,7 +6266,6 @@ void TABLE::mark_columns_needed_for_update() file->column_bitmaps_signal(); } } - file->register_columns_for_write(); if (default_field) mark_default_fields_for_write(FALSE); /* Mark all virtual columns needed for update */ @@ -6320,7 +6316,6 @@ void TABLE::mark_columns_needed_for_insert() /* Mark virtual columns for insert */ if (vfield) mark_virtual_columns_for_write(TRUE); - file->register_columns_for_write(); if (check_constraints) mark_check_constraint_columns_for_read(); DBUG_VOID_RETURN; diff --git a/sql/table.h b/sql/table.h index b217494685b..651fab7c4cb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -567,7 +567,6 @@ struct TABLE_SHARE TYPELIB *intervals; /* pointer to interval info */ mysql_mutex_t LOCK_ha_data; /* To protect access to ha_data */ mysql_mutex_t LOCK_share; /* To protect TABLE_SHARE */ - MY_BITMAP *check_set; /* Fields used by check constrant */ TDC_element *tdc; @@ -589,6 +588,7 @@ struct TABLE_SHARE LEX_STRING comment; /* Comment about table */ CHARSET_INFO *table_charset; /* Default charset of string fields */ + MY_BITMAP *check_set; /* Fields used by check constrant */ MY_BITMAP all_set; /* Key which is used for looking-up table in table cache and in the list @@ -1087,6 +1087,7 @@ public: MY_BITMAP *read_set, *write_set, *rpl_write_set; /* Set if using virtual fields */ MY_BITMAP *vcol_set, *def_vcol_set; + /* On INSERT: fields that the user specified a value for */ MY_BITMAP *has_value_set; /* diff --git a/sql/unireg.cc b/sql/unireg.cc index 45c55fa1af9..1c1a97b4172 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -40,15 +40,17 @@ #define ALLOCA_THRESHOLD 2048 static uint pack_keys(uchar *,uint, KEY *, ulong); -static bool pack_header(THD *, uchar *, List<Create_field> &, HA_CREATE_INFO *info, ulong, handler *); +static bool pack_header(THD *, uchar *, List<Create_field> &, HA_CREATE_INFO *, + ulong, handler *); static uint get_interval_id(uint *,List<Create_field> &, Create_field *); static bool pack_fields(uchar **, List<Create_field> &, HA_CREATE_INFO*, ulong); static void pack_constraints(uchar **buff, List<Virtual_column_info> *constr); static size_t packed_fields_length(List<Create_field> &); -static size_t packed_constraints_length(THD *thd, HA_CREATE_INFO* info, - List<Virtual_column_info> *constr); -static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, ulong); +static size_t packed_constraints_length(THD *, HA_CREATE_INFO*, + List<Virtual_column_info> *); +static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint, + ulong); /* write the length as @@ -512,7 +514,6 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo, */ static bool add_expr_length(THD *thd, Virtual_column_info **v_col_ptr, - HA_CREATE_INFO *info, size_t *length) { Virtual_column_info *v_col= *v_col_ptr; @@ -525,8 +526,11 @@ static bool add_expr_length(THD *thd, Virtual_column_info **v_col_ptr, if (!v_col->utf8) { /* + This v_col comes from the parser (e.g. CREATE TABLE) or + from old (before 10.2.1) frm. + We have to create a new Virtual_column_info as for alter table, - the current one may be shared with the original tables + the current one may be shared with the original table. */ Virtual_column_info *new_vcol= new (thd->mem_root) Virtual_column_info(); LEX_STRING to; @@ -611,10 +615,15 @@ static bool pack_header(THD *thd, uchar *forminfo, n_length=2L; create_info->field_check_constraints= 0; - expression_length= packed_constraints_length(thd, create_info, - create_info->constraint_list); - if (!expression_length && create_info->constraint_list->elements) - DBUG_RETURN(1); // Wrong characterset + if (create_info->check_constraint_list->elements) + { + expression_length= packed_constraints_length(thd, create_info, + create_info->check_constraint_list); + if (!expression_length) + DBUG_RETURN(1); // Wrong characterset + } + else + expression_length= 0; /* Check fields */ List_iterator<Create_field> it(create_fields); @@ -625,15 +634,12 @@ static bool pack_header(THD *thd, uchar *forminfo, ER_TOO_LONG_FIELD_COMMENT, field->field_name)) DBUG_RETURN(1); - if (add_expr_length(thd, &field->vcol_info, create_info, - &expression_length)) + if (add_expr_length(thd, &field->vcol_info, &expression_length)) DBUG_RETURN(1); if (field->has_default_expression()) - if (add_expr_length(thd, &field->default_value, create_info, - &expression_length)) + if (add_expr_length(thd, &field->default_value, &expression_length)) DBUG_RETURN(1); - if (add_expr_length(thd, &field->check_constraint, create_info, - &expression_length)) + if (add_expr_length(thd, &field->check_constraint, &expression_length)) DBUG_RETURN(1); totlength+= field->length; @@ -825,7 +831,7 @@ static size_t packed_constraints_length(THD *thd, HA_CREATE_INFO *info, Virtual_column_info *check; while ((check= it++)) - if (add_expr_length(thd, it.ref(), info, &length)) + if (add_expr_length(thd, it.ref(), &length)) return 0; return length; } @@ -984,7 +990,7 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields, if (field->check_constraint) pack_expression(&buff, field->check_constraint, field_nr, 3); } - pack_constraints(&buff, create_info->constraint_list); + pack_constraints(&buff, create_info->check_constraint_list); } *buff_arg= buff; DBUG_RETURN(0); |