diff options
-rw-r--r-- | include/my_base.h | 2 | ||||
-rw-r--r-- | include/mysql_com.h | 2 | ||||
-rw-r--r-- | sql/handler.cc | 48 | ||||
-rw-r--r-- | sql/item_func.cc | 14 | ||||
-rw-r--r-- | sql/item_func.h | 2 | ||||
-rw-r--r-- | sql/table.cc | 50 | ||||
-rw-r--r-- | sql/table.h | 16 |
7 files changed, 60 insertions, 74 deletions
diff --git a/include/my_base.h b/include/my_base.h index 1d7db5a3a11..8a8237ce8b2 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -100,7 +100,7 @@ enum ha_key_alg { HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */ HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */ HA_KEY_ALG_FULLTEXT= 4, /* FULLTEXT (MyISAM tables) */ - HA_KEY_ALG_LONG_HASH= 5 /* long BLOB keys */ + HA_KEY_ALG_LONG_HASH= 5 /* long BLOB keys */ }; /* Storage media types */ diff --git a/include/mysql_com.h b/include/mysql_com.h index 09491ee81c8..49769395697 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -204,7 +204,7 @@ enum enum_indicator_type system versioning when table itself supports it*/ #define LONG_UNIQUE_HASH_FIELD (1<< 30) /* This field will store hash for unique - column */ + column */ #define REFRESH_GRANT (1ULL << 0) /* Refresh grant tables */ #define REFRESH_LOG (1ULL << 1) /* Start on new log file */ diff --git a/sql/handler.cc b/sql/handler.cc index f1f47a183c4..1d10f2eeffb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6277,10 +6277,8 @@ static int check_duplicate_long_entry_key(TABLE *table, handler *h, uchar *new_r { Field *hash_field; int result, error= 0; - if (!(table->key_info[key_no].user_defined_key_parts == 1 - && table->key_info[key_no].key_part->field->flags & LONG_UNIQUE_HASH_FIELD )) - return 0; - hash_field= table->key_info[key_no].key_part->field; + KEY *key_info= table->key_info + key_no; + hash_field= key_info->key_part->field; DBUG_ASSERT((table->key_info[key_no].flags & HA_NULL_PART_KEY && table->key_info[key_no].key_length == HA_HASH_KEY_LENGTH_WITH_NULL) || table->key_info[key_no].key_length == HA_HASH_KEY_LENGTH_WITHOUT_NULL); @@ -6304,13 +6302,11 @@ static int check_duplicate_long_entry_key(TABLE *table, handler *h, uchar *new_r if (!result) { bool is_same; + uint arg_count= fields_in_hash_keyinfo(key_info); + Item_func_hash * temp= (Item_func_hash *)hash_field->vcol_info->expr; + Item ** arguments= temp->arguments(); do { - Item_func_or_sum * temp= static_cast<Item_func_or_sum *>(hash_field-> - vcol_info->expr); - Item_args * t_item= static_cast<Item_args *>(temp); - uint arg_count= t_item->argument_count(); - Item ** arguments= t_item->arguments(); long diff= table->check_unique_buf - new_rec; Field * t_field; is_same= true; @@ -6366,18 +6362,9 @@ static int check_duplicate_long_entry_key(TABLE *table, handler *h, uchar *new_r return error; } /** @brief - check whether inserted/updated records breaks the + check whether inserted records breaks the unique constraint on long columns. - In the case of update we just need to check the specic key - reason for that is consider case - create table t1(a blob , b blob , x blob , y blob ,unique(a,b) - ,unique(x,y)) - and update statement like this - update t1 set a=23+a; in this case if we try to scan for - whole keys in table then index scan on x_y will return 0 - because data is same so in the case of update we take - key as a parameter in normal insert key should be -1 - @returns 0 if no duplicate else returns error + @returns 0 if no duplicate else returns error */ static int check_duplicate_long_entries(TABLE *table, handler *h, uchar *new_rec) { @@ -6385,7 +6372,8 @@ static int check_duplicate_long_entries(TABLE *table, handler *h, uchar *new_rec int result; for (uint i= 0; i < table->s->keys; i++) { - if ((result= check_duplicate_long_entry_key(table, h, new_rec, i))) + if (table->key_info[i].algorithm == HA_KEY_ALG_LONG_HASH && + (result= check_duplicate_long_entry_key(table, h, new_rec, i))) return result; } return 0; @@ -6394,7 +6382,16 @@ static int check_duplicate_long_entries(TABLE *table, handler *h, uchar *new_rec /** @brief check whether updated records breaks the unique constraint on long columns. - @returns 0 if no duplicate else returns error + In the case of update we just need to check the specic key + reason for that is consider case + create table t1(a blob , b blob , x blob , y blob ,unique(a,b) + ,unique(x,y)) + and update statement like this + update t1 set a=23+a; in this case if we try to scan for + whole keys in table then index scan on x_y will return 0 + because data is same so in the case of update we take + key as a parameter in normal insert key should be -1 + @returns 0 if no duplicate else returns error */ static int check_duplicate_long_entries_update(TABLE *table, handler *h, uchar *new_rec) { @@ -6461,16 +6458,13 @@ int handler::ha_write_row(uchar *buf) DBUG_ENTER("handler::ha_write_row"); DEBUG_SYNC_C("ha_write_row_start"); - // setup_table_hash(table); MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str); mark_trx_read_write(); increment_statistics(&SSV::ha_write_count); - if ((error= check_duplicate_long_entries(table, table->file, buf))) - { - //re_setup_table(table); + if (table->s->long_unique_table && + (error= check_duplicate_long_entries(table, table->file, buf))) DBUG_RETURN(error); - } TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_WRITE_ROW, MAX_KEY, 0, { error= write_row(buf); }) diff --git a/sql/item_func.cc b/sql/item_func.cc index 24bb3d19cc5..e336d6c51e1 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1718,6 +1718,17 @@ bool Item_func_mod::fix_length_and_dec() DBUG_RETURN(FALSE); } +inline void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str) +{ + CHARSET_INFO *cs; + uchar l[4]; + int4store(l, str->length()); + cs= str->charset(); + cs->coll->hash_sort(cs, l, sizeof(l), &nr1, &nr2); + cs= str->charset(); + cs->coll->hash_sort(cs, (uchar *)str->ptr(), str->length(), &nr1, &nr2); + sql_print_information("setiya %lu, %s", nr1, str->ptr()); +} longlong Item_func_hash::val_int() { @@ -1740,11 +1751,12 @@ longlong Item_func_hash::val_int() } -void Item_func_hash::fix_length_and_dec() +bool Item_func_hash::fix_length_and_dec() { maybe_null= 1; decimals= 0; max_length= 8; + return false; } diff --git a/sql/item_func.h b/sql/item_func.h index c80f48f15b1..38a39801e52 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1025,7 +1025,7 @@ public: Item_func_hash(THD *thd, List<Item> &item): Item_int_func(thd, item) {} longlong val_int(); - void fix_length_and_dec(); + bool fix_length_and_dec(); const Type_handler *type_handler() const { return &type_handler_long; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_hash>(thd, this); } diff --git a/sql/table.cc b/sql/table.cc index e89c1d193df..bae9b4bb1f4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1056,7 +1056,6 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, Query_arena backup_arena; Virtual_column_info *vcol= 0; StringBuffer<MAX_FIELD_WIDTH> expr_str; - uint length= 0; bool res= 1; DBUG_ENTER("parse_vcol_defs"); @@ -1332,7 +1331,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, const uchar *frm_image_end = frm_image + frm_length; uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos); const uchar *disk_buff, *strpos; - const uchar * field_properties=NULL; ulong pos, record_offset; ulong rec_buff_length; handler *handler_file= 0; @@ -2562,10 +2560,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, field= key_part->field= share->field[key_part->fieldnr-1]; key_part->type= field->key_type(); - /* Invisible Full is currently used by long uniques */ - if ((field->invisible == INVISIBLE_USER || - field->invisible == INVISIBLE_SYSTEM )&& !field->vers_sys_field()) - keyinfo->flags |= HA_INVISIBLE_KEY; + + if (field->invisible > INVISIBLE_USER && !field->vers_sys_field()) + if (keyinfo->algorithm != HA_KEY_ALG_LONG_HASH) + keyinfo->flags |= HA_INVISIBLE_KEY; if (field->null_ptr) { key_part->null_offset=(uint) ((uchar*) field->null_ptr - @@ -8770,12 +8768,11 @@ int find_field_pos_in_hash(Item *hash_item, const char * field_name) /* find total number of field in hash expr */ -int fields_in_hash_keyinfo(KEY *keyinfo) +inline int fields_in_hash_keyinfo(KEY *keyinfo) { - Item_func_or_sum * temp= static_cast<Item_func_or_sum *>( - keyinfo->key_part->field->vcol_info->expr); - Item_args * t_item= static_cast<Item_args *>(temp); - return t_item->argument_count(); + Item_func_hash * temp= (Item_func_hash *) + keyinfo->key_part->field->vcol_info->expr; + return temp->argument_count(); } inline void setup_keyinfo_hash(KEY *key_info) @@ -8805,18 +8802,18 @@ inline void re_setup_keyinfo_hash(KEY *key_info) void create_update_handler(THD *thd, TABLE *table) { handler *update_handler= NULL; - for (uint i= 0; i < table->s->keys; i++) + for (uint i= 0; i < table->s->keys; i++) + { + if (table->key_info[i].algorithm == HA_KEY_ALG_LONG_HASH) { - if (table->key_info[i].algorithm == HA_KEY_ALG_LONG_HASH) - { - update_handler= table->file->clone(table->s->normalized_path.str, - thd->mem_root); - update_handler->ha_external_lock(thd, F_RDLCK); - table->update_handler= update_handler; - return; - } + update_handler= table->file->clone(table->s->normalized_path.str, + thd->mem_root); + update_handler->ha_external_lock(thd, F_RDLCK); + table->update_handler= update_handler; + return; } - return; + } + return; } /** @@ -9336,14 +9333,3 @@ bool TABLE::export_structure(THD *thd, Row_definition_list *defs) return false; } -void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str) -{ - CHARSET_INFO *cs; - uchar l[4]; - int4store(l, str->length()); - cs= &my_charset_bin; - cs->coll->hash_sort(cs, l, sizeof(l), &nr1, &nr2); - cs= str->charset(); - cs->coll->hash_sort(cs, (uchar *)str->ptr(), str->length(), &nr1, &nr2); - sql_print_information("setiya %lu, %s", nr1, str->ptr()); -} diff --git a/sql/table.h b/sql/table.h index f1c6e269c66..f4ef7aeb8c2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -347,19 +347,14 @@ enum field_visibility_t { }; #define INVISIBLE_MAX_BITS 3 -/* We will store the info into 3rd bit if field is hash field */ -#define HASH_FIELD_MASK 15 -#define HASH_FIELD_MASK_SHIFT 4 #define HA_HASH_FIELD_LENGTH 8 #define HA_HASH_KEY_LENGTH_WITHOUT_NULL 8 #define HA_HASH_KEY_LENGTH_WITH_NULL 9 -const LEX_CSTRING ha_hash_str {STRING_WITH_LEN("HASH")}; - int find_field_pos_in_hash(Item *hash_item, const char * field_name); -int fields_in_hash_keyinfo(KEY *keyinfo); +inline int fields_in_hash_keyinfo(KEY *keyinfo); inline void setup_keyinfo_hash(KEY *key_info); @@ -367,7 +362,7 @@ inline void re_setup_keyinfo_hash(KEY *key_info); Field * field_ptr_in_hash_str(Item *hash_item, int index); -void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str); +inline void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str); void create_update_handler(THD *thd, TABLE *table); @@ -1138,10 +1133,10 @@ public: uchar *check_unique_buf; handler *update_handler; /* Handler used in case of update */ /* - In the case of write row for long unique we are unable of find - Whick key is voilated. Because we in case of duplicate hash we never reach + In the case of write row for long unique we are unable to find + which key is violated. Because we in case of duplicate hash we never reach handler write_row function. So print_error will always print that - key 0 is voilated. We store which key is voilated in this variable + key 0 is violated. We store which key is violated in this variable by default this should be initialized to -1 */ int dupp_hash_key; @@ -2969,7 +2964,6 @@ void append_unescaped(String *res, const char *pos, size_t length); void prepare_frm_header(THD *thd, uint reclength, uchar *fileinfo, HA_CREATE_INFO *create_info, uint keys, KEY *key_info); const char *fn_frm_ext(const char *name); -void calc_hash_for_unique(ulong &nr1, ulong &nr2, String *str); /* Check that the integer is in the internal */ static inline int set_zone(int nr,int min_zone,int max_zone) |