diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-11-06 14:38:03 -0500 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-11-09 09:28:00 -0500 |
commit | 7ec655850397a0edfcea8c1fd82650824297e564 (patch) | |
tree | ee9eee5fa9fe5205a7e3950327c17afe93d2cd2a /sql/sql_bitmap.h | |
parent | d6b430c91b6ef6acd0b5adab6106915599c1abcc (diff) | |
download | mariadb-git-7ec655850397a0edfcea8c1fd82650824297e564.tar.gz |
MDEV-9021: MYSQLD SEGFAULTS WHEN BUILT USING --WITH-MAX-INDEXES=128
The bitmap implementation defines two template Bitmap classes. One
optimized for 64-bit (default) wide bitmaps while the other is used for
all other widths.
In order to optimize the computations, Bitmap<64> class has defined its
own member functions for bitmap operations, the other one, however,
relies on mysys' bitmap implementation (mysys/my_bitmap.c).
Issue 1:
In case of non 64-bit Bitmap class, intersect() wrongly reset the
received bitmap while initialising a new local bitmap structure
(bitmap_init() clears the bitmap buffer) thus, the received bitmap was
getting cleared.
Fixed by initializing the local bitmap structure by using a temporary
buffer and later copying the received bitmap to the initialised bitmap
structure.
Issue 2:
The non 64-bit Bitmap class had the Iterator missing which caused
compilation failure.
Also added a cmake variable to hold the MAX_INDEXES value when supplied
from the command prompt. (eg. cmake .. -DMAX_INDEXES=128U). Checks have
been put in place to trigger build failure if MAX_INDEXES value is
greater than 128.
Test modifications:
* Introduced include/have_max_indexes_[64|128].inc to facilitate
skipping of tests for which the output differs with different
MAX_INDEXES.
* Introduced include/max_indexes.inc which would get modified by cmake
to reflect the MAX_INDEXES value used to build the server. This file
simply sets an mtr variable '$max_indexes' to show the MAX_INDEXES
value, which will then be consumed by the above introduced include file.
* Some tests (portions), dependent on MAX_INDEXES value, have been moved
to separate test files.
Diffstat (limited to 'sql/sql_bitmap.h')
-rw-r--r-- | sql/sql_bitmap.h | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 229c4dc8379..5a2caf89fe2 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -51,8 +51,27 @@ public: void intersect(Bitmap& map2) { bitmap_intersect(&map, &map2.map); } void intersect(ulonglong map2buff) { + // Use a spearate temporary buffer, as bitmap_init() clears all the bits. + ulonglong buf2; MY_BITMAP map2; - my_bitmap_init(&map2, (uint32 *)&map2buff, sizeof(ulonglong)*8, 0); + + my_bitmap_init(&map2, (uint32 *) &buf2, sizeof(ulonglong) * 8, 0); + + // Store the original bits. + if (sizeof(ulonglong) >= 8) + { + int8store(const_cast<uchar *>(static_cast<uchar *> + (static_cast<void *>(&buf2))), + map2buff); + } + else + { + DBUG_ASSERT(sizeof(buffer) >= 4); + int4store(const_cast<uchar *>(static_cast<uchar *> + (static_cast<void *>(&buf2))), + static_cast<uint32>(map2buff)); + } + bitmap_intersect(&map, &map2); } /* Use highest bit for all bits above sizeof(ulonglong)*8. */ @@ -93,14 +112,33 @@ public: ulonglong to_ulonglong() const { if (sizeof(buffer) >= 8) - return uint8korr(buffer); + return uint8korr(static_cast<const uchar *> + (static_cast<const void *>(buffer))); DBUG_ASSERT(sizeof(buffer) >= 4); - return (ulonglong) uint4korr(buffer); + return (ulonglong) + uint4korr(static_cast<const uchar *> + (static_cast<const void *>(buffer))); } uint bits_set() { return bitmap_bits_set(&map); } + class Iterator + { + Bitmap ↦ + uint no; + public: + Iterator(Bitmap<default_width> &map2): map(map2), no(0) {} + int operator++(int) { + if (no == default_width) return BITMAP_END; + while (!map.is_set(no)) + { + if ((++no) == default_width) return BITMAP_END; + } + return no ++; + } + enum { BITMAP_END= default_width }; + }; }; /* An iterator to quickly walk over bits in unlonglong bitmap. */ |