Commit 9c4049ad authored by serg@serg.mylan's avatar serg@serg.mylan

Bitmap post-review fixes

parent eb93b6b8
...@@ -38,23 +38,23 @@ typedef struct st_bitmap ...@@ -38,23 +38,23 @@ typedef struct st_bitmap
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2); extern my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2);
extern my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe); extern my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe);
extern my_bool bitmap_is_clear_all(MY_BITMAP *map); extern my_bool bitmap_is_clear_all(const MY_BITMAP *map);
extern my_bool bitmap_is_prefix(MY_BITMAP *map, uint prefix_size); extern my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size);
extern my_bool bitmap_is_set(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_is_set_all(MY_BITMAP *map); extern my_bool bitmap_is_set_all(const MY_BITMAP *map);
extern my_bool bitmap_is_subset(MY_BITMAP *map1, MY_BITMAP *map2); extern my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2);
extern uint bitmap_set_next(MY_BITMAP *map); extern uint bitmap_set_next(MY_BITMAP *map);
extern void bitmap_clear_all(MY_BITMAP *map); extern void bitmap_clear_all(MY_BITMAP *map);
extern void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit); extern void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit);
extern void bitmap_free(MY_BITMAP *map); extern void bitmap_free(MY_BITMAP *map);
extern void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2); extern void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2);
extern void bitmap_set_all(MY_BITMAP *map); extern void bitmap_set_all(MY_BITMAP *map);
extern void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit); extern void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit);
extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size); extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size);
extern void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2); extern void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2);
extern void bitmap_union(MY_BITMAP *map, MY_BITMAP *map2); extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -16,7 +16,16 @@ ...@@ -16,7 +16,16 @@
/* /*
Handling of uchar arrays as large bitmaps. Handling of uchar arrays as large bitmaps.
We assume that the size of the used bitmap is less than ~(uint) 0
API limitations (or, rather asserted safety assumptions,
to encourage correct programming)
* the size of the used bitmap is less than ~(uint) 0
* it's a multiple of 8 (for efficiency reasons)
* when arguments are a bitmap and a bit number, the number
must be within bitmap size
* bitmap_set_prefix() is an exception - one can use ~0 to set all bits
* when both arguments are bitmaps, they must be of the same size
TODO: TODO:
Make assembler THREAD safe versions of these using test-and-set instructions Make assembler THREAD safe versions of these using test-and-set instructions
...@@ -45,11 +54,11 @@ inline void bitmap_unlock(MY_BITMAP *map) ...@@ -45,11 +54,11 @@ inline void bitmap_unlock(MY_BITMAP *map)
my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe) my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe)
{ {
// for efficiency reasons - MY_BITMAP is heavily used
DBUG_ASSERT((bitmap_size & 7) == 0); DBUG_ASSERT((bitmap_size & 7) == 0);
bitmap_size/=8; bitmap_size/=8;
if (!(map->bitmap=buf) && if (!(map->bitmap=buf) &&
!(map->bitmap=(uchar*)my_malloc(bitmap_size + sizeof(pthread_mutex_t), !(map->bitmap=(uchar*)my_malloc(bitmap_size +
(thread_safe ? sizeof(pthread_mutex_t) : 0),
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
return 1; return 1;
map->bitmap_size=bitmap_size; map->bitmap_size=bitmap_size;
...@@ -128,7 +137,8 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) ...@@ -128,7 +137,8 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
{ {
uint prefix_bytes, prefix_bits; uint prefix_bytes, prefix_bits;
DBUG_ASSERT(map->bitmap); DBUG_ASSERT(map->bitmap &&
(prefix_size <= map->bitmap_size*8 || prefix_size == ~0));
bitmap_lock(map); bitmap_lock(map);
set_if_smaller(prefix_size, map->bitmap_size*8); set_if_smaller(prefix_size, map->bitmap_size*8);
if ((prefix_bytes= prefix_size / 8)) if ((prefix_bytes= prefix_size / 8))
...@@ -150,7 +160,7 @@ void bitmap_set_all(MY_BITMAP *map) ...@@ -150,7 +160,7 @@ void bitmap_set_all(MY_BITMAP *map)
bitmap_set_prefix(map, ~0); bitmap_set_prefix(map, ~0);
} }
my_bool bitmap_is_prefix(MY_BITMAP *map, uint prefix_size) my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{ {
uint prefix_bits= prefix_size & 7, res= 0; uint prefix_bits= prefix_size & 7, res= 0;
uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8, uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8,
...@@ -167,7 +177,7 @@ my_bool bitmap_is_prefix(MY_BITMAP *map, uint prefix_size) ...@@ -167,7 +177,7 @@ my_bool bitmap_is_prefix(MY_BITMAP *map, uint prefix_size)
goto ret; goto ret;
while (m < end) while (m < end)
if (m++ != 0) if (*m++ != 0)
goto ret; goto ret;
res=1; res=1;
...@@ -176,23 +186,23 @@ ret: ...@@ -176,23 +186,23 @@ ret:
return res; return res;
} }
my_bool bitmap_is_clear_all(MY_BITMAP *map) my_bool bitmap_is_clear_all(const MY_BITMAP *map)
{ {
return bitmap_is_prefix(map, 0); return bitmap_is_prefix(map, 0);
} }
my_bool bitmap_is_set_all(MY_BITMAP *map) my_bool bitmap_is_set_all(const MY_BITMAP *map)
{ {
return bitmap_is_prefix(map, map->bitmap_size*8); return bitmap_is_prefix(map, map->bitmap_size*8);
} }
my_bool bitmap_is_set(MY_BITMAP *map, uint bitmap_bit) my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit)
{ {
DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
return map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7)); return map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7));
} }
my_bool bitmap_is_subset(MY_BITMAP *map1, MY_BITMAP *map2) my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
{ {
uint length, res=0; uint length, res=0;
uchar *m1=map1->bitmap, *m2=map2->bitmap, *end; uchar *m1=map1->bitmap, *m2=map2->bitmap, *end;
...@@ -215,7 +225,7 @@ ret: ...@@ -215,7 +225,7 @@ ret:
return res; return res;
} }
my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2) my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
{ {
uint res; uint res;
...@@ -231,7 +241,7 @@ my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2) ...@@ -231,7 +241,7 @@ my_bool bitmap_cmp(MY_BITMAP *map1, MY_BITMAP *map2)
return res; return res;
} }
void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2) void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
{ {
uchar *to=map->bitmap, *from=map2->bitmap, *end; uchar *to=map->bitmap, *from=map2->bitmap, *end;
...@@ -249,7 +259,7 @@ void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2) ...@@ -249,7 +259,7 @@ void bitmap_intersect(MY_BITMAP *map, MY_BITMAP *map2)
bitmap_unlock(map); bitmap_unlock(map);
} }
void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2) void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
{ {
uchar *to=map->bitmap, *from=map2->bitmap, *end; uchar *to=map->bitmap, *from=map2->bitmap, *end;
...@@ -267,7 +277,7 @@ void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2) ...@@ -267,7 +277,7 @@ void bitmap_subtract(MY_BITMAP *map, MY_BITMAP *map2)
bitmap_unlock(map); bitmap_unlock(map);
} }
void bitmap_union(MY_BITMAP *map, MY_BITMAP *map2) void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
{ {
uchar *to=map->bitmap, *from=map2->bitmap, *end; uchar *to=map->bitmap, *from=map2->bitmap, *end;
......
...@@ -844,7 +844,7 @@ int ha_berkeley::write_row(byte * record) ...@@ -844,7 +844,7 @@ int ha_berkeley::write_row(byte * record)
ulong thd_options = table->in_use ? table->in_use->options : 0; ulong thd_options = table->in_use ? table->in_use->options : 0;
for (uint retry=0 ; retry < berkeley_trans_retry ; retry++) for (uint retry=0 ; retry < berkeley_trans_retry ; retry++)
{ {
key_map changed_keys; key_map changed_keys(0);
if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)) if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{ {
if ((error=txn_begin(db_env, transaction, &sub_trans, 0))) /* purecov: deadcode */ if ((error=txn_begin(db_env, transaction, &sub_trans, 0))) /* purecov: deadcode */
...@@ -888,7 +888,8 @@ int ha_berkeley::write_row(byte * record) ...@@ -888,7 +888,8 @@ int ha_berkeley::write_row(byte * record)
else if (!changed_keys.is_clear_all()) else if (!changed_keys.is_clear_all())
{ {
new_error = 0; new_error = 0;
for (uint keynr=0; keynr < changed_keys.length(); keynr++) for (uint keynr=0 ; keynr < table->keys+test(hidden_primary_key) ;
keynr++)
{ {
if (changed_keys.is_set(keynr)) if (changed_keys.is_set(keynr))
{ {
...@@ -1012,7 +1013,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed, ...@@ -1012,7 +1013,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
Clobbers keybuff2 Clobbers keybuff2
*/ */
int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys, int ha_berkeley::restore_keys(DB_TXN *trans, key_map *changed_keys,
uint primary_key, uint primary_key,
const byte *old_row, DBT *old_key, const byte *old_row, DBT *old_key,
const byte *new_row, DBT *new_key, const byte *new_row, DBT *new_key,
...@@ -1034,14 +1035,13 @@ int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys, ...@@ -1034,14 +1035,13 @@ int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys,
rolled back. The last key set in changed_keys is the one that rolled back. The last key set in changed_keys is the one that
triggered the duplicate key error (it wasn't inserted), so for triggered the duplicate key error (it wasn't inserted), so for
that one just put back the old value. */ that one just put back the old value. */
if (!changed_keys.is_clear_all()) if (!changed_keys->is_clear_all())
{ {
key_map map1(1); for (keynr=0 ; keynr < table->keys+test(hidden_primary_key) ; keynr++)
for (keynr=0; keynr < changed_keys.length(); keynr++)
{ {
if (changed_keys.is_set(keynr)) if (changed_keys->is_set(keynr))
{ {
if (changed_keys.is_subset(map1) && if (changed_keys->is_prefix(1) &&
(error = remove_key(trans, keynr, new_row, new_key))) (error = remove_key(trans, keynr, new_row, new_key)))
break; /* purecov: inspected */ break; /* purecov: inspected */
if ((error = key_file[keynr]->put(key_file[keynr], trans, if ((error = key_file[keynr]->put(key_file[keynr], trans,
...@@ -1094,7 +1094,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -1094,7 +1094,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
sub_trans = transaction; sub_trans = transaction;
for (uint retry=0 ; retry < berkeley_trans_retry ; retry++) for (uint retry=0 ; retry < berkeley_trans_retry ; retry++)
{ {
key_map changed_keys; key_map changed_keys(0);
if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)) if (using_ignore && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{ {
if ((error=txn_begin(db_env, transaction, &sub_trans, 0))) /* purecov: deadcode */ if ((error=txn_begin(db_env, transaction, &sub_trans, 0))) /* purecov: deadcode */
...@@ -1152,7 +1152,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) ...@@ -1152,7 +1152,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
new_error=txn_abort(sub_trans); /* purecov: deadcode */ new_error=txn_abort(sub_trans); /* purecov: deadcode */
} }
else if (!changed_keys.is_clear_all()) else if (!changed_keys.is_clear_all())
new_error=restore_keys(transaction, changed_keys, primary_key, new_error=restore_keys(transaction, &changed_keys, primary_key,
old_row, &old_prim_key, new_row, &prim_key, old_row, &old_prim_key, new_row, &prim_key,
thd_options); thd_options);
if (new_error) if (new_error)
...@@ -1233,12 +1233,12 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record, ...@@ -1233,12 +1233,12 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
/* Delete all keys for new_record */ /* Delete all keys for new_record */
int ha_berkeley::remove_keys(DB_TXN *trans, const byte *record, int ha_berkeley::remove_keys(DB_TXN *trans, const byte *record,
DBT *new_record, DBT *prim_key, key_map keys) DBT *new_record, DBT *prim_key, key_map *keys)
{ {
int result = 0; int result = 0;
for (uint keynr=0; keynr < keys.length(); keynr++) for (uint keynr=0 ; keynr < table->keys+test(hidden_primary_key) ; keynr++)
{ {
if (keys.is_set(keynr)) if (keys->is_set(keynr))
{ {
int new_error=remove_key(trans, keynr, record, prim_key); int new_error=remove_key(trans, keynr, record, prim_key);
if (new_error) if (new_error)
...@@ -1278,7 +1278,7 @@ int ha_berkeley::delete_row(const byte * record) ...@@ -1278,7 +1278,7 @@ int ha_berkeley::delete_row(const byte * record)
break; /* purecov: deadcode */ break; /* purecov: deadcode */
DBUG_PRINT("trans",("starting sub transaction")); /* purecov: deadcode */ DBUG_PRINT("trans",("starting sub transaction")); /* purecov: deadcode */
} }
error=remove_keys(sub_trans, record, &row, &prim_key, keys); error=remove_keys(sub_trans, record, &row, &prim_key, &keys);
if (!error && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)) if (!error && (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS))
{ {
DBUG_PRINT("trans",("ending sub transaction")); /* purecov: deadcode */ DBUG_PRINT("trans",("ending sub transaction")); /* purecov: deadcode */
......
...@@ -72,8 +72,8 @@ class ha_berkeley: public handler ...@@ -72,8 +72,8 @@ class ha_berkeley: public handler
uint key_length); uint key_length);
int remove_key(DB_TXN *trans, uint keynr, const byte *record, DBT *prim_key); int remove_key(DB_TXN *trans, uint keynr, const byte *record, DBT *prim_key);
int remove_keys(DB_TXN *trans,const byte *record, DBT *new_record, int remove_keys(DB_TXN *trans,const byte *record, DBT *new_record,
DBT *prim_key, key_map keys); DBT *prim_key, key_map *keys);
int restore_keys(DB_TXN *trans, key_map changed_keys, uint primary_key, int restore_keys(DB_TXN *trans, key_map *changed_keys, uint primary_key,
const byte *old_row, DBT *old_key, const byte *old_row, DBT *old_key,
const byte *new_row, DBT *new_key, const byte *new_row, DBT *new_key,
ulong thd_options); ulong thd_options);
......
...@@ -981,8 +981,8 @@ public: ...@@ -981,8 +981,8 @@ public:
String value; // value of concat String value; // value of concat
String search_value; // key_item()'s value converted to cmp_collation String search_value; // key_item()'s value converted to cmp_collation
Item_func_match(List<Item> &a, uint b): Item_real_func(a), flags(b), Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b),
table(0), master(0), ft_handler(0), concat(0), key(0), join_key(0) { } join_key(0), ft_handler(0), table(0), master(0), concat(0) { }
~Item_func_match() ~Item_func_match()
{ {
if (!master && ft_handler) if (!master && ft_handler)
......
...@@ -567,19 +567,29 @@ SEL_ARG *SEL_ARG::clone_tree() ...@@ -567,19 +567,29 @@ SEL_ARG *SEL_ARG::clone_tree()
return root; return root;
} }
/***************************************************************************** /*
** Test if a key can be used in different ranges Test if a key can be used in different ranges
** Returns:
** -1 if impossible select SYNOPSIS
** 0 if can't use quick_select SQL_SELECT::test_quick_select(thd,keys_to_use, prev_tables,
** 1 if found usable range limit, force_quick_range)
** Updates the following in the select parameter:
** needed_reg ; Bits for keys with may be used if all prev regs are read Updates the following in the select parameter:
** quick ; Parameter to use when reading records. needed_reg - Bits for keys with may be used if all prev regs are read
** In the table struct the following information is updated: quick - Parameter to use when reading records.
** quick_keys ; Which keys can be used In the table struct the following information is updated:
** quick_rows ; How many rows the key matches quick_keys - Which keys can be used
*****************************************************************************/ quick_rows - How many rows the key matches
RETURN VALUES
-1 if impossible select
0 if can't use quick_select
1 if found usable range
TODO
check if the function really needs to modify keys_to_use, and change the
code to pass it by reference if not
*/
int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables, table_map prev_tables,
......
...@@ -16,6 +16,7 @@ template <uint default_width> class Bitmap ...@@ -16,6 +16,7 @@ template <uint default_width> class Bitmap
uchar buffer[(default_width+7)/8]; uchar buffer[(default_width+7)/8];
public: public:
Bitmap() { init(); } Bitmap() { init(); }
Bitmap(Bitmap& from) { *this=from; }
Bitmap(uint prefix_to_set) { init(prefix_to_set); } Bitmap(uint prefix_to_set) { init(prefix_to_set); }
void init() { bitmap_init(&map, buffer, default_width, 0); } void init() { bitmap_init(&map, buffer, default_width, 0); }
void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); } void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
...@@ -24,6 +25,7 @@ public: ...@@ -24,6 +25,7 @@ public:
{ {
init(); init();
memcpy(buffer, map2.buffer, sizeof(buffer)); memcpy(buffer, map2.buffer, sizeof(buffer));
return *this;
} }
void set_bit(uint n) { bitmap_set_bit(&map, n); } void set_bit(uint n) { bitmap_set_bit(&map, n); }
void clear_bit(uint n) { bitmap_clear_bit(&map, n); } void clear_bit(uint n) { bitmap_clear_bit(&map, n); }
......
...@@ -1579,7 +1579,7 @@ err: ...@@ -1579,7 +1579,7 @@ err:
static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
TABLE *table, TABLE *table,
const key_map& keys,ha_rows limit) const key_map *keys,ha_rows limit)
{ {
int error; int error;
DBUG_ENTER("get_quick_record_count"); DBUG_ENTER("get_quick_record_count");
...@@ -1587,7 +1587,7 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, ...@@ -1587,7 +1587,7 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
{ {
select->head=table; select->head=table;
table->reginfo.impossible_range=0; table->reginfo.impossible_range=0;
if ((error=select->test_quick_select(thd, keys,(table_map) 0,limit)) if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,limit))
== 1) == 1)
DBUG_RETURN(select->quick->records); DBUG_RETURN(select->quick->records);
if (error == -1) if (error == -1)
...@@ -1876,7 +1876,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1876,7 +1876,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
s->on_expr ? s->on_expr : conds, s->on_expr ? s->on_expr : conds,
&error); &error);
records= get_quick_record_count(join->thd, select, s->table, records= get_quick_record_count(join->thd, select, s->table,
s->const_keys, join->row_limit); &s->const_keys, join->row_limit);
s->quick=select->quick; s->quick=select->quick;
s->needed_reg=select->needed_reg; s->needed_reg=select->needed_reg;
select->quick=0; select->quick=0;
...@@ -2104,8 +2104,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, ...@@ -2104,8 +2104,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level,
else else
{ {
JOIN_TAB *stat=field->table->reginfo.join_tab; JOIN_TAB *stat=field->table->reginfo.join_tab;
key_map possible_keys; key_map possible_keys=field->key_start;
possible_keys=field->key_start;
possible_keys.intersect(field->table->keys_in_use_for_query); possible_keys.intersect(field->table->keys_in_use_for_query);
stat[0].keys.merge(possible_keys); // Add possible keys stat[0].keys.merge(possible_keys); // Add possible keys
...@@ -8777,7 +8776,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -8777,7 +8776,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
uint j; uint j;
if (!tab->keys.is_clear_all()) if (!tab->keys.is_clear_all())
{ {
for (j=0 ; j < tab->keys.length() ; j++) for (j=0 ; j < table->keys ; j++)
{ {
if (tab->keys.is_set(j)) if (tab->keys.is_set(j))
{ {
......
...@@ -156,9 +156,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -156,9 +156,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0))); VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
if (read_string(file,(gptr*) &disk_buff,key_info_length)) if (read_string(file,(gptr*) &disk_buff,key_info_length))
goto err_not_open; /* purecov: inspected */ goto err_not_open; /* purecov: inspected */
if (disk_buff[1] & 0x80) if (disk_buff[0] & 0x80)
{ {
outparam->keys= keys= uint2korr(disk_buff) & 0x7fff; outparam->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
outparam->key_parts= key_parts= uint2korr(disk_buff+2); outparam->key_parts= key_parts= uint2korr(disk_buff+2);
} }
else else
...@@ -279,7 +279,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -279,7 +279,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (my_pread(file,(byte*) record,(uint) outparam->reclength, if (my_pread(file,(byte*) record,(uint) outparam->reclength,
(ulong) (uint2korr(head+6)+ (ulong) (uint2korr(head+6)+
((uint2korr(head+14) == 0xffff ? ((uint2korr(head+14) == 0xffff ?
uint4korr(head+10) : uint2korr(head+14)))), uint4korr(head+47) : uint2korr(head+14)))),
MYF(MY_NABP))) MYF(MY_NABP)))
goto err_not_open; /* purecov: inspected */ goto err_not_open; /* purecov: inspected */
/* HACK: table->record[2] is used instead of table->default_values here */ /* HACK: table->record[2] is used instead of table->default_values here */
......
...@@ -100,7 +100,8 @@ int rea_create_table(THD *thd, my_string file_name, ...@@ -100,7 +100,8 @@ int rea_create_table(THD *thd, my_string file_name,
goto err; goto err;
maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000)); maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
int2store(forminfo+2,maxlength); int2store(forminfo+2,maxlength);
int4store(fileinfo+10,key_buff_length); int4store(fileinfo+10,(ulong) (filepos+maxlength));
int4store(fileinfo+47,key_buff_length);
fileinfo[26]= (uchar) test((create_info->max_rows == 1) && fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
(create_info->min_rows == 1) && (keys == 0)); (create_info->min_rows == 1) && (keys == 0));
int2store(fileinfo+28,key_info_length); int2store(fileinfo+28,key_info_length);
...@@ -293,8 +294,8 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) ...@@ -293,8 +294,8 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
if (key_count > 127 || key_parts > 127) if (key_count > 127 || key_parts > 127)
{ {
key_count|=0x8000; keybuff[0]= (key_count & 0x7f) | 0x80;
int2store(keybuff,key_count); keybuff[1]= key_count >> 7;
int2store(keybuff+2,key_parts); int2store(keybuff+2,key_parts);
} }
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment