Commit 49b51dd2 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge mysql-5.1 to mysql-5.5.

parents dbb6af27 2bb6cefa
CREATE TABLE bug14753402(a34 INT, col8953 NATIONAL CHAR(231) NOT NULL)
ENGINE=INNODB ROW_FORMAT=REDUNDANT;
INSERT INTO bug14753402 VALUES(1, 'aa');
CREATE INDEX idx1 ON bug14753402(col8953(165));
DROP TABLE bug14753402;
#
# Test Bug 14753402 - FAILING ASSERTION: LEN == IFIELD->FIXED_LEN
#
-- source include/have_innodb.inc
CREATE TABLE bug14753402(a34 INT, col8953 NATIONAL CHAR(231) NOT NULL)
ENGINE=INNODB ROW_FORMAT=REDUNDANT;
INSERT INTO bug14753402 VALUES(1, 'aa');
CREATE INDEX idx1 ON bug14753402(col8953(165));
DROP TABLE bug14753402;
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -459,36 +459,18 @@ dtype_get_fixed_size_low( ...@@ -459,36 +459,18 @@ dtype_get_fixed_size_low(
} else if (!comp) { } else if (!comp) {
return(len); return(len);
} else { } else {
/* We play it safe here and ask MySQL for #ifdef UNIV_DEBUG
mbminlen and mbmaxlen. Although
mbminlen and mbmaxlen are
initialized if and only if prtype
is (in one of the 3 functions in this file),
it could be that none of these functions
has been called. */
ulint i_mbminlen, i_mbmaxlen; ulint i_mbminlen, i_mbmaxlen;
innobase_get_cset_width( innobase_get_cset_width(
dtype_get_charset_coll(prtype), dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen); &i_mbminlen, &i_mbmaxlen);
if (UNIV_UNLIKELY ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) == mbminmaxlen);
!= mbminmaxlen)) { #endif /* UNIV_DEBUG */
if (DATA_MBMINLEN(mbminmaxlen)
ut_print_timestamp(stderr); == DATA_MBMAXLEN(mbminmaxlen)) {
fprintf(stderr, " InnoDB: "
"mbminlen=%lu, "
"mbmaxlen=%lu, "
"type->mbminlen=%lu, "
"type->mbmaxlen=%lu\n",
(ulong) i_mbminlen,
(ulong) i_mbmaxlen,
(ulong) DATA_MBMINLEN(mbminmaxlen),
(ulong) DATA_MBMAXLEN(mbminmaxlen));
}
if (i_mbminlen == i_mbmaxlen) {
return(len); return(len);
} }
} }
......
...@@ -361,24 +361,6 @@ rec_get_offsets_func( ...@@ -361,24 +361,6 @@ rec_get_offsets_func(
#define rec_get_offsets(rec,index,offsets,n,heap) \ #define rec_get_offsets(rec,index,offsets,n,heap) \
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__) rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
/******************************************************//**
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
UNIV_INTERN
void
rec_init_offsets_comp_ordinary(
/*===========================*/
const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
ulint extra, /*!< in: number of bytes to reserve
between the record header and
the data payload
(usually REC_N_NEW_EXTRA_BYTES) */
const dict_index_t* index, /*!< in: record descriptor */
ulint* offsets);/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
/******************************************************//** /******************************************************//**
The following function determines the offsets to each field The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */ in the record. It can reuse a previously allocated array. */
...@@ -644,8 +626,48 @@ rec_copy( ...@@ -644,8 +626,48 @@ rec_copy(
/*=====*/ /*=====*/
void* buf, /*!< in: buffer */ void* buf, /*!< in: buffer */
const rec_t* rec, /*!< in: physical record */ const rec_t* rec, /*!< in: physical record */
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
__attribute__((nonnull));
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
/**********************************************************//**
Determines the size of a data tuple prefix in a temporary file.
@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_temp(
/*========================*/
const dict_index_t* index, /*!< in: record descriptor */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
ulint* extra) /*!< out: extra size */
__attribute__((warn_unused_result, nonnull));
/******************************************************//**
Determine the offset to each field in temporary file.
@see rec_convert_dtuple_to_temp() */
UNIV_INTERN
void
rec_init_offsets_temp(
/*==================*/
const rec_t* rec, /*!< in: temporary file record */
const dict_index_t* index, /*!< in: record descriptor */
ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
__attribute__((nonnull));
/*********************************************************//**
Builds a temporary file record out of a data tuple.
@see rec_init_offsets_temp() */
UNIV_INTERN
void
rec_convert_dtuple_to_temp(
/*=======================*/
rec_t* rec, /*!< out: record */
const dict_index_t* index, /*!< in: record descriptor */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields) /*!< in: number of fields */
__attribute__((nonnull));
/**************************************************************//** /**************************************************************//**
Copies the first n fields of a physical record to a new physical record in Copies the first n fields of a physical record to a new physical record in
a buffer. a buffer.
...@@ -680,21 +702,6 @@ rec_fold( ...@@ -680,21 +702,6 @@ rec_fold(
__attribute__((pure)); __attribute__((pure));
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
/*********************************************************//** /*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
UNIV_INTERN
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
rec_t* rec, /*!< in: origin of record */
ulint extra, /*!< in: number of bytes to
reserve between the record
header and the data payload
(normally REC_N_NEW_EXTRA_BYTES) */
const dict_index_t* index, /*!< in: record descriptor */
ulint status, /*!< in: status bits of the record */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields);/*!< in: number of data fields */
/*********************************************************//**
Builds a physical record out of a data tuple and Builds a physical record out of a data tuple and
stores it into the given buffer. stores it into the given buffer.
@return pointer to the origin of physical record */ @return pointer to the origin of physical record */
...@@ -727,10 +734,7 @@ UNIV_INTERN ...@@ -727,10 +734,7 @@ UNIV_INTERN
ulint ulint
rec_get_converted_size_comp_prefix( rec_get_converted_size_comp_prefix(
/*===============================*/ /*===============================*/
const dict_index_t* index, /*!< in: record descriptor; const dict_index_t* index, /*!< in: record descriptor */
dict_table_is_comp() is
assumed to hold, even if
it does not */
const dfield_t* fields, /*!< in: array of data fields */ const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */ ulint n_fields,/*!< in: number of data fields */
ulint* extra); /*!< out: extra size */ ulint* extra); /*!< out: extra size */
......
This diff is collapsed.
...@@ -298,6 +298,7 @@ row_merge_buf_add( ...@@ -298,6 +298,7 @@ row_merge_buf_add(
for (i = 0; i < n_fields; i++, field++, ifield++) { for (i = 0; i < n_fields; i++, field++, ifield++) {
const dict_col_t* col; const dict_col_t* col;
ulint col_no; ulint col_no;
ulint fixed_len;
const dfield_t* row_field; const dfield_t* row_field;
ulint len; ulint len;
...@@ -346,16 +347,27 @@ row_merge_buf_add( ...@@ -346,16 +347,27 @@ row_merge_buf_add(
ut_ad(len <= col->len || col->mtype == DATA_BLOB); ut_ad(len <= col->len || col->mtype == DATA_BLOB);
if (ifield->fixed_len) { fixed_len = ifield->fixed_len;
if (fixed_len && !dict_table_is_comp(index->table)
&& DATA_MBMINLEN(col->mbminmaxlen)
!= DATA_MBMAXLEN(col->mbminmaxlen)) {
/* CHAR in ROW_FORMAT=REDUNDANT is always
fixed-length, but in the temporary file it is
variable-length for variable-length character
sets. */
fixed_len = 0;
}
if (fixed_len) {
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
/* len should be between size calcualted base on /* len should be between size calcualted base on
mbmaxlen and mbminlen */ mbmaxlen and mbminlen */
ut_ad(len <= ifield->fixed_len); ut_ad(len <= fixed_len);
ut_ad(!mbmaxlen || len >= mbminlen ut_ad(!mbmaxlen || len >= mbminlen
* (ifield->fixed_len / mbmaxlen)); * (fixed_len / mbmaxlen));
ut_ad(!dfield_is_ext(field)); ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
...@@ -379,12 +391,11 @@ row_merge_buf_add( ...@@ -379,12 +391,11 @@ row_merge_buf_add(
ulint size; ulint size;
ulint extra; ulint extra;
size = rec_get_converted_size_comp(index, size = rec_get_converted_size_temp(
REC_STATUS_ORDINARY, index, entry, n_fields, &extra);
entry, n_fields, &extra);
ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size); ut_ad(data_size + extra_size == size);
ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra); ut_ad(extra_size == extra);
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
...@@ -588,14 +599,9 @@ row_merge_buf_write( ...@@ -588,14 +599,9 @@ row_merge_buf_write(
ulint extra_size; ulint extra_size;
const dfield_t* entry = buf->tuples[i]; const dfield_t* entry = buf->tuples[i];
size = rec_get_converted_size_comp(index, size = rec_get_converted_size_temp(
REC_STATUS_ORDINARY, index, entry, n_fields, &extra_size);
entry, n_fields,
&extra_size);
ut_ad(size >= extra_size); ut_ad(size >= extra_size);
ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES);
extra_size -= REC_N_NEW_EXTRA_BYTES;
size -= REC_N_NEW_EXTRA_BYTES;
/* Encode extra_size + 1 */ /* Encode extra_size + 1 */
if (extra_size + 1 < 0x80) { if (extra_size + 1 < 0x80) {
...@@ -608,9 +614,8 @@ row_merge_buf_write( ...@@ -608,9 +614,8 @@ row_merge_buf_write(
ut_ad(b + size < block[1]); ut_ad(b + size < block[1]);
rec_convert_dtuple_to_rec_comp(b + extra_size, 0, index, rec_convert_dtuple_to_temp(b + extra_size, index,
REC_STATUS_ORDINARY, entry, n_fields);
entry, n_fields);
b += size; b += size;
...@@ -872,7 +877,7 @@ err_exit: ...@@ -872,7 +877,7 @@ err_exit:
*mrec = *buf + extra_size; *mrec = *buf + extra_size;
rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets); rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets); data_size = rec_offs_data_size(offsets);
...@@ -891,7 +896,7 @@ err_exit: ...@@ -891,7 +896,7 @@ err_exit:
*mrec = b + extra_size; *mrec = b + extra_size;
rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets); rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets); data_size = rec_offs_data_size(offsets);
ut_ad(extra_size + data_size < sizeof *buf); ut_ad(extra_size + data_size < sizeof *buf);
......
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