summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h2
-rw-r--r--include/mysql_com.h2
-rw-r--r--sql/handler.cc48
-rw-r--r--sql/item_func.cc14
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/table.cc50
-rw-r--r--sql/table.h16
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)