diff options
Diffstat (limited to 'heap/hp_hash.c')
-rw-r--r-- | heap/hp_hash.c | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/heap/hp_hash.c b/heap/hp_hash.c index e28f4725caf..cd70d2ab532 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -30,27 +30,27 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, TREE *rb_tree = &keyinfo->rb_tree; heap_rb_param custom_arg; - info->lastinx = inx; - custom_arg.keyseg = keyinfo->seg; - custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME; - custom_arg.key_length = start_key_len; + info->lastinx= inx; + custom_arg.keyseg= keyinfo->seg; + custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; if (start_key) { - hp_rb_pack_key(keyinfo, info->recbuf, start_key); + custom_arg.key_length= hp_rb_pack_key(keyinfo, info->recbuf, start_key, + start_key_len); start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag, - &custom_arg); + &custom_arg); } else { start_pos= 0; } - custom_arg.key_length = end_key_len; if (end_key) { - hp_rb_pack_key(keyinfo, info->recbuf, end_key); + custom_arg.key_length= hp_rb_pack_key(keyinfo, info->recbuf, end_key, + end_key_len); end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag, - &custom_arg); + &custom_arg); } else { @@ -443,6 +443,43 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit))) continue; } + if (seg->flag & HA_SWAP_KEY) + { + uint length= seg->length; + byte *pos= (byte*) rec + seg->start; + +#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; + } memcpy(key, rec + seg->start, (size_t) seg->length); key+= seg->length; } @@ -450,21 +487,38 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, return key - start_key; } -uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old) +uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) { HA_KEYSEG *seg, *endseg; uchar *start_key= key; - for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; - old+= seg->length, seg++) + for (seg= keydef->seg, endseg= seg + keydef->keysegs; + seg < endseg && (int) k_len > 0; old+= seg->length, seg++) { if (seg->null_bit) { + k_len--; if (!(*key++= (char) 1 - *old++)) + { + k_len-= seg->length; continue; + } + } + if (seg->flag & HA_SWAP_KEY) + { + uint length= seg->length; + byte *pos= (byte*) old + length; + + k_len-= length; + while (length--) + { + *key++= *--pos; + } + continue; } memcpy((byte*) key, old, seg->length); key+= seg->length; + k_len-= seg->length; } return key - start_key; } |