int mi_rkey(MI_INFO * info, byte * buf, int inx, const byte * key, uint key_len, enum ha_rkey_function search_flag) { uchar *key_buff; MYISAM_SHARE *share = info->s; uint pack_key_length; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter", ("base: %lx inx: %d search_flag: %d", info, inx, search_flag)); if ((inx = _mi_check_index(info, inx)) < 0) DBUG_RETURN(my_errno); info->update &= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); if (!info->use_packed_key) { if (key_len == 0) key_len = USE_WHOLE_KEY; key_buff = info->lastkey + info->s->base.max_key_length; pack_key_length = _mi_pack_key(info, (uint) inx, key_buff, (uchar *) key, key_len); info->last_rkey_length = pack_key_length; DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE, share->keyinfo[inx].seg, key_buff, pack_key_length); ); } else {
int _mi_insert(register MI_INFO * info, register MI_KEYDEF * keyinfo, uchar * key, uchar * anc_buff, uchar * key_pos, uchar * key_buff, uchar * father_buff, uchar * father_key_pos, my_off_t father_page, my_bool insert_last) { uint a_length , nod_flag; int t_length; uchar *endpos, *prev_key; MI_KEY_PARAM s_temp; DBUG_ENTER("_mi_insert"); DBUG_PRINT("enter", ("key_pos: %lx", key_pos)); DBUG_EXECUTE("key", _mi_print_key(DBUG_FILE, keyinfo->seg, key, USE_WHOLE_KEY); );
int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, key_part_map keypart_map, enum ha_rkey_function search_flag) { uchar *key_buff; MYISAM_SHARE *share=info->s; MI_KEYDEF *keyinfo; HA_KEYSEG *last_used_keyseg; uint pack_key_length, use_key_length, nextflag; ICP_RESULT res= ICP_NO_MATCH; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter", ("base: 0x%lx buf: 0x%lx inx: %d search_flag: %d", (long) info, (long) buf, inx, search_flag)); if ((inx = _mi_check_index(info,inx)) < 0) DBUG_RETURN(my_errno); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->last_key_func= search_flag; keyinfo= share->keyinfo + inx; if (info->once_flags & USE_PACKED_KEYS) { info->once_flags&= ~USE_PACKED_KEYS; /* Reset flag */ /* key is already packed!; This happens when we are using a MERGE TABLE In this key 'key_part_map' is the length of the key ! */ key_buff=info->lastkey+info->s->base.max_key_length; pack_key_length= keypart_map; bmove(key_buff, key, pack_key_length); last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg; } else { DBUG_ASSERT(keypart_map); /* Save the packed key for later use in the second buffer of lastkey. */ key_buff=info->lastkey+info->s->base.max_key_length; pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key, keypart_map, &last_used_keyseg); /* Save packed_key_length for use by the MERGE engine. */ info->pack_key_length= pack_key_length; info->last_used_keyseg= (uint16) (last_used_keyseg - info->s->keyinfo[inx].seg); DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg, key_buff, pack_key_length);); }
static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key, key_part_map keypart_map, enum ha_rkey_function search_flag) { uint inx=(uint) info->lastinx, nextflag, key_len; MI_KEYDEF *keyinfo=info->s->keyinfo+inx; uchar *key_buff; double pos; DBUG_ENTER("_mi_record_pos"); DBUG_PRINT("enter",("search_flag: %d",search_flag)); DBUG_ASSERT(keypart_map); key_buff=info->lastkey+info->s->base.max_key_length; key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key, keypart_map, (HA_KEYSEG**) 0); DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg, (uchar*) key_buff,key_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)); );