Commit 646f4e4f authored by sunny's avatar sunny

branches/5.1: Fix for bug# 36793. This is a back port from branches/zip. This

code has been tested on a big-endian machine too.
parent 1d628f12
......@@ -331,10 +331,10 @@ mach_write_to_2_little_endian(
Convert integral type from storage byte order (big endian) to
host byte order. */
UNIV_INLINE
void
ullint
mach_read_int_type(
/*===============*/
byte* dest, /* out: where to write */
/* out: integer value */
const byte* src, /* in: where to read from */
ulint len, /* in: length of src */
ibool unsigned_type); /* in: signed or unsigned flag */
......
......@@ -696,33 +696,39 @@ mach_write_to_2_little_endian(
Convert integral type from storage byte order (big endian) to
host byte order. */
UNIV_INLINE
void
ullint
mach_read_int_type(
/*===============*/
byte* dest, /* out: where to write */
/* out: integer value */
const byte* src, /* in: where to read from */
ulint len, /* in: length of src */
ibool unsigned_type) /* in: signed or unsigned flag */
{
#ifdef WORDS_BIGENDIAN
memcpy(dest, src, len);
/* XXX this can be optimized on big-endian machines */
ullint ret;
uint i;
if (unsigned_type || (src[0] & 0x80)) {
if (!unsigned_type) {
dest[0] ^= 128;
ret = 0x0000000000000000ULL;
} else {
ret = 0xFFFFFFFFFFFFFF00ULL;
}
#else
byte* ptr;
/* Convert integer data from Innobase to a little-endian format,
sign bit restored to normal. */
if (unsigned_type) {
ret |= src[0];
} else {
for (ptr = dest + len; ptr != dest; ++src) {
--ptr;
*ptr = *src;
ret |= src[0] ^ 0x80;
}
if (!unsigned_type) {
dest[len - 1] ^= 128;
for (i = 1; i < len; i++) {
ret <<= 8;
ret |= src[i];
}
#endif
return(ret);
}
......@@ -4563,8 +4563,6 @@ row_search_autoinc_read_column(
const byte* data;
ib_ulonglong value;
mem_heap_t* heap = NULL;
/* Our requirement is that dest should be word aligned. */
byte dest[sizeof(value)];
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
......@@ -4582,40 +4580,13 @@ row_search_autoinc_read_column(
ut_a(len != UNIV_SQL_NULL);
ut_a(len <= sizeof value);
mach_read_int_type(dest, data, len, unsigned_type);
/* The assumption here is that the AUTOINC value can't be negative
and that dest is word aligned. */
switch (len) {
case 8:
value = *(ib_ulonglong*) dest;
break;
case 4:
value = *(ib_uint32_t*) dest;
break;
case 3:
value = *(ib_uint32_t*) dest;
value &= 0xFFFFFF;
break;
case 2:
value = *(uint16 *) dest;
break;
case 1:
value = *dest;
break;
default:
ut_error;
}
value = mach_read_int_type(data, len, unsigned_type);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
/* We assume that the autoinc counter can't be negative. */
if (!unsigned_type && (ib_longlong) value < 0) {
value = 0;
}
......
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