← Back to team overview

maria-developers team mailing list archive

Re: InnoDB blob for primary key

 

Hi Sergei!
As I already told you i was building prototype.It is some what completed
apart from one thing comparing of two field values. the difficulty is how
to get data length of field  from table->record[1]. I will try to solve it.
One more thing actually i got how mysql hide field. For example  condsider three
fields hash,data,data. mysql field pointer point at second field not at hash
field and hash field ptr is stored in  table->hash_field
can we do something similar to store hash fields(if we make array of hashes in
case of more than one unique).But will adding member variable cause problem?
what do you think?
Regards
sachin

On Fri, Apr 15, 2016 at 6:37 PM, Sachin Setia <sachinsetia1001@xxxxxxxxx> wrote:
> Hi Sergei!
>
> Actually I was going through the mysql source code for unique long constraints
> in file sql_tmp_table.cc in function create_tmp_table they make a new field
> and a new key(hash_key) and pass this table obejct to storage
> engine.They actually
> refer this field as a hash field
> On the time of insert they call bool check_unique_constraint(TABLE
> *table) function
> which first calculate the hash and store it in field then they see for duplicate
> hash and retrive ha_index_next_same if records are not same then record
>
> We can do the same thing in mariadb by adding one more field and key in
> mysql_prepare_create_table in this we check for blob with unlimited
> length or varchar for length
> greater then internal storage engine by doing this in
> mysql_prepare_create_table there
> will be no issues of frm file inconsistance.
>
> In case of insert first we will fill the hash field in fill_record
> function of sql_base.cc
> by first calculating the hash. Then we will retrive the index map
> using ha_index_read_map
> if returened value is zero then we will comapare two records and if
> they match then we will through error
> I am not sure where to place this code either in fill_record or later
> Or i can simple just
> fill hash in field in fill_record and then check for duplicates later on.
>
> Current I am not sure how to hide columns from user.Sir, can you
> suggest me where to look
>
> But there is one problem we can make unique key by this approch but
> not primary key because primary key
> is clustered and hashes can collide so i think we can't use hash field
> as primary key. To overcome this problem
> I have one idea instead of storing just hash we can make hash field
> length 10 bytes and in last two bytes
> we can store short int which tells how much time hash is repeated this
> can make hash unique
> in case of collusion. And also we are not doing more computation
> because we already retrive
> all records with same hashes.
> What do you think of this idea?.
> And there is one more problem how to make it foreign key.
>
> Will send you a prototype code tomorrow.
> Regards
> sachin
>
> On Fri, Apr 15, 2016 at 12:23 AM, Sergei Golubchik <serg@xxxxxxxxxxx> wrote:
>> Hi, Sachin!
>>
>> On Apr 13, Sachin Setia wrote:
>>> Hello Sergei
>>> Sorry I did not see your mail. Actually i was thinking something like
>>> this before implementing the prototype but if i am more closer to
>>> innodb the more performance i will i get. I will definitively think
>>> about it.
>>
>> Great!
>>
>> Could you please tell me (mailing list, that is) what you think before
>> next Monday (before April 18h, that is)?
>>
>> Regards,
>> Sergei
>> Chief Architect MariaDB
>> and security@xxxxxxxxxxx
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ac2162b..291a3e2 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8906,7 +8906,9 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
   List_iterator_fast<Item> v(values);
   List<TABLE> tbl_list;
   Item *value;
-  Field *field;
+  Field *field,hash_field;
+  int diff,src_length,dest_length,res;
+  	Field * blob_field;
   bool abort_on_warning_saved= thd->abort_on_warning;
   uint autoinc_index= table->next_number_field
                         ? table->next_number_field->field_index
@@ -8929,12 +8931,18 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
     Reset the table->auto_increment_field_not_null as it is valid for
     only one row.
   */
-  table->auto_increment_field_not_null= FALSE;
+  table->auto_increment_field_not_null= FALSE; 
+  hash_field=*ptr++; //change
+  hash_field->null_bit=0;
+//  field->null_offset();
+	//just random number for hash
+  field->store(random(),true);
+
   while ((field = *ptr++) && ! thd->is_error())
   {
     /* Ensure that all fields are from the same table */
     DBUG_ASSERT(field->table == table);
-
+	blob_field=field;
     value=v++;
     if (field->field_index == autoinc_index)
       table->auto_increment_field_not_null= TRUE;
@@ -8956,6 +8964,31 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
         goto err;
     field->set_explicit_default(value);
   }
+  table->file->ha_index_init(0,0);
+ res = table->file->ha_index_read_map(table->record[1],hash_field->ptr,HA_WHOLE_KEY,HA_READ_KEY_EXACT);
+  while(!res){
+	  //compare the record if not sure how to compare it so just assume it works
+		 diff = table->record[1]-table->record[0];
+		 src_length = blob_field->data_length();
+		 //dest_length = blob_field->data_length(table->record[1]); // i  dont know how to get the length from record 1
+		 // so i am enable to do this
+		 // then we can comapare records using 
+		 //field->cmp_max
+ //this is mysql code
+	/*  if (!(table->distinct ?
+          table_rec_cmp(table) :
+          group_rec_cmp(table->group, table->record[0], table->record[1])))
+      return false; // skip it
+    res= table->file->ha_index_next_same(table->record[1],
+                                         table->hash_field->ptr,
+                                         sizeof(hash)); */
+	  //fetch the next record 
+	  res= table->file->ha_index_next_same(table->record[1],
+                                         hash_field->ptr,
+                                         8);
+	
+  }
+  table->file->ha_index_end();
   /* Update virtual fields*/
   thd->abort_on_warning= FALSE;
   if (table->vfield &&
@@ -8964,6 +8997,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
                                               VCOL_UPDATE_FOR_WRITE))
     goto err;
   thd->abort_on_warning= abort_on_warning_saved;
+    
   DBUG_RETURN(thd->is_error());
 
 err:
@@ -9074,7 +9108,7 @@ my_bool mysql_rm_tmp_tables(void)
             handler_file->ha_delete_table(filePathCopy);
             delete handler_file;
           }
-          free_table_share(&share);
+          free_table_share(&share); 
         }
         /*
           File can be already deleted by tmp_table.file->delete_table().
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7122fbb..4ac06b0 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -212,11 +212,11 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
                table_list->view_db.str, table_list->view_name.str);
       DBUG_RETURN(-1);
     }
-    if (values.elements != table->s->fields)
-    {
-      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
-      DBUG_RETURN(-1);
-    }
+//    if (values.elements != table->s->fields) //change
+//    {
+//      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
+//      DBUG_RETURN(-1);
+//    }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
     Field_iterator_table_ref field_it;
     field_it.set(table_list);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index dfce503..f6b0732 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3208,6 +3208,38 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
                            handler *file, KEY **key_info_buffer,
                            uint *key_count, int create_table_mode)
 {
+//	Create_field * t_create_field = (Create_field *)my_malloc(sizeof(Create_field),MYF(MY_WME));
+//	//Key t_key;
+//	t_create_field->field_name="blob_hash";
+//	t_create_field->sql_type=MYSQL_TYPE_LONGLONG;
+//	/* Create_field() :change(0), after(0), comment(null_lex_str),
+//                  def(0), on_update(0), sql_type(MYSQL_TYPE_NULL),
+//                  flags(0), pack_length(0), key_length(0), interval(0),
+//                  srid(0), geom_type(Field::GEOM_GEOMETRY),
+//                  field(0), option_list(NULL), option_struct(NULL),
+//                  create_if_not_exists(false), vcol_info(0),
+//                  stored_in_db(true)
+//	 * */
+//	t_create_field->after=NULL;
+//	t_create_field->change=NULL;
+//	t_create_field->comment=null_lex_str;
+//	t_create_field->def=0;
+//	t_create_field->on_update=0;
+//	t_create_field->interval=0;
+//	t_create_field->field=0;
+//	t_create_field->vcol_info=0;
+//	t_create_field->option_list=NULL;
+//	t_create_field->option_struct=NULL;
+//	t_create_field->stored_in_db=true;
+//	t_create_field->geom_type=Field::GEOM_GEOMETRY;
+	Create_field * t_create_field = new(thd->mem_root) Create_field();
+	t_create_field->sql_type=MYSQL_TYPE_LONGLONG;
+	t_create_field->field_name="unique_blob_hash";
+	t_create_field->flags=NOT_NULL_FLAG;
+	t_create_field->length=t_create_field->char_length=8;
+	t_create_field->charset=NULL;
+	//t_create_field->
+	alter_info->create_list.push_front(t_create_field);
   const char	*key_name;
   Create_field	*sql_field,*dup_field;
   uint		field,null_fields,blob_columns,max_key_length;
@@ -3227,7 +3259,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
   null_fields=blob_columns=0;
   create_info->varchar= 0;
   max_key_length= file->max_key_length();
-
+//	sql_field=it++;
+//	t_create_field->charset=sql_field->charset;
+//	t_create_field->comment=sql_field->comment;
+//	it.rewind();
   for (field_no=0; (sql_field=it++) ; field_no++)
   {
     CHARSET_INFO *save_cs;
@@ -3874,11 +3909,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)
@@ -4174,6 +4209,20 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
                           thd->mem_root))
       DBUG_RETURN(TRUE);
 
+	//just override the blob key with hash //change
+	
+	KEY *t_hash_key = &key_info[-1]; 
+	//t_hash_key->flags = HA_NOSAME;
+	t_hash_key->algorithm=HA_KEY_ALG_UNDEF;
+	t_hash_key->name="blob_hash_key";
+	t_hash_key->key_length=8;
+	//t_hash_key->key_part->field = t_create_field;
+	t_hash_key->key_part->key_type=t_create_field->pack_flag;
+	t_hash_key->key_part->length=8;
+	t_hash_key->key_part->fieldnr=0;
+	t_hash_key->key_part->null_bit=0;
+	t_hash_key->key_part->offset=0;
+	
   DBUG_RETURN(FALSE);
 }
 

Follow ups

References