mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge mysql-5.1 to mysql-5.5.
This commit is contained in:
@ -1,5 +0,0 @@
|
|||||||
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;
|
|
@ -1,13 +0,0 @@
|
|||||||
#
|
|
||||||
# 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;
|
|
@ -1,6 +1,6 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
} 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(
|
|||||||
#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(
|
|||||||
/*=====*/
|
/*=====*/
|
||||||
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(
|
|||||||
__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
|
|||||||
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 */
|
||||||
|
@ -167,7 +167,6 @@ rec_get_n_extern_new(
|
|||||||
{
|
{
|
||||||
const byte* nulls;
|
const byte* nulls;
|
||||||
const byte* lens;
|
const byte* lens;
|
||||||
dict_field_t* field;
|
|
||||||
ulint null_mask;
|
ulint null_mask;
|
||||||
ulint n_extern;
|
ulint n_extern;
|
||||||
ulint i;
|
ulint i;
|
||||||
@ -188,10 +187,13 @@ rec_get_n_extern_new(
|
|||||||
|
|
||||||
/* read the lengths of fields 0..n */
|
/* read the lengths of fields 0..n */
|
||||||
do {
|
do {
|
||||||
ulint len;
|
const dict_field_t* field
|
||||||
|
= dict_index_get_nth_field(index, i);
|
||||||
|
const dict_col_t* col
|
||||||
|
= dict_field_get_col(field);
|
||||||
|
ulint len;
|
||||||
|
|
||||||
field = dict_index_get_nth_field(index, i);
|
if (!(col->prtype & DATA_NOT_NULL)) {
|
||||||
if (!(dict_field_get_col(field)->prtype & DATA_NOT_NULL)) {
|
|
||||||
/* nullable field => read the null flag */
|
/* nullable field => read the null flag */
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
||||||
@ -209,8 +211,6 @@ rec_get_n_extern_new(
|
|||||||
|
|
||||||
if (UNIV_UNLIKELY(!field->fixed_len)) {
|
if (UNIV_UNLIKELY(!field->fixed_len)) {
|
||||||
/* Variable-length field: read the length */
|
/* Variable-length field: read the length */
|
||||||
const dict_col_t* col
|
|
||||||
= dict_field_get_col(field);
|
|
||||||
len = *lens--;
|
len = *lens--;
|
||||||
/* If the maximum length of the field is up
|
/* If the maximum length of the field is up
|
||||||
to 255 bytes, the actual length is always
|
to 255 bytes, the actual length is always
|
||||||
@ -239,16 +239,15 @@ rec_get_n_extern_new(
|
|||||||
Determine the offset to each field in a leaf-page record
|
Determine the offset to each field in a leaf-page record
|
||||||
in ROW_FORMAT=COMPACT. This is a special case of
|
in ROW_FORMAT=COMPACT. This is a special case of
|
||||||
rec_init_offsets() and rec_get_offsets_func(). */
|
rec_init_offsets() and rec_get_offsets_func(). */
|
||||||
UNIV_INTERN
|
UNIV_INLINE __attribute__((nonnull))
|
||||||
void
|
void
|
||||||
rec_init_offsets_comp_ordinary(
|
rec_init_offsets_comp_ordinary(
|
||||||
/*===========================*/
|
/*===========================*/
|
||||||
const rec_t* rec, /*!< in: physical record in
|
const rec_t* rec, /*!< in: physical record in
|
||||||
ROW_FORMAT=COMPACT */
|
ROW_FORMAT=COMPACT */
|
||||||
ulint extra, /*!< in: number of bytes to reserve
|
ibool temp, /*!< in: whether to use the
|
||||||
between the record header and
|
format for temporary files in
|
||||||
the data payload
|
index creation */
|
||||||
(usually REC_N_NEW_EXTRA_BYTES) */
|
|
||||||
const dict_index_t* index, /*!< in: record descriptor */
|
const dict_index_t* index, /*!< in: record descriptor */
|
||||||
ulint* offsets)/*!< in/out: array of offsets;
|
ulint* offsets)/*!< in/out: array of offsets;
|
||||||
in: n=rec_offs_n_fields(offsets) */
|
in: n=rec_offs_n_fields(offsets) */
|
||||||
@ -256,27 +255,38 @@ rec_init_offsets_comp_ordinary(
|
|||||||
ulint i = 0;
|
ulint i = 0;
|
||||||
ulint offs = 0;
|
ulint offs = 0;
|
||||||
ulint any_ext = 0;
|
ulint any_ext = 0;
|
||||||
const byte* nulls = rec - (extra + 1);
|
const byte* nulls = temp
|
||||||
|
? rec - 1
|
||||||
|
: rec - (1 + REC_N_NEW_EXTRA_BYTES);
|
||||||
const byte* lens = nulls
|
const byte* lens = nulls
|
||||||
- UT_BITS_IN_BYTES(index->n_nullable);
|
- UT_BITS_IN_BYTES(index->n_nullable);
|
||||||
dict_field_t* field;
|
|
||||||
ulint null_mask = 1;
|
ulint null_mask = 1;
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
/* We cannot invoke rec_offs_make_valid() here, because it can hold
|
/* We cannot invoke rec_offs_make_valid() here if temp=TRUE.
|
||||||
that extra != REC_N_NEW_EXTRA_BYTES. Similarly, rec_offs_validate()
|
Similarly, rec_offs_validate() will fail in that case, because
|
||||||
will fail in that case, because it invokes rec_get_status(). */
|
it invokes rec_get_status(). */
|
||||||
offsets[2] = (ulint) rec;
|
offsets[2] = (ulint) rec;
|
||||||
offsets[3] = (ulint) index;
|
offsets[3] = (ulint) index;
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
|
|
||||||
|
ut_ad(temp || dict_table_is_comp(index->table));
|
||||||
|
|
||||||
|
if (temp && dict_table_is_comp(index->table)) {
|
||||||
|
/* No need to do adjust fixed_len=0. We only need to
|
||||||
|
adjust it for ROW_FORMAT=REDUNDANT. */
|
||||||
|
temp = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* read the lengths of fields 0..n */
|
/* read the lengths of fields 0..n */
|
||||||
do {
|
do {
|
||||||
ulint len;
|
const dict_field_t* field
|
||||||
|
= dict_index_get_nth_field(index, i);
|
||||||
|
const dict_col_t* col
|
||||||
|
= dict_field_get_col(field);
|
||||||
|
ulint len;
|
||||||
|
|
||||||
field = dict_index_get_nth_field(index, i);
|
if (!(col->prtype & DATA_NOT_NULL)) {
|
||||||
if (!(dict_field_get_col(field)->prtype
|
|
||||||
& DATA_NOT_NULL)) {
|
|
||||||
/* nullable field => read the null flag */
|
/* nullable field => read the null flag */
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
if (UNIV_UNLIKELY(!(byte) null_mask)) {
|
||||||
@ -296,10 +306,9 @@ rec_init_offsets_comp_ordinary(
|
|||||||
null_mask <<= 1;
|
null_mask <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!field->fixed_len)) {
|
if (!field->fixed_len
|
||||||
|
|| (temp && !dict_col_get_fixed_size(col, temp))) {
|
||||||
/* Variable-length field: read the length */
|
/* Variable-length field: read the length */
|
||||||
const dict_col_t* col
|
|
||||||
= dict_field_get_col(field);
|
|
||||||
len = *lens--;
|
len = *lens--;
|
||||||
/* If the maximum length of the field is up
|
/* If the maximum length of the field is up
|
||||||
to 255 bytes, the actual length is always
|
to 255 bytes, the actual length is always
|
||||||
@ -393,9 +402,8 @@ rec_init_offsets(
|
|||||||
= dict_index_get_n_unique_in_tree(index);
|
= dict_index_get_n_unique_in_tree(index);
|
||||||
break;
|
break;
|
||||||
case REC_STATUS_ORDINARY:
|
case REC_STATUS_ORDINARY:
|
||||||
rec_init_offsets_comp_ordinary(rec,
|
rec_init_offsets_comp_ordinary(
|
||||||
REC_N_NEW_EXTRA_BYTES,
|
rec, FALSE, index, offsets);
|
||||||
index, offsets);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,17 +774,19 @@ rec_get_nth_field_offs_old(
|
|||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
|
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
|
||||||
@return total size */
|
@return total size */
|
||||||
UNIV_INTERN
|
UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
|
||||||
ulint
|
ulint
|
||||||
rec_get_converted_size_comp_prefix(
|
rec_get_converted_size_comp_prefix_low(
|
||||||
/*===============================*/
|
/*===================================*/
|
||||||
const dict_index_t* index, /*!< in: record descriptor;
|
const dict_index_t* index, /*!< in: record descriptor;
|
||||||
dict_table_is_comp() is
|
dict_table_is_comp() is
|
||||||
assumed to hold, even if
|
assumed to hold, even if
|
||||||
it does not */
|
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 */
|
||||||
|
ibool temp) /*!< in: whether this is a
|
||||||
|
temporary file record */
|
||||||
{
|
{
|
||||||
ulint extra_size;
|
ulint extra_size;
|
||||||
ulint data_size;
|
ulint data_size;
|
||||||
@ -785,15 +795,25 @@ rec_get_converted_size_comp_prefix(
|
|||||||
ut_ad(fields);
|
ut_ad(fields);
|
||||||
ut_ad(n_fields > 0);
|
ut_ad(n_fields > 0);
|
||||||
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
||||||
|
ut_ad(!temp || extra);
|
||||||
|
|
||||||
extra_size = REC_N_NEW_EXTRA_BYTES
|
extra_size = temp
|
||||||
|
? UT_BITS_IN_BYTES(index->n_nullable)
|
||||||
|
: REC_N_NEW_EXTRA_BYTES
|
||||||
+ UT_BITS_IN_BYTES(index->n_nullable);
|
+ UT_BITS_IN_BYTES(index->n_nullable);
|
||||||
data_size = 0;
|
data_size = 0;
|
||||||
|
|
||||||
|
if (temp && dict_table_is_comp(index->table)) {
|
||||||
|
/* No need to do adjust fixed_len=0. We only need to
|
||||||
|
adjust it for ROW_FORMAT=REDUNDANT. */
|
||||||
|
temp = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* read the lengths of fields 0..n */
|
/* read the lengths of fields 0..n */
|
||||||
for (i = 0; i < n_fields; i++) {
|
for (i = 0; i < n_fields; i++) {
|
||||||
const dict_field_t* field;
|
const dict_field_t* field;
|
||||||
ulint len;
|
ulint len;
|
||||||
|
ulint fixed_len;
|
||||||
const dict_col_t* col;
|
const dict_col_t* col;
|
||||||
|
|
||||||
field = dict_index_get_nth_field(index, i);
|
field = dict_index_get_nth_field(index, i);
|
||||||
@ -809,8 +829,14 @@ rec_get_converted_size_comp_prefix(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(len <= col->len || col->mtype == DATA_BLOB);
|
ut_ad(len <= col->len || col->mtype == DATA_BLOB
|
||||||
|
|| (col->len == 0 && col->mtype == DATA_VARCHAR));
|
||||||
|
|
||||||
|
fixed_len = field->fixed_len;
|
||||||
|
if (temp && fixed_len
|
||||||
|
&& !dict_col_get_fixed_size(col, temp)) {
|
||||||
|
fixed_len = 0;
|
||||||
|
}
|
||||||
/* If the maximum length of a variable-length field
|
/* If the maximum length of a variable-length field
|
||||||
is up to 255 bytes, the actual length is always stored
|
is up to 255 bytes, the actual length is always stored
|
||||||
in one byte. If the maximum length is more than 255
|
in one byte. If the maximum length is more than 255
|
||||||
@ -818,19 +844,19 @@ rec_get_converted_size_comp_prefix(
|
|||||||
0..127. The length will be encoded in two bytes when
|
0..127. The length will be encoded in two bytes when
|
||||||
it is 128 or more, or when the field is stored externally. */
|
it is 128 or more, or when the field is stored externally. */
|
||||||
|
|
||||||
if (field->fixed_len) {
|
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);
|
||||||
|
|
||||||
ut_ad(len <= field->fixed_len);
|
ut_ad(len <= fixed_len);
|
||||||
|
|
||||||
ut_ad(!mbmaxlen || len >= mbminlen
|
ut_ad(!mbmaxlen || len >= mbminlen
|
||||||
* (field->fixed_len / mbmaxlen));
|
* (fixed_len / mbmaxlen));
|
||||||
|
|
||||||
/* dict_index_add_col() should guarantee this */
|
/* dict_index_add_col() should guarantee this */
|
||||||
ut_ad(!field->prefix_len
|
ut_ad(!field->prefix_len
|
||||||
|| field->fixed_len == field->prefix_len);
|
|| fixed_len == field->prefix_len);
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
} else if (dfield_is_ext(&fields[i])) {
|
} else if (dfield_is_ext(&fields[i])) {
|
||||||
ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
|
ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
|
||||||
@ -848,13 +874,30 @@ rec_get_converted_size_comp_prefix(
|
|||||||
data_size += len;
|
data_size += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNIV_LIKELY_NULL(extra)) {
|
if (extra) {
|
||||||
*extra = extra_size;
|
*extra = extra_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(extra_size + data_size);
|
return(extra_size + data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************//**
|
||||||
|
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
|
||||||
|
@return total size */
|
||||||
|
UNIV_INTERN
|
||||||
|
ulint
|
||||||
|
rec_get_converted_size_comp_prefix(
|
||||||
|
/*===============================*/
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
ut_ad(dict_table_is_comp(index->table));
|
||||||
|
return(rec_get_converted_size_comp_prefix_low(
|
||||||
|
index, fields, n_fields, extra, FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************//**
|
/**********************************************************//**
|
||||||
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
|
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
|
||||||
@return total size */
|
@return total size */
|
||||||
@ -899,8 +942,8 @@ rec_get_converted_size_comp(
|
|||||||
return(ULINT_UNDEFINED);
|
return(ULINT_UNDEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(size + rec_get_converted_size_comp_prefix(index, fields,
|
return(size + rec_get_converted_size_comp_prefix_low(
|
||||||
n_fields, extra));
|
index, fields, n_fields, extra, FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************//**
|
/***********************************************************//**
|
||||||
@ -1077,19 +1120,18 @@ rec_convert_dtuple_to_rec_old(
|
|||||||
|
|
||||||
/*********************************************************//**
|
/*********************************************************//**
|
||||||
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
|
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
|
||||||
UNIV_INTERN
|
UNIV_INLINE __attribute__((nonnull))
|
||||||
void
|
void
|
||||||
rec_convert_dtuple_to_rec_comp(
|
rec_convert_dtuple_to_rec_comp(
|
||||||
/*===========================*/
|
/*===========================*/
|
||||||
rec_t* rec, /*!< in: origin of record */
|
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 */
|
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 */
|
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 status, /*!< in: status bits of the record */
|
||||||
|
ibool temp) /*!< in: whether to use the
|
||||||
|
format for temporary files in
|
||||||
|
index creation */
|
||||||
{
|
{
|
||||||
const dfield_t* field;
|
const dfield_t* field;
|
||||||
const dtype_t* type;
|
const dtype_t* type;
|
||||||
@ -1101,31 +1143,44 @@ rec_convert_dtuple_to_rec_comp(
|
|||||||
ulint n_node_ptr_field;
|
ulint n_node_ptr_field;
|
||||||
ulint fixed_len;
|
ulint fixed_len;
|
||||||
ulint null_mask = 1;
|
ulint null_mask = 1;
|
||||||
ut_ad(extra == 0 || dict_table_is_comp(index->table));
|
ut_ad(temp || dict_table_is_comp(index->table));
|
||||||
ut_ad(extra == 0 || extra == REC_N_NEW_EXTRA_BYTES);
|
|
||||||
ut_ad(n_fields > 0);
|
ut_ad(n_fields > 0);
|
||||||
|
|
||||||
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
|
if (temp) {
|
||||||
case REC_STATUS_ORDINARY:
|
ut_ad(status == REC_STATUS_ORDINARY);
|
||||||
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
||||||
n_node_ptr_field = ULINT_UNDEFINED;
|
n_node_ptr_field = ULINT_UNDEFINED;
|
||||||
break;
|
nulls = rec - 1;
|
||||||
case REC_STATUS_NODE_PTR:
|
if (dict_table_is_comp(index->table)) {
|
||||||
ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
|
/* No need to do adjust fixed_len=0. We only
|
||||||
n_node_ptr_field = n_fields - 1;
|
need to adjust it for ROW_FORMAT=REDUNDANT. */
|
||||||
break;
|
temp = FALSE;
|
||||||
case REC_STATUS_INFIMUM:
|
}
|
||||||
case REC_STATUS_SUPREMUM:
|
} else {
|
||||||
ut_ad(n_fields == 1);
|
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
|
||||||
n_node_ptr_field = ULINT_UNDEFINED;
|
|
||||||
break;
|
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
|
||||||
default:
|
case REC_STATUS_ORDINARY:
|
||||||
ut_error;
|
ut_ad(n_fields <= dict_index_get_n_fields(index));
|
||||||
return;
|
n_node_ptr_field = ULINT_UNDEFINED;
|
||||||
|
break;
|
||||||
|
case REC_STATUS_NODE_PTR:
|
||||||
|
ut_ad(n_fields
|
||||||
|
== dict_index_get_n_unique_in_tree(index) + 1);
|
||||||
|
n_node_ptr_field = n_fields - 1;
|
||||||
|
break;
|
||||||
|
case REC_STATUS_INFIMUM:
|
||||||
|
case REC_STATUS_SUPREMUM:
|
||||||
|
ut_ad(n_fields == 1);
|
||||||
|
n_node_ptr_field = ULINT_UNDEFINED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ut_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end = rec;
|
end = rec;
|
||||||
nulls = rec - (extra + 1);
|
|
||||||
lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
|
lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
|
||||||
/* clear the SQL-null flags */
|
/* clear the SQL-null flags */
|
||||||
memset(lens + 1, 0, nulls - lens);
|
memset(lens + 1, 0, nulls - lens);
|
||||||
@ -1171,6 +1226,10 @@ rec_convert_dtuple_to_rec_comp(
|
|||||||
|
|
||||||
ifield = dict_index_get_nth_field(index, i);
|
ifield = dict_index_get_nth_field(index, i);
|
||||||
fixed_len = ifield->fixed_len;
|
fixed_len = ifield->fixed_len;
|
||||||
|
if (temp && fixed_len
|
||||||
|
&& !dict_col_get_fixed_size(ifield->col, temp)) {
|
||||||
|
fixed_len = 0;
|
||||||
|
}
|
||||||
/* If the maximum length of a variable-length field
|
/* If the maximum length of a variable-length field
|
||||||
is up to 255 bytes, the actual length is always stored
|
is up to 255 bytes, the actual length is always stored
|
||||||
in one byte. If the maximum length is more than 255
|
in one byte. If the maximum length is more than 255
|
||||||
@ -1240,8 +1299,7 @@ rec_convert_dtuple_to_rec_new(
|
|||||||
rec = buf + extra_size;
|
rec = buf + extra_size;
|
||||||
|
|
||||||
rec_convert_dtuple_to_rec_comp(
|
rec_convert_dtuple_to_rec_comp(
|
||||||
rec, REC_N_NEW_EXTRA_BYTES, index, status,
|
rec, index, dtuple->fields, dtuple->n_fields, status, FALSE);
|
||||||
dtuple->fields, dtuple->n_fields);
|
|
||||||
|
|
||||||
/* Set the info bits of the record */
|
/* Set the info bits of the record */
|
||||||
rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
|
rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
|
||||||
@ -1303,6 +1361,54 @@ rec_convert_dtuple_to_rec(
|
|||||||
return(rec);
|
return(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNIV_HOTBACKUP
|
||||||
|
/**********************************************************//**
|
||||||
|
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
|
||||||
|
@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 */
|
||||||
|
{
|
||||||
|
return(rec_get_converted_size_comp_prefix_low(
|
||||||
|
index, fields, n_fields, extra, TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************//**
|
||||||
|
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) */
|
||||||
|
{
|
||||||
|
rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************//**
|
||||||
|
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 */
|
||||||
|
{
|
||||||
|
rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields,
|
||||||
|
REC_STATUS_ORDINARY, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************//**
|
/**************************************************************//**
|
||||||
Copies the first n fields of a physical record to a data tuple. The fields
|
Copies the first n fields of a physical record to a data tuple. The fields
|
||||||
are copied to the memory heap. */
|
are copied to the memory heap. */
|
||||||
@ -1513,6 +1619,7 @@ rec_copy_prefix_to_buf(
|
|||||||
|
|
||||||
return(*buf + (rec - (lens + 1)));
|
return(*buf + (rec - (lens + 1)));
|
||||||
}
|
}
|
||||||
|
#endif /* UNIV_HOTBACKUP */
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
Validates the consistency of an old-style physical record.
|
Validates the consistency of an old-style physical record.
|
||||||
|
@ -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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
*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:
|
|||||||
|
|
||||||
*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);
|
||||||
|
Reference in New Issue
Block a user