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
the terms of the GNU General Public License as published by the Free Software
......@@ -459,36 +459,18 @@ dtype_get_fixed_size_low(
} else if (!comp) {
return(len);
} else {
/* We play it safe here and ask MySQL for
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. */
#ifdef UNIV_DEBUG
ulint i_mbminlen, i_mbmaxlen;
innobase_get_cset_width(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
if (UNIV_UNLIKELY
(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
!= mbminmaxlen)) {
ut_print_timestamp(stderr);
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) {
ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
== mbminmaxlen);
#endif /* UNIV_DEBUG */
if (DATA_MBMINLEN(mbminmaxlen)
== DATA_MBMAXLEN(mbminmaxlen)) {
return(len);
}
}
......
......@@ -361,24 +361,6 @@ rec_get_offsets_func(
#define rec_get_offsets(rec,index,offsets,n,heap) \
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
in the record. It can reuse a previously allocated array. */
......@@ -644,8 +626,48 @@ rec_copy(
/*=====*/
void* buf, /*!< in: buffer */
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
/**********************************************************//**
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
a buffer.
......@@ -680,21 +702,6 @@ rec_fold(
__attribute__((pure));
#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
stores it into the given buffer.
@return pointer to the origin of physical record */
......@@ -727,10 +734,7 @@ UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
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 */
......
This diff is collapsed.
......@@ -298,6 +298,7 @@ row_merge_buf_add(
for (i = 0; i < n_fields; i++, field++, ifield++) {
const dict_col_t* col;
ulint col_no;
ulint fixed_len;
const dfield_t* row_field;
ulint len;
......@@ -346,16 +347,27 @@ row_merge_buf_add(
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
ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
/* len should be between size calcualted base on
mbmaxlen and mbminlen */
ut_ad(len <= ifield->fixed_len);
ut_ad(len <= fixed_len);
ut_ad(!mbmaxlen || len >= mbminlen
* (ifield->fixed_len / mbmaxlen));
* (fixed_len / mbmaxlen));
ut_ad(!dfield_is_ext(field));
#endif /* UNIV_DEBUG */
......@@ -379,12 +391,11 @@ row_merge_buf_add(
ulint size;
ulint extra;
size = rec_get_converted_size_comp(index,
REC_STATUS_ORDINARY,
entry, n_fields, &extra);
size = rec_get_converted_size_temp(
index, entry, n_fields, &extra);
ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size);
ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra);
ut_ad(data_size + extra_size == size);
ut_ad(extra_size == extra);
}
#endif /* UNIV_DEBUG */
......@@ -588,14 +599,9 @@ row_merge_buf_write(
ulint extra_size;
const dfield_t* entry = buf->tuples[i];
size = rec_get_converted_size_comp(index,
REC_STATUS_ORDINARY,
entry, n_fields,
&extra_size);
size = rec_get_converted_size_temp(
index, entry, n_fields, &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 */
if (extra_size + 1 < 0x80) {
......@@ -608,9 +614,8 @@ row_merge_buf_write(
ut_ad(b + size < block[1]);
rec_convert_dtuple_to_rec_comp(b + extra_size, 0, index,
REC_STATUS_ORDINARY,
entry, n_fields);
rec_convert_dtuple_to_temp(b + extra_size, index,
entry, n_fields);
b += size;
......@@ -872,7 +877,7 @@ err_exit:
*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);
......@@ -891,7 +896,7 @@ err_exit:
*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);
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