ha_checksum mi_checksum(MI_INFO *info, const uchar *buf) { uint i; ha_checksum crc=0; MI_COLUMNDEF *rec=info->s->rec; for (i=info->s->base.fields ; i-- ; buf+=(rec++)->length) { const uchar *pos; ulong length; switch (rec->type) { case FIELD_BLOB: { length=_mi_calc_blob_length(rec->length- portable_sizeof_char_ptr, buf); memcpy((char*) &pos, buf+rec->length- portable_sizeof_char_ptr, sizeof(char*)); break; } case FIELD_VARCHAR: { uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length-1); if (pack_length == 1) length= (ulong) *(uchar*) buf; else length= uint2korr(buf); pos= buf+pack_length; break; } default: length=rec->length; pos=buf; break; } crc=my_checksum(crc, pos ? pos : (uchar*) "", length); } return crc; }
uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) { DBUG_ENTER("_mi_ft_segiterator"); if (!ftsi->num) DBUG_RETURN(0); ftsi->num--; if (!ftsi->seg) DBUG_RETURN(1); ftsi->seg--; if (ftsi->seg->null_bit && (ftsi->rec[ftsi->seg->null_pos] & ftsi->seg->null_bit)) { ftsi->pos=0; DBUG_RETURN(1); } ftsi->pos= ftsi->rec+ftsi->seg->start; if (ftsi->seg->flag & HA_VAR_LENGTH_PART) { uint pack_length= (ftsi->seg->bit_start); ftsi->len= (pack_length == 1 ? (uint) *(uchar*) ftsi->pos : uint2korr(ftsi->pos)); ftsi->pos+= pack_length; /* Skip VARCHAR length */ DBUG_RETURN(1); } if (ftsi->seg->flag & HA_BLOB_PART) { ftsi->len=_mi_calc_blob_length(ftsi->seg->bit_start,ftsi->pos); memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start, sizeof(char*)); DBUG_RETURN(1); } ftsi->len=ftsi->seg->length; DBUG_RETURN(1); }
uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key, const uchar *record, my_off_t filepos) { HA_KEYSEG *keyseg; MI_KEYDEF *keyinfo = &info->s->keyinfo[keynr]; uint len = 0; uchar *pos; uint dlen; uchar *dptr; double mbr[SPDIMS * 2]; uint i; keyseg = &keyinfo->seg[-1]; pos = (uchar*)record + keyseg->start; dlen = _mi_calc_blob_length(keyseg->bit_start, pos); memcpy(&dptr, pos + keyseg->bit_start, sizeof(char*)); if (!dptr) { my_errno= HA_ERR_NULL_IN_SPATIAL; return 0; } sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr); /* SRID */ for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++) { uint length = keyseg->length, start= keyseg->start; double val; DBUG_ASSERT(length == sizeof(double)); DBUG_ASSERT(!(start % sizeof(double))); DBUG_ASSERT(start < sizeof(mbr)); DBUG_ASSERT(keyseg->type == HA_KEYTYPE_DOUBLE); val= mbr[start / sizeof (double)]; #ifdef HAVE_ISNAN if (isnan(val)) { bzero(key, length); key+= length; len+= length; continue; } #endif if (keyseg->flag & HA_SWAP_KEY) { uchar buf[sizeof(double)]; float8store(buf, val); pos= &buf[length]; while (pos > buf) *key++ = *--pos; } else { float8store((uchar *)key, val); key += length; } len+= length; } _mi_dpointer(info, key, filepos); return len; }
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)););
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)); );