Thread Previous • Date Previous • Date Next • Thread Next |
Hello Developers, Hi this is sachin.Actually i was currently experimenting with with blob uniques in innodb there is three main problems 1.Unique blob 2.Blob Forigen key 3.Blob primary key 1. For blob unique we can simply store hash in unclustered index 2. Blob Forigen key i am currently working on it 3. Blob primary key :- for this i thought we create a 4 byte column which stores the hash of blob primary key.Internally this column will work as primary key and key for clustered index. I already successufully tested this here is my output MariaDB [sachin]> create table t4 (abc blob primary key); Query OK, 0 rows affected (0.10 sec) MariaDB [sachin]> insert into t4 values('sachin'); Query OK, 1 row affected (0.01 sec) MariaDB [sachin]> insert into t4 values('sachin'); ERROR 1062 (23000): Duplicate entry 'sachin' for key 'PRIMARY' MariaDB [sachin]> insert into t4 values('sachin setiya'); Query OK, 1 row affected (0.00 sec) MariaDB [sachin]> insert into t4 values('sachin setiya'); ERROR 1062 (23000): Duplicate entry 'sachin setiya' for key 'PRIMARY' MariaDB [sachin]> desc t4; +-------+------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------+------+-----+---------+-------+ | abc | blob | NO | PRI | NULL | | +-------+------+------+-----+---------+-------+ 1 row in set (0.01 sec) MariaDB [sachin]> select * from t4; +---------------+ | abc | +---------------+ | sachin | | sachin setiya | +---------------+ 2 rows in set (0.01 sec) @Sergei hi! Actually i invested arround 2 months in mariadb So for me now it does not matter either i got selected in gsoc i want to do work in innodb blob unique from today.Please sir allow me to do this I am including the patch file and t4.ibd and t4.frm file Regards sachin
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dfce503..efd6f22 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3244,7 +3244,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, !(sql_field->charset= find_bin_collation(sql_field->charset))) DBUG_RETURN(TRUE); - /* + /* Convert the default value from client character set into the column character set if necessary. */ @@ -3874,11 +3874,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == Field::GEOM_POINT) column->length= MAX_LEN_GEOM_POINT_FIELD; - if (!column->length) - { - my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str); - DBUG_RETURN(TRUE); - } +// if (!column->length) //change +// { +// my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str); +// DBUG_RETURN(TRUE); +// } } #ifdef HAVE_SPATIAL if (key->type == Key::SPATIAL) @@ -3992,9 +3992,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (key_part_length == 0 && (sql_field->flags & NOT_NULL_FLAG)) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), - column->field_name.str); - DBUG_RETURN(TRUE); +// my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), +// column->field_name.str); +// DBUG_RETURN(TRUE); } if (key_part_length > file->max_key_part_length() && key->type != Key::FULLTEXT) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index c51deb0..f6e94af 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1315,7 +1315,7 @@ dict_table_add_to_cache( #define BIG_ROW_SIZE 1024 ut_ad(mutex_own(&(dict_sys->mutex))); - + dict_table_add_system_columns(table, heap); table->cached = TRUE; diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 206038d..d8223d7 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -1251,7 +1251,7 @@ dict_table_open_on_name( Adds system columns to a table object. */ UNIV_INTERN void -dict_table_add_system_columns( +dict_table_add_system_columns( //work /*==========================*/ dict_table_t* table, /*!< in/out: table */ mem_heap_t* heap) /*!< in: temporary heap */ @@ -1266,16 +1266,25 @@ dict_table_add_system_columns( etc.) and as the last columns of the table memory object. The clustered index will not always physically contain all system columns. */ - +// dict_mem_table_add_col(table,heap,"DB_BLOB_HASH",DATA_INT +// ,DATA_NOT_NULL,DATA_BLOB_HASH_LEN); dict_mem_table_add_col(table, heap, "DB_ROW_ID", DATA_SYS, DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN); #if DATA_ROW_ID != 0 #error "DATA_ROW_ID != 0" #endif +// dict_mem_table_add_col(table,heap,"DB_BLOB_HASH",DATA_SYS, +// DATA_BLOB_HASH|DATA_NOT_NULL, +// DATA_BLOB_HASH_LEN); + //just a rough trick to get it working + +// if(*table->name=='y'){ dict_mem_table_add_col(table, heap, "DB_TRX_ID", DATA_SYS, DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN); +// } + #if DATA_TRX_ID != 1 #error "DATA_TRX_ID != 1" #endif @@ -1310,7 +1319,11 @@ dict_table_add_to_cache( ulint row_len; ut_ad(dict_lru_validate()); - +// bool x =false;//break +// if(x){ +// dict_mem_table_add_col(table,heap,"DB_BLOB_HASH",DATA_INT +// ,DATA_NOT_NULL,4); +// } /* The lower limit for what we consider a "big" row */ #define BIG_ROW_SIZE 1024 @@ -3075,7 +3088,7 @@ dict_index_build_internal_clust( /* Copy the fields of index */ dict_index_copy(new_index, index, table, 0, index->n_fields); - if (dict_index_is_univ(index)) { + if (dict_index_is_univ(index)) { //work /* No fixed number of fields determines an entry uniquely */ new_index->n_uniq = REC_MAX_N_FIELDS; @@ -3124,7 +3137,7 @@ dict_index_build_internal_clust( DATA_ROLL_PTR), 0); - for (i = 0; i < trx_id_pos; i++) { + for (i = 0; i < trx_id_pos; i++) {//work i think i need to do some stuff ulint fixed_size = dict_col_get_fixed_size( dict_index_get_nth_col(new_index, i), diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc index d6ed8ac..8cc59f8 100644 --- a/storage/xtradb/dict/dict0load.cc +++ b/storage/xtradb/dict/dict0load.cc @@ -2276,7 +2276,7 @@ dictionary cache. ibd_file_missing flag TRUE in the table object we return */ UNIV_INTERN dict_table_t* -dict_load_table( +dict_load_table( //work for corruped table /*============*/ const char* name, /*!< in: table name in the databasename/tablename format */ @@ -2337,7 +2337,7 @@ dict_load_table( btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); - + return(NULL); } diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index a4f6cd6..6cbe556 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -101,11 +101,11 @@ dict_mem_table_create( memcpy(table->name, name, strlen(name) + 1); table->is_system_db = dict_mem_table_is_system(table->name); table->space = (unsigned int) space; - table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS); - + table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS); //work + table->cols = static_cast<dict_col_t*>( mem_heap_alloc(heap, - (n_cols + DATA_N_SYS_COLS) + (n_cols + DATA_N_SYS_COLS)//work * sizeof(dict_col_t))); ut_d(table->magic_n = DICT_TABLE_MAGIC_N); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index e5edf76..3a8dc91 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5983,7 +5983,7 @@ ha_innobase::open( ibool par_case_name_set = FALSE; char par_case_name[FN_REFLEN]; dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE; - + ibool is_blob_primary_key=false; DBUG_ENTER("ha_innobase::open"); UT_NOT_USED(mode); @@ -6031,13 +6031,20 @@ ha_innobase::open( /* Get pointer to a table object in InnoDB dictionary cache */ ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err); - + //int number_of_columns = dict_table_get_n_user_cols(ib_table); + //if(ib_table->) + if(ib_table){ + int number_of_columns = dict_table_get_n_user_cols(ib_table); + if(!innobase_strcasecmp(ib_table->col_names,"DB_BLOB_HASH")){ + is_blob_primary_key=true; + number_of_columns--;//stodo i think we need to add flag for blob primary key to make checking easier + } if (ib_table - && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_user_cols(ib_table)) + && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)) + && table->s->stored_fields != number_of_columns) //work || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) && (table->s->fields - != dict_table_get_n_user_cols(ib_table) - 1)))) { + != dict_table_get_n_user_cols(ib_table) - 1))) { ib_logf(IB_LOG_LEVEL_WARN, "table %s contains %lu user defined columns " "in InnoDB, but %lu columns in MySQL. Please " @@ -6054,7 +6061,7 @@ ha_innobase::open( ib_table = NULL; is_part = NULL; } - + } if (UNIV_UNLIKELY(ib_table && ib_table->is_corrupt && srv_pass_corrupt_table <= 1)) { free_share(share); @@ -6254,12 +6261,12 @@ ha_innobase::open( /* Looks like MySQL-3.23 sometimes has primary key number != 0 */ primary_key = table->s->primary_key; key_used_on_scan = primary_key; - + if(!is_blob_primary_key){ if (!innobase_build_index_translation(table, ib_table, share)) { sql_print_error("Build InnoDB index translation table for" " Table %s failed", name); } - + } /* Allocate a buffer for a 'row reference'. A row reference is a string of bytes of length ref_length which uniquely specifies a row in our table. Note that MySQL may also compare two row @@ -6314,7 +6321,11 @@ ha_innobase::open( for (uint i = 0; i < table->s->keys; i++) { dict_index_t* index; index = innobase_get_index(i); - if (dict_index_is_clust(index)) { + if (dict_index_is_clust(index)) { //work + if(is_blob_primary_key){ + ref_length=4; //hash length + continue; + } ref_length = table->key_info[i].key_length; } @@ -7795,7 +7806,8 @@ build_template_field( //ut_ad(field == table->field[i]); ut_ad(clust_index->table == index->table); - +//work here we go +//todo it should get the next column defs col = dict_table_get_nth_col(index->table, i); templ = prebuilt->mysql_template + prebuilt->n_template++; @@ -8138,7 +8150,8 @@ ha_innobase::build_template( continue; } } - + if(!innobase_strcasecmp(clust_index->fields->name,"DB_BLOB_HASH")) + i++; build_template_field(prebuilt, clust_index, index, table, field, i); } @@ -11065,6 +11078,7 @@ create_table_def( ulint doc_id_col = 0; ibool has_doc_id_col = FALSE; mem_heap_t* heap; + bool is_blob_primary_key=false; DBUG_ENTER("create_table_def"); DBUG_PRINT("enter", ("table_name: %s", table_name)); @@ -11126,6 +11140,12 @@ create_table_def( table->fts->doc_col = doc_id_col; } } else { + if(form->key_info[0].key_part->length==0 && //change + form->key_info[0].key_part->key_type|MYSQL_TYPE_BLOB){ + s_cols++; + is_blob_primary_key=true; + } + table = dict_mem_table_create(table_name, 0, s_cols, flags, flags2); } @@ -11143,6 +11163,13 @@ create_table_def( table->data_dir_path = NULL; } heap = mem_heap_create(1000); + //work + //add one more column for hash + + if(is_blob_primary_key){ + dict_mem_table_add_col(table,heap,"DB_BLOB_HASH", + DATA_INT,1283,4); + } for (i = 0; i < n_cols; i++) { Field* field = form->field[i]; @@ -11222,7 +11249,7 @@ create_table_def( err = DB_ERROR; goto error_ret; } - + dict_mem_table_add_col(table, heap, field->field_name, col_type, @@ -11347,7 +11374,7 @@ create_index( the length of the key part versus the column. */ Field* field = NULL; - +//work for (ulint j = 0; j < form->s->fields; j++) { field = form->field[j]; @@ -11396,7 +11423,12 @@ create_index( } field_lengths[i] = key_part->length; - + if(form->key_info[0].key_part->length==0 && //change + form->key_info[0].key_part->key_type|MYSQL_TYPE_BLOB){ + dict_mem_index_add_field( + index,"DB_BLOB_HASH", 0); + continue; + } dict_mem_index_add_field( index, key_part->field->field_name, prefix_len); } diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h index 111664b..0f510e8 100644 --- a/storage/xtradb/include/data0type.h +++ b/storage/xtradb/include/data0type.h @@ -147,6 +147,9 @@ be less than 256 */ #define DATA_ROLL_PTR 2 /* rollback data pointer: 7 bytes */ #define DATA_ROLL_PTR_LEN 7 +//#define DATA_BLOB_HASH 3 // hash coloumn for blob primay key +//#define DATA_BLOB_HASH_LEN 4 //used as a clustered index + #define DATA_N_SYS_COLS 3 /* number of system columns defined above */ #define DATA_FTS_DOC_ID 3 /* Used as FTS DOC ID column */ diff --git a/storage/xtradb/que/que0que.cc b/storage/xtradb/que/que0que.cc index e2dc023..076785d 100644 --- a/storage/xtradb/que/que0que.cc +++ b/storage/xtradb/que/que0que.cc @@ -1030,7 +1030,7 @@ que_thr_step( que_node_print_info(node); } #endif - if (type & QUE_NODE_CONTROL_STAT) { + if (type & QUE_NODE_CONTROL_STAT) { //improve if ((thr->prev_node != que_node_get_parent(node)) && que_node_get_next(thr->prev_node)) { diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index d02e179..c58d7fb 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -137,7 +137,7 @@ row_ins_alloc_sys_fields( /*=====================*/ ins_node_t* node) /*!< in: insert node */ { - dtuple_t* row; + dtuple_t* row; //work dict_table_t* table; mem_heap_t* heap; const dict_col_t* col; @@ -3118,7 +3118,7 @@ row_ins_index_entry_set_vals( n_fields = dtuple_get_n_fields(entry); - for (i = 0; i < n_fields; i++) { + for (i = 0; i < n_fields; i++) {//see dict_field_t* ind_field; dfield_t* field; const dfield_t* row_field; @@ -3169,8 +3169,8 @@ row_ins_index_entry_step( ut_ad(dtuple_check_typed(node->row)); - row_ins_index_entry_set_vals(node->index, node->entry, node->row); - + row_ins_index_entry_set_vals(node->index, node->entry, node->row);//explore +//need to see who sets the entry in row ut_ad(dtuple_check_typed(node->entry)); err = row_ins_index_entry(node->index, node->entry, thr); @@ -3208,7 +3208,7 @@ row_ins_alloc_row_id_step( /* Fill in row id value to row */ - row_id = dict_sys_get_new_row_id(); + row_id = dict_sys_get_new_row_id(); //work dict_sys_write_row_id(node->row_id_buf, row_id); } diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 9427b20..b28e778 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -510,7 +510,15 @@ row_mysql_store_col_in_innobase_format( return(buf); } - +//this is just dummy function +int dummuy_hash(byte * ptr,int length){ + int val=0; + for(int i=0;i<length;i++){ + val =val*8+(int )*ptr; + ptr++; + } + return val; +} /**************************************************************//** Convert a row in the MySQL format to a row in the Innobase format. Note that the function to convert a MySQL format key value to an InnoDB dtuple is @@ -532,15 +540,22 @@ row_mysql_convert_row_to_innobase( const mysql_row_templ_t*templ; dfield_t* dfield; ulint i; - + ibool is_blob_primary_key=false; + ibool is_first_template=true; ut_ad(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); - ut_ad(prebuilt->mysql_template); - - for (i = 0; i < prebuilt->n_template; i++) { + ut_ad(prebuilt->mysql_template);//work + if(!innobase_strcasecmp(prebuilt->table->col_names,"DB_BLOB_HASH")){ + is_blob_primary_key =true; + } + for (i = 0; i < prebuilt->n_template; i++) { //change add one templ = prebuilt->mysql_template + i; + if(is_blob_primary_key&&is_first_template){ + dfield = dtuple_get_nth_field(row, i+1); + is_first_template=false; + }else{ dfield = dtuple_get_nth_field(row, i); - + } if (templ->mysql_null_bit_mask != 0) { /* Column may be SQL NULL */ @@ -565,6 +580,17 @@ row_mysql_convert_row_to_innobase( next_column: ; } + if(is_blob_primary_key){ + //get the first field and set the hash + dfield_t * hash_field=dtuple_get_nth_field(row,0); + dfield_t * blob_field=dtuple_get_nth_field(row,1); + byte * hash = static_cast<byte *>(mem_heap_zalloc(prebuilt->heap,4)); + mach_write_to_4(hash,dummuy_hash((byte *)blob_field->data,blob_field->len)); + //4 is hash length + hash_field->len=4; + hash_field->data=hash; + //hash_field->type + } /* If there is a FTS doc id column and it is not user supplied ( generated by server) then assign it a new doc id. */ @@ -831,7 +857,7 @@ row_create_prebuilt( prebuilt->search_tuple = dtuple_create(heap, search_tuple_n_fields); - ref = dtuple_create(heap, ref_len); + ref = dtuple_create(heap, ref_len);//work dict_index_copy_types(ref, clust_index, ref_len); @@ -1057,7 +1083,7 @@ row_get_prebuilt_insert_row( dict_table_copy_types(row, table); - ins_node_set_new_row(node, row); + ins_node_set_new_row(node, row);//explore prebuilt->ins_graph = static_cast<que_fork_t*>( que_node_get_parent( @@ -1353,7 +1379,7 @@ row_insert_for_mysql( row_get_prebuilt_insert_row(prebuilt); node = prebuilt->ins_node; - row_mysql_convert_row_to_innobase(node->row, prebuilt, mysql_rec); + row_mysql_convert_row_to_innobase(node->row, prebuilt, mysql_rec);//debug savept = trx_savept_take(trx); diff --git a/storage/xtradb/row/row0row.cc b/storage/xtradb/row/row0row.cc index be786f9..a1dd465 100644 --- a/storage/xtradb/row/row0row.cc +++ b/storage/xtradb/row/row0row.cc @@ -83,7 +83,7 @@ row_build_index_entry_low( entry, dict_index_get_n_unique_in_tree(index)); } - for (i = 0; i < entry_len; i++) { + for (i = 0; i < entry_len; i++) { //explore need to see how it works for simple const dict_field_t* ind_field = dict_index_get_nth_field(index, i); const dict_col_t* col
Attachment:
t4.frm
Description: Binary data
Attachment:
t4.ibd
Description: Binary data
Thread Previous • Date Previous • Date Next • Thread Next |