MDEV-33623 Partitioning is broken on big endian architectures

MDEV-33502 Slowdown when running nested statement with many partitions
caused this error as I failed to take into account bigendian architectures.

This patch also introduces bitmap_import() and bitmap_export() to be used
when one wants to store bitmaps in files/logs in a portable way.

Reviewed-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
Monty 2024-03-08 15:18:21 +02:00
parent 9a132d423a
commit f838b2d799
10 changed files with 202 additions and 118 deletions

View file

@ -79,64 +79,68 @@ extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2);
extern void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2);
extern void bitmap_invert(MY_BITMAP *map); extern void bitmap_invert(MY_BITMAP *map);
extern void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2);
/* Functions to export/import bitmaps to an architecture independent format */
extern void bitmap_export(uchar *to, MY_BITMAP *map);
extern void bitmap_import(MY_BITMAP *map, uchar *from);
extern uint bitmap_lock_set_next(MY_BITMAP *map); extern uint bitmap_lock_set_next(MY_BITMAP *map);
extern void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit); extern void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit);
#define my_bitmap_map_bytes sizeof(my_bitmap_map) #define my_bitmap_map_bytes sizeof(my_bitmap_map)
#define my_bitmap_map_bits (my_bitmap_map_bytes*8) #define my_bitmap_map_bits (my_bitmap_map_bytes*8)
#define bitmap_buffer_size(bits) (MY_ALIGN(bits, my_bitmap_map_bits)*my_bitmap_map_bytes) #define bitmap_buffer_size(bits) (MY_ALIGN((bits), my_bitmap_map_bits)/8)
#define no_bytes_in_map(map) (((map)->n_bits + 7)/8) #define my_bitmap_buffer_size(map) bitmap_buffer_size((map)->n_bits)
#define no_bytes_in_export_map(map) (((map)->n_bits + 7)/8)
#define no_words_in_map(map) (((map)->n_bits + (my_bitmap_map_bits-1))/my_bitmap_map_bits) #define no_words_in_map(map) (((map)->n_bits + (my_bitmap_map_bits-1))/my_bitmap_map_bits)
#define bytes_word_aligned(bytes) (8*((bytes + 7)/8))
/* Fast, not thread safe, bitmap functions */ /* Fast, not thread safe, bitmap functions */
/* The following functions must be compatible with create_last_bit_mask()! */ /* The following functions must be compatible with create_last_bit_mask()! */
static inline void static inline void
bitmap_set_bit(MY_BITMAP *map,uint bit) bitmap_set_bit(MY_BITMAP *map,uint bit)
{ {
uchar *b= (uchar*) map->bitmap + bit / 8;
DBUG_ASSERT(bit < map->n_bits); DBUG_ASSERT(bit < map->n_bits);
*b= (uchar) (*b | 1U << (bit & 7)); map->bitmap[bit/my_bitmap_map_bits]|=
(1ULL << (bit & (my_bitmap_map_bits-1)));
} }
static inline void static inline void
bitmap_flip_bit(MY_BITMAP *map,uint bit) bitmap_flip_bit(MY_BITMAP *map,uint bit)
{ {
uchar *b= (uchar*) map->bitmap + bit / 8;
DBUG_ASSERT(bit < map->n_bits); DBUG_ASSERT(bit < map->n_bits);
*b= (uchar) (*b ^ 1U << (bit & 7)); map->bitmap[bit/my_bitmap_map_bits]^=
(1ULL << (bit & (my_bitmap_map_bits-1)));
} }
static inline void static inline void
bitmap_clear_bit(MY_BITMAP *map,uint bit) bitmap_clear_bit(MY_BITMAP *map,uint bit)
{ {
uchar *b= (uchar*) map->bitmap + bit / 8;
DBUG_ASSERT(bit < map->n_bits); DBUG_ASSERT(bit < map->n_bits);
*b= (uchar) (*b & ~(1U << (bit & 7))); map->bitmap[bit/my_bitmap_map_bits]&=
~(1ULL << (bit & (my_bitmap_map_bits-1)));
} }
static inline uint static inline uint
bitmap_is_set(const MY_BITMAP *map,uint bit) bitmap_is_set(const MY_BITMAP *map,uint bit)
{ {
const uchar *b= (const uchar*) map->bitmap + bit / 8;
DBUG_ASSERT(bit < map->n_bits); DBUG_ASSERT(bit < map->n_bits);
return !!(*b & (1U << (bit & 7))); return (!!(map->bitmap[bit/my_bitmap_map_bits] &
(1ULL << (bit & (my_bitmap_map_bits-1)))));
} }
/* Return true if bitmaps are equal */ /* Return true if bitmaps are equal */
static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
{ {
DBUG_ASSERT(map1->n_bits == map2->n_bits); DBUG_ASSERT(map1->n_bits == map2->n_bits);
return (memcmp(map1->bitmap, map2->bitmap, 8*(no_words_in_map(map1))) == 0); return (memcmp(map1->bitmap, map2->bitmap,
my_bitmap_buffer_size(map1)) == 0);
} }
#define bitmap_clear_all(MAP) \ #define bitmap_clear_all(MAP) \
{ memset((MAP)->bitmap, 0, 8*no_words_in_map((MAP))); } { memset((MAP)->bitmap, 0, my_bitmap_buffer_size(MAP)); }
static inline void static inline void
bitmap_set_all(const MY_BITMAP *map) bitmap_set_all(const MY_BITMAP *map)
{ {
if (map->n_bits) if (map->n_bits)
{ {
memset(map->bitmap, 0xFF, 8*(no_words_in_map(map)-1)); memset(map->bitmap, 0xFF, my_bitmap_map_bytes * (no_words_in_map(map)-1));
DBUG_ASSERT(map->bitmap + no_words_in_map(map)-1 == map->last_word_ptr); DBUG_ASSERT(map->bitmap + no_words_in_map(map)-1 == map->last_word_ptr);
*map->last_word_ptr= ~map->last_bit_mask; *map->last_word_ptr= ~map->last_bit_mask;
} }

View file

@ -18,7 +18,7 @@
*/ */
/* /*
Handling of uchar arrays as large bitmaps. Handling of my_bitmap_map (ulonglong) arrays as large bitmaps.
API limitations (or, rather asserted safety assumptions, API limitations (or, rather asserted safety assumptions,
to encourage correct programming) to encourage correct programming)
@ -222,12 +222,14 @@ void my_bitmap_free(MY_BITMAP *map)
my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit) my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
{ {
uchar *value= ((uchar*) map->bitmap) + (bitmap_bit / 8); my_bitmap_map *value, bit, res;
uchar bit= 1 << ((bitmap_bit) & 7);
uchar res= (*value) & bit;
DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit);
value= map->bitmap + (bitmap_bit/my_bitmap_map_bits);
bit= 1ULL << (bitmap_bit & (my_bitmap_map_bits-1));
res= *value & bit;
*value|= bit; *value|= bit;
return res; return MY_TEST(res);
} }
@ -269,13 +271,14 @@ my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit)
my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit) my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit)
{ {
uchar *byte= (uchar*) map->bitmap + (bitmap_bit / 8); my_bitmap_map *value, bit, res;
uchar bit= 1 << ((bitmap_bit) & 7);
uchar res= (*byte) & bit;
DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit);
*byte&= ~bit; value= map->bitmap + (bitmap_bit/my_bitmap_map_bits);
return res; bit= 1ULL << (bitmap_bit & (my_bitmap_map_bits-1));
res= *value & bit;
*value&= ~bit;
return MY_TEST(res);
} }
@ -310,23 +313,24 @@ uint bitmap_set_next(MY_BITMAP *map)
void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
{ {
uint prefix_bytes, prefix_bits, d; uint prefix, prefix_bits;
uchar *m= (uchar *)map->bitmap; my_bitmap_map *value= map->bitmap;
DBUG_ASSERT_BITMAP(map); DBUG_ASSERT_BITMAP(map);
DBUG_ASSERT(prefix_size <= map->n_bits || prefix_size == (uint) ~0); DBUG_ASSERT(prefix_size <= map->n_bits || prefix_size == (uint) ~0);
set_if_smaller(prefix_size, map->n_bits); set_if_smaller(prefix_size, map->n_bits);
if ((prefix_bytes= prefix_size / 8))
memset(m, 0xff, prefix_bytes); if ((prefix= prefix_size / my_bitmap_map_bits))
m+= prefix_bytes;
if ((prefix_bits= prefix_size & 7))
{ {
*(m++)= (1 << prefix_bits)-1; my_bitmap_map *end= value+prefix;
// As the prefix bits are set, lets count this byte too as a prefix byte. do
prefix_bytes ++; {
*value++= ~(my_bitmap_map) 0;
} while (value < end);
} }
if ((d= no_bytes_in_map(map)-prefix_bytes)) if ((prefix_bits= prefix_size & (my_bitmap_map_bits-1)))
memset(m, 0, d); *value++= (1ULL << prefix_bits)-1;
while (value <= map->last_word_ptr)
*value++= 0;
DBUG_ASSERT_BITMAP(map); DBUG_ASSERT_BITMAP(map);
} }
@ -343,10 +347,9 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{ {
uint prefix_mask= last_byte_mask(prefix_size); my_bitmap_map *value= map->bitmap;
uchar *m= (uchar*) map->bitmap; my_bitmap_map *end= value+ (prefix_size/my_bitmap_map_bits);
uchar *end_prefix= m+(prefix_size-1)/8; uint prefix_bits;
uchar *end;
/* Empty prefix is always true */ /* Empty prefix is always true */
if (!prefix_size) if (!prefix_size)
@ -354,16 +357,18 @@ my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
DBUG_ASSERT_BITMAP_AND_BIT(map, prefix_size-1); DBUG_ASSERT_BITMAP_AND_BIT(map, prefix_size-1);
while (m < end_prefix) while (value < end)
if (*m++ != 0xff) if (*value++ != ~(my_bitmap_map) 0)
return 0; return 0;
end= ((uchar*) map->last_word_ptr) + sizeof(*map->last_word_ptr)-1; if ((prefix_bits= prefix_size & (my_bitmap_map_bits-1)))
if (*m != prefix_mask) {
if (*value++ != (1ULL << prefix_bits)-1)
return 0; return 0;
}
while (++m <= end) end= map->last_word_ptr;
if (*m != 0) while (value <= end)
if (*value++ != 0)
return 0; return 0;
return 1; return 1;
} }
@ -700,3 +705,64 @@ void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit)
bitmap_clear_bit(map, bitmap_bit); bitmap_clear_bit(map, bitmap_bit);
bitmap_unlock(map); bitmap_unlock(map);
} }
/*
Functions to export/import bitmaps to an architecture independent format
(low_byte_first)
*/
#ifdef WORDS_BIGENDIAN
/* Big endian machines, like powerpc or s390x */
void bitmap_export(uchar *to, MY_BITMAP *map)
{
my_bitmap_map *value;
uint length;
uchar buff[my_bitmap_map_bytes];
for (value= map->bitmap ; value < map->last_word_ptr ; value++)
{
int8store(to, *value);
to+= 8;
}
int8store(buff, *value);
/* We want length & 7 to return a serie 8,2,3,4,5,6,7, 8,2,3,... */
length= 1+ ((no_bytes_in_export_map(map) + 7) & 7);
memcpy(to, buff, length);
}
void bitmap_import(MY_BITMAP *map, uchar *from)
{
my_bitmap_map *value;
uint length;
uchar buff[my_bitmap_map_bytes];
for (value= map->bitmap ; value < map->last_word_ptr ; value++)
{
*value= uint8korr(from);
from+= 8;
}
bzero(buff, sizeof(buff));
/* We want length & 7 to return a serie 8,2,3,4,5,6,7, 8,2,3,... */
length= 1+ ((no_bytes_in_export_map(map) + 7) & 7);
memcpy(buff, from, length);
*value= uint8korr(buff) & ~map->last_bit_mask;
}
#else
/* Little endian machines, like intel and amd */
void bitmap_export(uchar *to, MY_BITMAP *map)
{
memcpy(to, (uchar*) map->bitmap, no_bytes_in_export_map(map));
}
void bitmap_import(MY_BITMAP *map, uchar *from)
{
memcpy((uchar*) map->bitmap, from, no_bytes_in_export_map(map));
*map->last_word_ptr&= ~map->last_bit_mask;
}
#endif /* WORDS_BIGENDIAN */

View file

@ -3392,10 +3392,9 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len,
false))) false)))
{ {
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8); bitmap_import(&m_cols, ptr_after_width);
create_last_bit_mask(&m_cols); // Needed to fix last part of bitmap DBUG_DUMP("m_cols", (uchar*) ptr_after_width, no_bytes_in_export_map(&m_cols));
ptr_after_width+= (m_width + 7) / 8; ptr_after_width+= (m_width + 7) / 8;
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
} }
else else
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -3414,11 +3413,9 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len,
false))) false)))
{ {
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8); bitmap_import(&m_cols_ai, ptr_after_width);
create_last_bit_mask(&m_cols_ai); // Needed to fix last part of bitmap DBUG_DUMP("m_cols_ai", ptr_after_width, no_bytes_in_export_map(&m_cols_ai));
ptr_after_width+= (m_width + 7) / 8; ptr_after_width+= (m_width + 7) / 8;
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
no_bytes_in_map(&m_cols_ai));
} }
else else
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -3497,8 +3494,9 @@ int Rows_log_event::get_data_size()
uchar *end= net_store_length(buf, m_width); uchar *end= net_store_length(buf, m_width);
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
return (int)(6 + no_bytes_in_map(&m_cols) + (end - buf) + return (int) (6 + no_bytes_in_export_map(&m_cols) + (end - buf) +
(general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) + (general_type_code == UPDATE_ROWS_EVENT ?
no_bytes_in_export_map(&m_cols_ai) : 0) +
m_rows_cur - m_rows_buf);); m_rows_cur - m_rows_buf););
int data_size= 0; int data_size= 0;
Log_event_type type= get_type_code(); Log_event_type type= get_type_code();
@ -3514,11 +3512,11 @@ int Rows_log_event::get_data_size()
{ {
data_size= ROWS_HEADER_LEN_V1; data_size= ROWS_HEADER_LEN_V1;
} }
data_size+= no_bytes_in_map(&m_cols); data_size+= no_bytes_in_export_map(&m_cols);
data_size+= (uint) (end - buf); data_size+= (uint) (end - buf);
if (general_type_code == UPDATE_ROWS_EVENT) if (general_type_code == UPDATE_ROWS_EVENT)
data_size+= no_bytes_in_map(&m_cols_ai); data_size+= no_bytes_in_export_map(&m_cols_ai);
data_size+= (uint) (m_rows_cur - m_rows_buf); data_size+= (uint) (m_rows_cur - m_rows_buf);
return data_size; return data_size;

View file

@ -1229,17 +1229,12 @@ Old_rows_log_event::Old_rows_log_event(const uchar *buf, uint event_len,
false))) false)))
{ {
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8); bitmap_import(&m_cols, ptr_after_width);
create_last_bit_mask(&m_cols); // Needed to fix last part of bitmap DBUG_DUMP("m_cols", ptr_after_width, no_bytes_in_export_map(&m_cols));
ptr_after_width+= (m_width + 7) / 8; ptr_after_width+= (m_width + 7) / 8;
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
} }
else else
{
// Needed because my_bitmap_init() does not set it to null on failure
m_cols.bitmap= NULL;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
}
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
@ -1257,8 +1252,6 @@ Old_rows_log_event::Old_rows_log_event(const uchar *buf, uint event_len,
m_rows_cur= m_rows_end; m_rows_cur= m_rows_end;
memcpy(m_rows_buf, ptr_rows_data, data_size); memcpy(m_rows_buf, ptr_rows_data, data_size);
} }
else
m_cols.bitmap= 0; // to not free it
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1277,10 +1270,10 @@ int Old_rows_log_event::get_data_size()
uchar *end= net_store_length(buf, (m_width + 7) / 8); uchar *end= net_store_length(buf, (m_width + 7) / 8);
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
return (int)(6 + no_bytes_in_map(&m_cols) + (end - buf) + return (int)(6 + no_bytes_in_export_map(&m_cols) + (end - buf) +
m_rows_cur - m_rows_buf);); m_rows_cur - m_rows_buf););
int data_size= ROWS_HEADER_LEN; int data_size= ROWS_HEADER_LEN;
data_size+= no_bytes_in_map(&m_cols); data_size+= no_bytes_in_export_map(&m_cols);
data_size+= (uint) (end - buf); data_size+= (uint) (end - buf);
data_size+= (uint) (m_rows_cur - m_rows_buf); data_size+= (uint) (m_rows_cur - m_rows_buf);
@ -1798,6 +1791,8 @@ bool Old_rows_log_event::write_data_body()
*/ */
uchar sbuf[MAX_INT_WIDTH]; uchar sbuf[MAX_INT_WIDTH];
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf; my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
uint bitmap_size= no_bytes_in_export_map(&m_cols);
uchar *bitmap;
// This method should not be reached. // This method should not be reached.
assert(0); assert(0);
@ -1809,10 +1804,14 @@ bool Old_rows_log_event::write_data_body()
DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf)); DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
res= res || write_data(sbuf, (size_t) (sbuf_end - sbuf)); res= res || write_data(sbuf, (size_t) (sbuf_end - sbuf));
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); bitmap= (uchar*) my_alloca(bitmap_size);
res= res || write_data((uchar*)m_cols.bitmap, no_bytes_in_map(&m_cols)); bitmap_export(bitmap, &m_cols);
DBUG_DUMP("m_cols", bitmap, no_bytes_in_export_map(&m_cols));
res= res || write_data(bitmap, no_bytes_in_export_map(&m_cols));
DBUG_DUMP("rows", m_rows_buf, data_size); DBUG_DUMP("rows", m_rows_buf, data_size);
res= res || write_data(m_rows_buf, (size_t) data_size); res= res || write_data(m_rows_buf, (size_t) data_size);
my_afree(bitmap);
return res; return res;

View file

@ -6085,30 +6085,37 @@ bool Rows_log_event::write_data_body()
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf; my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
bool res= false; bool res= false;
uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width); uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
uint bitmap_size= no_bytes_in_export_map(&m_cols);
uchar *bitmap;
DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf)); DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf)); DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
res= res || write_data(sbuf, (size_t) (sbuf_end - sbuf)); res= res || write_data(sbuf, (size_t) (sbuf_end - sbuf));
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); bitmap= (uchar*) my_alloca(bitmap_size);
res= res || write_data((uchar*)m_cols.bitmap, no_bytes_in_map(&m_cols)); bitmap_export(bitmap, &m_cols);
DBUG_DUMP("m_cols", bitmap, bitmap_size);
res= res || write_data(bitmap, bitmap_size);
/* /*
TODO[refactor write]: Remove the "down cast" here (and elsewhere). TODO[refactor write]: Remove the "down cast" here (and elsewhere).
*/ */
if (get_general_type_code() == UPDATE_ROWS_EVENT) if (get_general_type_code() == UPDATE_ROWS_EVENT)
{ {
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap, DBUG_ASSERT(m_cols.n_bits == m_cols_ai.n_bits);
no_bytes_in_map(&m_cols_ai)); bitmap_export(bitmap, &m_cols_ai);
res= res || write_data((uchar*)m_cols_ai.bitmap,
no_bytes_in_map(&m_cols_ai)); DBUG_DUMP("m_cols_ai", bitmap, bitmap_size);
res= res || write_data(bitmap, bitmap_size);
} }
DBUG_DUMP("rows", m_rows_buf, data_size); DBUG_DUMP("rows", m_rows_buf, data_size);
res= res || write_data(m_rows_buf, (size_t) data_size); res= res || write_data(m_rows_buf, (size_t) data_size);
my_afree(bitmap);
return res; return res;
} }
bool Rows_log_event::write_compressed() bool Rows_log_event::write_compressed()
{ {
uchar *m_rows_buf_tmp= m_rows_buf; uchar *m_rows_buf_tmp= m_rows_buf;
@ -8391,10 +8398,7 @@ void Update_rows_log_event::init(MY_BITMAP const *cols)
{ {
/* Cols can be zero if this is a dummy binrows event */ /* Cols can be zero if this is a dummy binrows event */
if (likely(cols != NULL)) if (likely(cols != NULL))
{ bitmap_copy(&m_cols_ai, cols);
memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
create_last_bit_mask(&m_cols_ai); // Needed to fix last part of bitmap
}
} }
} }

View file

@ -6781,8 +6781,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param)
void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
{ {
dst->param= src->param; dst->param= src->param;
memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap, bitmap_copy(&dst->covered_fields, &src->covered_fields);
no_bytes_in_map(&src->covered_fields));
dst->out_rows= src->out_rows; dst->out_rows= src->out_rows;
dst->is_covering= src->is_covering; dst->is_covering= src->is_covering;
dst->index_records= src->index_records; dst->index_records= src->index_records;

View file

@ -379,19 +379,19 @@ int ha_spider::open(
spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME | MY_ZEROFILL), spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME | MY_ZEROFILL),
&wide_handler, sizeof(SPIDER_WIDE_HANDLER), &wide_handler, sizeof(SPIDER_WIDE_HANDLER),
&searched_bitmap, &searched_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&ft_discard_bitmap, &ft_discard_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&position_bitmap, &position_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&idx_read_bitmap, &idx_read_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&idx_write_bitmap, &idx_write_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&rnd_read_bitmap, &rnd_read_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&rnd_write_bitmap, &rnd_write_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&partition_handler, &partition_handler,
(uint) sizeof(SPIDER_PARTITION_HANDLER), (uint) sizeof(SPIDER_PARTITION_HANDLER),
NullS) NullS)
@ -399,19 +399,19 @@ int ha_spider::open(
spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME | MY_ZEROFILL), spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME | MY_ZEROFILL),
&wide_handler, sizeof(SPIDER_WIDE_HANDLER), &wide_handler, sizeof(SPIDER_WIDE_HANDLER),
&searched_bitmap, &searched_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&ft_discard_bitmap, &ft_discard_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&position_bitmap, &position_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&idx_read_bitmap, &idx_read_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&idx_write_bitmap, &idx_write_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&rnd_read_bitmap, &rnd_read_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
&rnd_write_bitmap, &rnd_write_bitmap,
(uint) sizeof(uchar) * no_bytes_in_map(table->read_set), (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set),
NullS) NullS)
#endif #endif
) )
@ -436,9 +436,9 @@ int ha_spider::open(
wide_handler->top_share = table->s; wide_handler->top_share = table->s;
owner->wide_handler_owner = TRUE; owner->wide_handler_owner = TRUE;
memset(wide_handler->ft_discard_bitmap, 0xFF, memset(wide_handler->ft_discard_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
memset(wide_handler->searched_bitmap, 0, memset(wide_handler->searched_bitmap, 0,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
wide_handler_alloc = TRUE; wide_handler_alloc = TRUE;
if (!share && !spider_get_share(name, table, thd, this, &error_num)) if (!share && !spider_get_share(name, table, thd, this, &error_num))
@ -1386,9 +1386,9 @@ int ha_spider::reset()
if (!is_clone) if (!is_clone)
{ {
memset(wide_handler->ft_discard_bitmap, 0xFF, memset(wide_handler->ft_discard_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
memset(wide_handler->searched_bitmap, 0, memset(wide_handler->searched_bitmap, 0,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
} }
while (wide_handler->condition) while (wide_handler->condition)
{ {
@ -1678,7 +1678,7 @@ int ha_spider::index_init(
bitmap_set_all(table->read_set); bitmap_set_all(table->read_set);
if (is_clone) if (is_clone)
memset(wide_handler->searched_bitmap, 0xFF, memset(wide_handler->searched_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
} }
} }
@ -4114,7 +4114,7 @@ ha_rows ha_spider::multi_range_read_info_const(
bitmap_set_all(table->read_set); bitmap_set_all(table->read_set);
if (is_clone) if (is_clone)
memset(wide_handler->searched_bitmap, 0xFF, memset(wide_handler->searched_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
} }
} }
@ -4179,7 +4179,7 @@ ha_rows ha_spider::multi_range_read_info(
bitmap_set_all(table->read_set); bitmap_set_all(table->read_set);
if (is_clone) if (is_clone)
memset(wide_handler->searched_bitmap, 0xFF, memset(wide_handler->searched_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
} }
} }
@ -7183,7 +7183,7 @@ int ha_spider::rnd_init(
bitmap_set_all(table->read_set); bitmap_set_all(table->read_set);
if (is_clone) if (is_clone)
memset(wide_handler->searched_bitmap, 0xFF, memset(wide_handler->searched_bitmap, 0xFF,
no_bytes_in_map(table->read_set)); my_bitmap_buffer_size(table->read_set));
} }
set_select_column_mode(); set_select_column_mode();

View file

@ -4484,7 +4484,7 @@ int spider_handlersocket_handler::init()
&link_for_hash, &link_for_hash,
sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count,
&minimum_select_bitmap, &minimum_select_bitmap,
table ? sizeof(uchar) * no_bytes_in_map(table->read_set) : 0, table ? sizeof(uchar) * my_bitmap_buffer_size(table->read_set) : 0,
NullS)) NullS))
) { ) {
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@ -6159,7 +6159,7 @@ void spider_handlersocket_handler::minimum_select_bitmap_create()
TABLE *table = spider->get_table(); TABLE *table = spider->get_table();
Field **field_p; Field **field_p;
DBUG_ENTER("spider_handlersocket_handler::minimum_select_bitmap_create"); DBUG_ENTER("spider_handlersocket_handler::minimum_select_bitmap_create");
memset(minimum_select_bitmap, 0, no_bytes_in_map(table->read_set)); memset(minimum_select_bitmap, 0, my_bitmap_buffer_size(table->read_set));
if ( if (
spider->use_index_merge || spider->use_index_merge ||
#ifdef HA_CAN_BULK_ACCESS #ifdef HA_CAN_BULK_ACCESS
@ -6174,7 +6174,7 @@ void spider_handlersocket_handler::minimum_select_bitmap_create()
table_share->primary_key == MAX_KEY table_share->primary_key == MAX_KEY
) { ) {
/* need all columns */ /* need all columns */
memset(minimum_select_bitmap, 0xFF, no_bytes_in_map(table->read_set)); memset(minimum_select_bitmap, 0xFF, my_bitmap_buffer_size(table->read_set));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} else { } else {
/* need primary key columns */ /* need primary key columns */

View file

@ -8591,7 +8591,7 @@ int spider_mbase_handler::init()
&link_for_hash, &link_for_hash,
sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count,
&minimum_select_bitmap, &minimum_select_bitmap,
table ? sizeof(uchar) * no_bytes_in_map(table->read_set) : 0, table ? sizeof(uchar) * my_bitmap_buffer_size(table->read_set) : 0,
NullS)) NullS))
) { ) {
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@ -15750,7 +15750,7 @@ void spider_mbase_handler::minimum_select_bitmap_create()
Field **field_p; Field **field_p;
DBUG_ENTER("spider_mbase_handler::minimum_select_bitmap_create"); DBUG_ENTER("spider_mbase_handler::minimum_select_bitmap_create");
DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider this=%p", this));
memset(minimum_select_bitmap, 0, no_bytes_in_map(table->read_set)); memset(minimum_select_bitmap, 0, my_bitmap_buffer_size(table->read_set));
if ( if (
spider->use_index_merge || spider->use_index_merge ||
#ifdef HA_CAN_BULK_ACCESS #ifdef HA_CAN_BULK_ACCESS
@ -15765,7 +15765,7 @@ void spider_mbase_handler::minimum_select_bitmap_create()
table_share->primary_key == MAX_KEY table_share->primary_key == MAX_KEY
) { ) {
/* need all columns */ /* need all columns */
memset(minimum_select_bitmap, 0xFF, no_bytes_in_map(table->read_set)); memset(minimum_select_bitmap, 0xFF, my_bitmap_buffer_size(table->read_set));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} else { } else {
/* need primary key columns */ /* need primary key columns */

View file

@ -512,10 +512,14 @@ error:
my_bool test_copy(MY_BITMAP *map, uint bitsize) my_bool test_copy(MY_BITMAP *map, uint bitsize)
{ {
my_bitmap_map buff[16]; my_bitmap_map buff[16], buff2[16], buff3[16];
MY_BITMAP map2; MY_BITMAP map2, map3;
uint rnd_bit;
my_bitmap_init(&map2, buff, sizeof(buff)*8, FALSE); my_bitmap_init(&map2, buff, sizeof(buff)*8, FALSE);
memset((void*) buff, 0xff, sizeof(buff)); my_bitmap_init(&map3, buff2, sizeof(buff)*8, FALSE);
bitmap_set_all(&map2);
bitmap_set_all(&map3);
bitsize= MY_MIN(bitsize, map2.n_bits); bitsize= MY_MIN(bitsize, map2.n_bits);
bitmap_copy(map, &map2); bitmap_copy(map, &map2);
@ -524,6 +528,15 @@ my_bool test_copy(MY_BITMAP *map, uint bitsize)
diag("bitmap_copy failed on bitsize %d", bitsize); diag("bitmap_copy failed on bitsize %d", bitsize);
return 1; return 1;
} }
bitmap_set_prefix(&map2, rnd_bit= get_rand_bit(bitsize)+1);
bitmap_export((uchar*) buff3, &map2);
bitmap_import(&map3, (uchar*) buff3);
if (!bitmap_cmp(&map2, &map3))
{
diag("bitmap_export/bitmap_import failed on bitsize %d rnd_bit: %d",
bitsize, rnd_bit);
return 1;
}
return 0; return 0;
} }
@ -639,6 +652,7 @@ my_bool do_test(uint bitsize)
bitmap_clear_all(&map); bitmap_clear_all(&map);
if (test_copy(&map,bitsize)) if (test_copy(&map,bitsize))
goto error; goto error;
bitmap_clear_all(&map);
if (test_bitmap_exists_intersection(&map, bitsize)) if (test_bitmap_exists_intersection(&map, bitsize))
goto error; goto error;
return FALSE; return FALSE;