Пример #1
0
ulong hp_rec_hashnr(HP_KEYDEF *keydef, const uchar *rec)
{
  ulong nr=1, nr2=4;
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    uchar *pos=(uchar*) rec+seg->start,*end=pos+seg->length;
    if (seg->null_bit)
    {
      if (rec[seg->null_pos] & seg->null_bit)
      {
	nr^= (nr << 1) | 1;
	continue;
      }
    }
    if (seg->type == HA_KEYTYPE_TEXT)
    {
      const CHARSET_INFO *cs= seg->charset;
      size_t char_length= seg->length;
      if (cs->mbmaxlen > 1)
      {
        char_length= my_charpos(cs, pos, pos + char_length,
                                char_length / cs->mbmaxlen);
        set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
      }
      cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
    }
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
    {
      const CHARSET_INFO *cs= seg->charset;
      uint pack_length= seg->bit_start;
      size_t length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
      if (cs->mbmaxlen > 1)
      {
        size_t char_length;
        char_length= my_charpos(cs, pos + pack_length,
                                pos + pack_length + length,
                                seg->length/cs->mbmaxlen);
        set_if_smaller(length, char_length);
      }
      cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
    }
    else
    {
      for (; pos < end ; pos++)
      {
	nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos))+ (nr << 8);
	nr2+=3;
      }
    }
  }
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
  return(nr);
}
Пример #2
0
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
{
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    CHARSET_INFO *cs= seg->charset;
    uint char_length= seg->length;
    uchar *pos= (uchar*) rec + seg->start;
    if (seg->null_bit)
      *key++= MY_TEST(rec[seg->null_pos] & seg->null_bit);
    if (cs->mbmaxlen > 1)
    {
      char_length= my_charpos(cs, pos, pos + seg->length,
                              char_length / cs->mbmaxlen);
      set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
    }
    if (seg->type == HA_KEYTYPE_VARTEXT1)
      char_length+= seg->bit_start;             /* Copy also length */
    else if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
    {
      *key++= get_rec_bits(rec + seg->bit_pos,
                           seg->bit_start, seg->bit_length);
      char_length--;
    }
    memcpy(key,rec+seg->start,(size_t) char_length);
    key+= char_length;
  }
}
Пример #3
0
void hp_make_key(HP_KEYDEF *keydef, uchar *key, const uchar *rec)
{
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    const CHARSET_INFO *cs= seg->charset;
    uint char_length= seg->length;
    const uchar *pos= rec + seg->start;
    if (seg->null_bit)
      *key++= MY_TEST(rec[seg->null_pos] & seg->null_bit);

    if (seg->flag & HA_BLOB_PART)
    {
      uint tmp_length= hp_calc_blob_length(seg->bit_start, pos);
      uint length= MY_MIN(seg->length, tmp_length);

      memcpy(&pos, rec + seg->bit_start, sizeof(char *));
      if (cs->mbmaxlen > 1)
      {
        char_length= my_charpos(cs, pos, pos + seg->length,
                                char_length / cs->mbmaxlen);
        set_if_smaller(char_length, length); /* QQ: ok to remove? */
      }
      store_key_length_inc(key, char_length);
    }
    else
    {
      if (cs->mbmaxlen > 1)
      {
        char_length= my_charpos(cs, pos, pos + seg->length,
                                char_length / cs->mbmaxlen);
        set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
      }
      if (seg->type == HA_KEYTYPE_VARTEXT1)
        char_length+= seg->bit_start;             /* Copy also length */
    }

    memcpy(key, pos, (size_t) char_length);
    key+= char_length;
  }
}
Пример #4
0
int resize_queue(QUEUE *queue, uint max_elements)
{
  uchar **new_root;
  DBUG_ENTER("resize_queue");
  if (queue->max_elements == max_elements)
    DBUG_RETURN(0);
  if ((new_root= (uchar **) my_realloc((void *)queue->root,
				      (max_elements+1)*sizeof(void*),
				      MYF(MY_WME))) == 0)
    DBUG_RETURN(1);
  set_if_smaller(queue->elements, max_elements);
  queue->max_elements= max_elements;
  queue->root= new_root;
  DBUG_RETURN(0);
}
uint _mi_ft_convert_to_ft2(MI_INFO *info, uint keynr, uchar *key)
{
  my_off_t root;
  DYNAMIC_ARRAY *da=info->ft1_to_ft2;
  MI_KEYDEF *keyinfo=&info->s->ft2_keyinfo;
  uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end;
  uint length, key_length;
  DBUG_ENTER("_mi_ft_convert_to_ft2");

  /* we'll generate one pageful at once, and insert the rest one-by-one */
  /* calculating the length of this page ...*/
  length=(keyinfo->block_length-2) / keyinfo->keylength;
  set_if_smaller(length, da->elements);
  length=length * keyinfo->keylength;

  get_key_full_length_rdonly(key_length, key);
  while (_mi_ck_delete(info, keynr, key, key_length) == 0)
  {
    /*
      nothing to do here.
      _mi_ck_delete() will populate info->ft1_to_ft2 with deleted keys
     */
  }

  /* creating pageful of keys */
  mi_putint(info->buff,length+2,0);
  memcpy(info->buff+2, key_ptr, length);
  info->buff_used=info->page_changed=1;           /* info->buff is used */
  if ((root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
      _mi_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
    DBUG_RETURN(-1);

  /* inserting the rest of key values */
  end= (uchar*) dynamic_array_ptr(da, da->elements);
  for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength)
    if(_mi_ck_real_write_btree(info, keyinfo, key_ptr, 0, &root, SEARCH_SAME))
      DBUG_RETURN(-1);

  /* now, writing the word key entry */
  ft_intXstore(key+key_length, - (int) da->elements);
  _mi_dpointer(info, key+key_length+HA_FT_WLEN, root);

  DBUG_RETURN(_mi_ck_real_write_btree(info,
                                     info->s->keyinfo+keynr,
                                     key, 0,
                                     &info->s->state.key_root[keynr],
                                     SEARCH_SAME));
}
Пример #6
0
size_t my_strnxfrm_simple(CHARSET_INFO * cs, 
                          uchar *dest, size_t len,
                          const uchar *src, size_t srclen)
{
  const uchar *map= cs->sort_order;
  size_t dstlen= len;
  set_if_smaller(len, srclen);
  if (dest != src)
  {
    const uchar *end;
    for ( end=src+len; src < end ;  )
      *dest++= map[*src++];
  }
  else
  {
    const uchar *end;
    for ( end=dest+len; dest < end ; dest++)
      *dest= (char) map[(uchar) *dest];
  }
  if (dstlen > len)
    bfill(dest, dstlen - len, ' ');
  return dstlen;
}
Пример #7
0
MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
                        uchar *key, const uchar *record,
                        MARIA_RECORD_POS filepos, ulonglong trid)
{
  const uchar *pos;
  reg1 HA_KEYSEG *keyseg;
  my_bool is_ft;
  DBUG_ENTER("_ma_make_key");

  int_key->data= key;
  int_key->flag= 0;                             /* Always return full key */
  int_key->keyinfo= info->s->keyinfo + keynr;

  is_ft= int_key->keyinfo->flag & HA_FULLTEXT;
  for (keyseg= int_key->keyinfo->seg ; keyseg->type ;keyseg++)
  {
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
    uint length=keyseg->length;
    uint char_length;
    CHARSET_INFO *cs=keyseg->charset;

    if (keyseg->null_bit)
    {
      if (record[keyseg->null_pos] & keyseg->null_bit)
      {
	*key++= 0;				/* NULL in key */
	continue;
      }
      *key++=1;					/* Not NULL */
    }

    char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
                  length);

    pos= record+keyseg->start;
    if (type == HA_KEYTYPE_BIT)
    {
      if (keyseg->bit_length)
      {
        uchar bits= get_rec_bits(record + keyseg->bit_pos,
                                 keyseg->bit_start, keyseg->bit_length);
        *key++= (char) bits;
        length--;
      }
      memcpy(key, pos, length);
      key+= length;
      continue;
    }
    if (keyseg->flag & HA_SPACE_PACK)
    {
      if (type != HA_KEYTYPE_NUM)
      {
        length= (uint) cs->cset->lengthsp(cs, (const char*)pos, length);
      }
      else
      {
        const uchar *end= pos + length;
	while (pos < end && pos[0] == ' ')
	  pos++;
	length= (uint) (end-pos);
      }
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy(key, pos, (size_t) char_length);
      key+=char_length;
      continue;
    }
    if (keyseg->flag & HA_VAR_LENGTH_PART)
    {
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
      uint tmp_length= (pack_length == 1 ? (uint) *pos :
                        uint2korr(pos));
      pos+= pack_length;			/* Skip VARCHAR length */
      set_if_smaller(length,tmp_length);
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy(key,pos,(size_t) char_length);
      key+= char_length;
      continue;
    }
    else if (keyseg->flag & HA_BLOB_PART)
    {
      uint tmp_length= _ma_calc_blob_length(keyseg->bit_start,pos);
      uchar *blob_pos;
      memcpy(&blob_pos, pos+keyseg->bit_start,sizeof(char*));
      set_if_smaller(length,tmp_length);
      FIX_LENGTH(cs, blob_pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy(key, blob_pos, (size_t) char_length);
      key+= char_length;
      continue;
    }
    else if (keyseg->flag & HA_SWAP_KEY)
    {						/* Numerical column */
#ifdef HAVE_ISNAN
      if (type == HA_KEYTYPE_FLOAT)
      {
	float nr;
	float4get(nr,pos);
	if (isnan(nr))
	{
	  /* Replace NAN with zero */
	  bzero(key,length);
	  key+=length;
	  continue;
	}
      }
      else if (type == HA_KEYTYPE_DOUBLE)
      {
	double nr;
	float8get(nr,pos);
	if (isnan(nr))
	{
	  bzero(key,length);
	  key+=length;
	  continue;
	}
      }
#endif
      pos+=length;
      while (length--)
      {
	*key++ = *--pos;
      }
      continue;
    }
    FIX_LENGTH(cs, pos, length, char_length);
    memcpy(key, pos, char_length);
    if (length > char_length)
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
    key+= length;
  }
  _ma_dpointer(info->s, key, filepos);
  int_key->data_length= (key - int_key->data);
  int_key->ref_length= info->s->rec_reflength;
  int_key->flag= 0;
  if (_ma_have_versioning(info) && trid)
  {
    int_key->ref_length+= transid_store_packed(info,
                                               key + int_key->ref_length,
                                               (TrID) trid);
    int_key->flag|= SEARCH_USER_KEY_HAS_TRANSID;
  }

  DBUG_PRINT("exit",("keynr: %d",keynr));
  DBUG_DUMP_KEY("key", int_key);
  DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, int_key););
Пример #8
0
uint _mi_make_key(MI_INFO *info, uint keynr, uchar *key,
		  const uchar *record, my_off_t filepos)
{
  uchar *pos;
  uchar *start;
  HA_KEYSEG *keyseg;
  my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
  DBUG_ENTER("_mi_make_key");

  if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
  {
    /*
      TODO: nulls processing
    */
    DBUG_RETURN(sp_make_key(info,keynr,key,record,filepos));
  }

  start=key;
  for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
  {
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
    uint length=keyseg->length;
    uint char_length;
    const CHARSET_INFO *cs= keyseg->charset;

    if (keyseg->null_bit)
    {
      if (record[keyseg->null_pos] & keyseg->null_bit)
      {
	*key++= 0;				/* NULL in key */
	continue;
      }
      *key++=1;					/* Not NULL */
    }

    char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
                  length);

    pos= (uchar*) record+keyseg->start;
    if (type == HA_KEYTYPE_BIT)
    {
      if (keyseg->bit_length)
      {
        uchar bits= get_rec_bits((uchar*) record + keyseg->bit_pos,
                                 keyseg->bit_start, keyseg->bit_length);
        *key++= bits;
        length--;
      }
      memcpy((uchar*) key, pos, length);
      key+= length;
      continue;
    }
    if (keyseg->flag & HA_SPACE_PACK)
    {
      if (type != HA_KEYTYPE_NUM)
      {
        length= cs->cset->lengthsp(cs, (char*) pos, length);
      }
      else
      {
        uchar *end= pos + length;
	while (pos < end && pos[0] == ' ')
	  pos++;
	length=(uint) (end-pos);
      }
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
      key+=char_length;
      continue;
    }
    if (keyseg->flag & HA_VAR_LENGTH_PART)
    {
      uint pack_length= (keyseg->bit_start == 1 ? 1 : 2);
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
                        uint2korr(pos));
      pos+= pack_length;			/* Skip VARCHAR length */
      set_if_smaller(length,tmp_length);
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
      key+= char_length;
      continue;
    }
    else if (keyseg->flag & HA_BLOB_PART)
    {
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
      memcpy(&pos,pos+keyseg->bit_start,sizeof(char*));
      set_if_smaller(length,tmp_length);
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
      key+= char_length;
      continue;
    }
    else if (keyseg->flag & HA_SWAP_KEY)
    {						/* Numerical column */
      if (type == HA_KEYTYPE_FLOAT)
      {
	float nr;
	float4get(&nr,pos);
	if (my_isnan(nr))
	{
	  /* Replace NAN with zero */
	  memset(key, 0, length);
	  key+=length;
	  continue;
	}
      }
      else if (type == HA_KEYTYPE_DOUBLE)
      {
	double nr;
	float8get(&nr,pos);
	if (my_isnan(nr))
	{
	  memset(key, 0, length);
	  key+=length;
	  continue;
	}
      }
      pos+=length;
      while (length--)
      {
	*key++ = *--pos;
      }
      continue;
    }
    FIX_LENGTH(cs, pos, length, char_length);
    memcpy((uchar*) key, pos, char_length);
    if (length > char_length)
      cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
    key+= length;
  }
  _mi_dpointer(info,key,filepos);
  DBUG_PRINT("exit",("keynr: %d",keynr));
  DBUG_DUMP("key",(uchar*) start,(uint) (key-start)+keyseg->length);
  DBUG_EXECUTE("key",
	       _mi_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start,
			     (uint) (key-start)););
Пример #9
0
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
                    key_part_map keypart_map)
{
  HA_KEYSEG *seg, *endseg;
  uchar *start_key= key;

  for (seg= keydef->seg, endseg= seg + keydef->keysegs;
       seg < endseg && keypart_map; old+= seg->length, seg++)
  {
    uint char_length;
    keypart_map>>= 1;
    if (seg->null_bit)
    {
      /* Convert NULL from MySQL representation into HEAP's. */
      if (!(*key++= (char) 1 - *old++))
      {
	/* Add key pack length (2) to key for VARCHAR segments */
        if (seg->type == HA_KEYTYPE_VARTEXT1)
          old+= 2;
        continue;
      }
    }
    if (seg->flag & HA_SWAP_KEY)
    {
      uint length= seg->length;
      uchar *pos= (uchar*) old + length;
      
      while (length--)
      {
	*key++= *--pos;
      }
      continue;
    }
    if (seg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
    {
      /* Length of key-part used with heap_rkey() always 2 */
      uint tmp_length=uint2korr(old);
      uint length= seg->length;
      CHARSET_INFO *cs= seg->charset;
      char_length= length/cs->mbmaxlen;

      old+= 2;
      set_if_smaller(length,tmp_length);	/* Safety */
      FIX_LENGTH(cs, old, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy((uchar*) key, old,(size_t) char_length);
      key+= char_length;
      continue;
    }
    char_length= seg->length;
    if (seg->charset->mbmaxlen > 1)
    {
      char_length= my_charpos(seg->charset, old, old+char_length,
                              char_length / seg->charset->mbmaxlen);
      set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
      if (char_length < seg->length)
        seg->charset->cset->fill(seg->charset, (char*) key + char_length, 
                                 seg->length - char_length, ' ');
    }
    memcpy(key, old, (size_t) char_length);
    key+= seg->length;
  }
  return (uint) (key - start_key);
}
Пример #10
0
uint hp_rb_make_key(HP_KEYDEF *keydef, uchar *key, 
		    const uchar *rec, uchar *recpos)
{
  uchar *start_key= key;
  HA_KEYSEG *seg, *endseg;

  for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++)
  {
    uint char_length;
    if (seg->null_bit)
    {
      if (!(*key++= 1 - MY_TEST(rec[seg->null_pos] & seg->null_bit)))
        continue;
    }
    if (seg->flag & HA_SWAP_KEY)
    {
      uint length= seg->length;
      uchar *pos= (uchar*) rec + seg->start;
      DBUG_ASSERT(seg->type != HA_KEYTYPE_BIT);

#ifdef HAVE_ISNAN
      if (seg->type == HA_KEYTYPE_FLOAT)
      {
	float nr;
	float4get(nr, pos);
	if (isnan(nr))
	{
	  /* Replace NAN with zero */
 	  bzero(key, length);
	  key+= length;
	  continue;
	}
      }
      else if (seg->type == HA_KEYTYPE_DOUBLE)
      {
	double nr;
	float8get(nr, pos);
	if (isnan(nr))
	{
 	  bzero(key, length);
	  key+= length;
	  continue;
	}
      }
#endif
      pos+= length;
      while (length--)
      {
	*key++= *--pos;
      }
      continue;
    }

    if (seg->flag & HA_VAR_LENGTH_PART)
    {
      uchar *pos=      (uchar*) rec + seg->start;
      uint length=     seg->length;
      uint pack_length= seg->bit_start;
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
                        uint2korr(pos));
      CHARSET_INFO *cs= seg->charset;
      char_length= length/cs->mbmaxlen;

      pos+= pack_length;			/* Skip VARCHAR length */
      set_if_smaller(length,tmp_length);
      FIX_LENGTH(cs, pos, length, char_length);
      store_key_length_inc(key,char_length);
      memcpy((uchar*) key,(uchar*) pos,(size_t) char_length);
      key+= char_length;
      continue;
    }

    char_length= seg->length;
    if (seg->charset->mbmaxlen > 1)
    {
      char_length= my_charpos(seg->charset, 
                              rec + seg->start, rec + seg->start + char_length,
                              char_length / seg->charset->mbmaxlen);
      set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
      if (char_length < seg->length)
        seg->charset->cset->fill(seg->charset, (char*) key + char_length,
                                 seg->length - char_length, ' ');
    }
    if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
    {
      *key++= get_rec_bits(rec + seg->bit_pos,
                           seg->bit_start, seg->bit_length);
      char_length--;
    }
    memcpy(key, rec + seg->start, (size_t) char_length);
    key+= seg->length;
  }
  memcpy(key, &recpos, sizeof(uchar*));
  return (uint) (key - start_key);
}
Пример #11
0
int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
{
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ;
       seg < endseg ;
       key+= (seg++)->length)
  {
    if (seg->null_bit)
    {
      int found_null= MY_TEST(rec[seg->null_pos] & seg->null_bit);
      if (found_null != (int) *key++)
	return 1;
      if (found_null)
      {
        /* Add key pack length (2) to key for VARCHAR segments */
        if (seg->type == HA_KEYTYPE_VARTEXT1)
          key+= 2;
	continue;
      }
    }
    if (seg->type == HA_KEYTYPE_TEXT)
    {
      CHARSET_INFO *cs= seg->charset;
      uint char_length_key;
      uint char_length_rec;
      uchar *pos= (uchar*) rec + seg->start;
      if (cs->mbmaxlen > 1)
      {
        uint char_length= seg->length / cs->mbmaxlen;
        char_length_key= my_charpos(cs, key, key + seg->length, char_length);
        set_if_smaller(char_length_key, seg->length);
        char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
        set_if_smaller(char_length_rec, seg->length);
      }
      else
      {
        char_length_key= seg->length;
        char_length_rec= seg->length;
      }
      
      if (seg->charset->coll->strnncollsp(seg->charset,
					  (uchar*) pos, char_length_rec,
					  (uchar*) key, char_length_key, 0))
	return 1;
    }
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
    {
      uchar *pos= (uchar*) rec + seg->start;
      CHARSET_INFO *cs= seg->charset;
      uint pack_length= seg->bit_start;
      uint char_length_rec= (pack_length == 1 ? (uint) *(uchar*) pos :
                             uint2korr(pos));
      /* Key segments are always packed with 2 bytes */
      uint char_length_key= uint2korr(key);
      pos+= pack_length;
      key+= 2;                                  /* skip key pack length */
      if (cs->mbmaxlen > 1)
      {
        uint char_length1, char_length2;
        char_length1= char_length2= seg->length / cs->mbmaxlen; 
        char_length1= my_charpos(cs, key, key + char_length_key, char_length1);
        set_if_smaller(char_length_key, char_length1);
        char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2);
        set_if_smaller(char_length_rec, char_length2);
      }
      else
        set_if_smaller(char_length_rec, seg->length);

      if (cs->coll->strnncollsp(seg->charset,
                                (uchar*) pos, char_length_rec,
                                (uchar*) key, char_length_key, 0))
	return 1;
    }
    else
    {
      uint dec= 0;
      if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
      {
        uchar bits= get_rec_bits(rec + seg->bit_pos,
                                 seg->bit_start, seg->bit_length);
        if (bits != (*key))
          return 1;
        dec= 1;
        key++;
      }

      if (bcmp(rec + seg->start, key, seg->length - dec))
	return 1;
    }
  }
  return 0;
}
Пример #12
0
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
                   my_bool diff_if_only_endspace_difference)
{
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    if (seg->null_bit)
    {
      if ((rec1[seg->null_pos] & seg->null_bit) !=
	  (rec2[seg->null_pos] & seg->null_bit))
	return 1;
      if (rec1[seg->null_pos] & seg->null_bit)
	continue;
    }
    if (seg->type == HA_KEYTYPE_TEXT)
    {
      CHARSET_INFO *cs= seg->charset;
      uint char_length1;
      uint char_length2;
      uchar *pos1= (uchar*)rec1 + seg->start;
      uchar *pos2= (uchar*)rec2 + seg->start;
      if (cs->mbmaxlen > 1)
      {
        uint char_length= seg->length / cs->mbmaxlen;
        char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
        set_if_smaller(char_length1, seg->length);
        char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
        set_if_smaller(char_length2, seg->length);
      }
      else
      {
        char_length1= char_length2= seg->length;
      }
      if (seg->charset->coll->strnncollsp(seg->charset,
      					  pos1,char_length1,
					  pos2,char_length2, 0))
	return 1;
    }
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
    {
      uchar *pos1= (uchar*) rec1 + seg->start;
      uchar *pos2= (uchar*) rec2 + seg->start;
      uint char_length1, char_length2;
      uint pack_length= seg->bit_start;
      CHARSET_INFO *cs= seg->charset;
      if (pack_length == 1)
      {
        char_length1= (uint) *(uchar*) pos1++;
        char_length2= (uint) *(uchar*) pos2++;
      }
      else
      {
        char_length1= uint2korr(pos1);
        char_length2= uint2korr(pos2);
        pos1+= 2;
        pos2+= 2;
      }
      if (cs->mbmaxlen > 1)
      {
        uint safe_length1= char_length1;
        uint safe_length2= char_length2;
        uint char_length= seg->length / cs->mbmaxlen;
        char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
        set_if_smaller(char_length1, safe_length1);
        char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
        set_if_smaller(char_length2, safe_length2);
      }
      else
      {
        set_if_smaller(char_length1, seg->length);
        set_if_smaller(char_length2, seg->length);
      }

      if (cs->coll->strnncollsp(seg->charset,
                                pos1, char_length1,
                                pos2, char_length2,
                                seg->flag & HA_END_SPACE_ARE_EQUAL ?
                                0 : diff_if_only_endspace_difference))
	return 1;
    }
    else
    {
      uint dec= 0;
      if (seg->type == HA_KEYTYPE_BIT && seg->bit_length)
      {
        uchar bits1= get_rec_bits(rec1 + seg->bit_pos,
                                  seg->bit_start, seg->bit_length);
        uchar bits2= get_rec_bits(rec2 + seg->bit_pos,
                                  seg->bit_start, seg->bit_length);
        if (bits1 != bits2)
          return 1;
        dec= 1;
      }
      if (bcmp(rec1 + seg->start, rec2 + seg->start, seg->length - dec))
	return 1;
    }
  }
  return 0;
}
Пример #13
0
ulong hp_hashnr(register HP_KEYDEF *keydef, register const uchar *key)
{
  /*register*/ 
  ulong nr=1, nr2=4;
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    uchar *pos=(uchar*) key;
    key+=seg->length;
    if (seg->null_bit)
    {
      key++;					/* Skip null byte */
      if (*pos)					/* Found null */
      {
	nr^= (nr << 1) | 1;
	/* Add key pack length (2) to key for VARCHAR segments */
        if (seg->type == HA_KEYTYPE_VARTEXT1)
          key+= 2;
	continue;
      }
      pos++;
    }
    if (seg->type == HA_KEYTYPE_TEXT)
    {
       CHARSET_INFO *cs= seg->charset;
       uint length= seg->length;
       if (cs->mbmaxlen > 1)
       {
         uint char_length;
         char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
         set_if_smaller(length, char_length);
       }
       cs->coll->hash_sort(cs, pos, length, &nr, &nr2);
    }
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
    {
       CHARSET_INFO *cs= seg->charset;
       uint pack_length= 2;                     /* Key packing is constant */
       uint length= uint2korr(pos);
       if (cs->mbmaxlen > 1)
       {
         uint char_length;
         char_length= my_charpos(cs, pos +pack_length,
                                 pos +pack_length + length,
                                 seg->length/cs->mbmaxlen);
         set_if_smaller(length, char_length);
       }
       cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
       key+= pack_length;
    }
    else
    {
      for (; pos < (uchar*) key ; pos++)
      {
	nr^=(ulong) ((((uint) nr & 63)+nr2)*((uint) *pos)) + (nr << 8);
	nr2+=3;
      }
    }
  }
#ifdef ONLY_FOR_HASH_DEBUGGING
  DBUG_PRINT("exit", ("hash: 0x%lx", nr));
#endif
  return((ulong) nr);
}
Пример #14
0
static void get_options( int argc, char *argv[])
{
  char *pos,*progname;
  DEBUGGER_OFF;

  progname= argv[0];

  while (--argc >0 && *(pos = *(++argv)) == '-' ) {
    switch(*++pos) {
    case 'b':
      if (*++pos)
	nisam_block_size= MY_ALIGN(atoi(pos),512);
      set_if_bigger(nisam_block_size,8192);	/* Max block size */
      set_if_smaller(nisam_block_size,1024);
      break;
    case 'B':
      use_blob=1;
      break;
    case 'K':				/* Use key cacheing */
      key_cacheing=1;
      break;
    case 'W':				/* Use write cacheing */
      write_cacheing=1;
      if (*++pos)
	my_default_record_cache_size=atoi(pos);
      break;
    case 'i':
      if (*++pos)
	srand(atoi(pos));
      break;
    case 'l':
      use_log=1;
      break;
    case 'L':
      locking=1;
      break;
    case 'A':				/* use asyncron io */
      async_io=1;
      if (*++pos)
	my_default_record_cache_size=atoi(pos);
      break;
    case 'v':				/* verbose */
      verbose=1;
      break;
    case 'm':				/* records */
      recant=atoi(++pos);
      break;
    case 'f':
      if ((first_key=atoi(++pos)) <0 || first_key >= NISAM_KEYS)
	first_key=0;
      break;
    case 'k':
      if ((keys=(uint) atoi(++pos)) < 1 ||
	   keys > (uint) (NISAM_KEYS-first_key))
	keys=NISAM_KEYS-first_key;
      break;
    case 'P':
      pack_type=0;			/* Don't use DIFF_LENGTH */
      break;
    case 'R':				/* Length of record pointer */
      rec_pointer_size=atoi(++pos);
      if (rec_pointer_size > 3)
	rec_pointer_size=0;
      break;
    case 'S':
      pack_fields=0;			/* Static-length-records */
      break;
    case 't':
      testflag=atoi(++pos);		/* testmod */
      break;
    case '?':
    case 'I':
    case 'V':
      printf("%s  Ver 1.4 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
      puts("TCX Datakonsult AB, by Monty, for your professional use\n");
      printf("Usage: %s [-?ABIKLPRSVWltv] [-b#] [-k#] [-f#] [-m#] [-t#]\n",progname);
      exit(0);
    case '#':
      DEBUGGER_ON;
      DBUG_PUSH (++pos);
      break;
    default:
      printf("Illegal option: '%c'\n",*pos);
      break;
    }
  }
  return;
} /* get options */
Пример #15
0
int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
                   my_bool diff_if_only_endspace_difference)
{
  HA_KEYSEG *seg,*endseg;

  for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
  {
    if (seg->null_bit)
    {
      if ((rec1[seg->null_pos] & seg->null_bit) !=
	  (rec2[seg->null_pos] & seg->null_bit))
	return 1;
      if (rec1[seg->null_pos] & seg->null_bit)
	continue;
    }
    if (seg->type == HA_KEYTYPE_TEXT)
    {
      const CHARSET_INFO *cs= seg->charset;
      uint char_length1;
      uint char_length2;
      uchar *pos1= (uchar*)rec1 + seg->start;
      uchar *pos2= (uchar*)rec2 + seg->start;
      if (cs->mbmaxlen > 1)
      {
        uint char_length= seg->length / cs->mbmaxlen;
        char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
        set_if_smaller(char_length1, seg->length);
        char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
        set_if_smaller(char_length2, seg->length);
      }
      else
      {
        char_length1= char_length2= seg->length;
      }
      if (seg->charset->coll->strnncollsp(seg->charset,
      					  pos1,char_length1,
					  pos2,char_length2, 0))
	return 1;
    }
    else if (seg->type == HA_KEYTYPE_VARTEXT1)  /* Any VARCHAR segments */
    {
      uchar *pos1= (uchar*) rec1 + seg->start;
      uchar *pos2= (uchar*) rec2 + seg->start;
      uint char_length1, char_length2;
      uint pack_length= seg->bit_start;
      const CHARSET_INFO *cs= seg->charset;
      char_length1= hp_calc_blob_length(pack_length, pos1);
      char_length2= hp_calc_blob_length(pack_length, pos2);
      pos1+= pack_length;
      pos2+= pack_length;

      if (seg->flag & HA_BLOB_PART)
      {
        memcpy(&pos1, pos1, sizeof(char *));
        memcpy(&pos2, pos2, sizeof(char *));
      }

      if (cs->mbmaxlen > 1)
      {
        uint safe_length1= char_length1;
        uint safe_length2= char_length2;
        uint char_length= seg->length / cs->mbmaxlen;
        char_length1= my_charpos(cs, pos1, pos1 + char_length1, char_length);
        set_if_smaller(char_length1, safe_length1);
        char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
        set_if_smaller(char_length2, safe_length2);
      }

      if (cs->coll->strnncollsp(seg->charset,
                                pos1, char_length1,
                                pos2, char_length2,
                                seg->flag & HA_END_SPACE_ARE_EQUAL ?
                                0 : diff_if_only_endspace_difference))
	return 1;
    }
    else
    {
      if (memcmp(rec1+seg->start,rec2+seg->start,seg->length))
	return 1;
    }
  }
  return 0;
}
Пример #16
0
uint 
_mi_make_key(register MI_INFO * info, uint keynr, uchar * key,
	     const byte * record, my_off_t filepos)
{
	byte           *pos, *end;
	uchar          *start;
	reg1 MI_KEYSEG *keyseg;
	DBUG_ENTER("_mi_make_key");

	start = key;
	for (keyseg = info->s->keyinfo[keynr].seg; keyseg->type; keyseg++) {
		enum ha_base_keytype type = (enum ha_base_keytype)keyseg->type;
		uint		length = keyseg->length;

		if (keyseg->null_bit) {
			if (record[keyseg->null_pos] & keyseg->null_bit) {
				*key++ = 0;	/* NULL in key */
				continue;
			}
			*key++ = 1;	/* Not NULL */
		}
		pos = (byte *) record + keyseg->start;
		if (keyseg->flag & HA_SPACE_PACK) {
			end = pos + length;
			if (type != HA_KEYTYPE_NUM) {
				while (end > pos && end[-1] == ' ')
					end--;
			} else {
				while (pos < end && pos[0] == ' ')
					pos++;
			}
			length = (uint) (end - pos);
			store_key_length_inc(key, length);
			memcpy((byte *) key, (byte *) pos, (size_t) length);
			key += length;
			continue;
		}
		if (keyseg->flag & HA_VAR_LENGTH) {
			uint		tmp_length = uint2korr(pos);
			pos += 2;	/* Skip VARCHAR length */
			set_if_smaller(length, tmp_length);
			store_key_length_inc(key, length);
		} else if (keyseg->flag & HA_BLOB_PART) {
			uint		tmp_length = _mi_calc_blob_length(keyseg->bit_start, pos);
			memcpy_fixed((byte *) & pos, pos + keyseg->bit_start, sizeof(char *));
			set_if_smaller(length, tmp_length);
			store_key_length_inc(key, length);
		} else if (keyseg->flag & HA_SWAP_KEY) {	/* Numerical column */
#ifdef NAN_TEST
			float		float_nr;
			double		dbl_nr;
			if (type == HA_KEYTYPE_FLOAT) {
				float_nr = float4get(pos);
				if (float_nr == (float)FLT_MAX) {
					float_nr = (float)FLT_MAX;
					pos = (byte *) & float_nr;
				}
			} else if (type == HA_KEYTYPE_DOUBLE) {
				dbl_nr = float8get(key);
				if (dbl_nr == DBL_MAX) {
					dbl_nr = DBL_MAX;
					pos = (byte *) & dbl_nr;
				}
			}
#endif
			pos += length;
			while (length--) {
				*key++ = *--pos;
			}
			continue;
		}
		memcpy((byte *) key, pos, length);
		key += length;
	}
	_mi_dpointer(info, key, filepos);
	DBUG_PRINT("exit", ("keynr: %d", keynr));
	DBUG_DUMP("key", (byte *) start, (uint) (key - start) + keyseg->length);
	DBUG_EXECUTE("key",
		_mi_print_key(DBUG_FILE, info->s->keyinfo[keynr].seg, start,
			      (uint) (key - start));
	);