Commit a12d0d5a authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18609 Assertion !is_string || (*af)->charset() == cf->charset failed

The Create_field::charset can contain garbage for columns
that the SQL layer does not consider as being string columns.
InnoDB considers BIT a string column for historical reasons
(and backward compatibility with old persistent InnoDB metadata),
and therefore it checked the charset.

The Field::charset() consistently is my_charset_bin for BIT,
so we can trust that one.
parent 869ce67f
......@@ -779,10 +779,22 @@ DELETE FROM t1 LIMIT 3;
ALTER TABLE t1 MODIFY f BIT(15);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
ALTER TABLE t1 MODIFY f BIT(8);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
SELECT HEX(f) FROM t1;
HEX(f)
80
DROP TABLE t1;
CREATE TABLE t1 (b BIT NOT NULL) ENGINE=InnoDB ROW_FORMAT=REDUNDANT DEFAULT CHARSET utf16;
INSERT INTO t1 SET b=b'1';
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT HEX(c) FROM t1;
HEX(c)
1
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1508,10 +1520,22 @@ DELETE FROM t1 LIMIT 3;
ALTER TABLE t1 MODIFY f BIT(15);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
ALTER TABLE t1 MODIFY f BIT(8);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
SELECT HEX(f) FROM t1;
HEX(f)
80
DROP TABLE t1;
CREATE TABLE t1 (b BIT NOT NULL) ENGINE=InnoDB ROW_FORMAT=COMPACT DEFAULT CHARSET utf16;
INSERT INTO t1 SET b=b'1';
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT HEX(c) FROM t1;
HEX(c)
1
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -2237,10 +2261,22 @@ DELETE FROM t1 LIMIT 3;
ALTER TABLE t1 MODIFY f BIT(15);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
ALTER TABLE t1 MODIFY f BIT(8);
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
SELECT HEX(f) FROM t1;
HEX(f)
80
DROP TABLE t1;
CREATE TABLE t1 (b BIT NOT NULL) ENGINE=InnoDB ROW_FORMAT=DYNAMIC DEFAULT CHARSET utf16;
INSERT INTO t1 SET b=b'1';
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
SELECT HEX(c) FROM t1;
HEX(c)
1
DROP TABLE t1;
disconnect analyze;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
......
......@@ -668,10 +668,19 @@ ALTER TABLE t1 MODIFY f BIT(15);
DELETE FROM t1 LIMIT 3;
--enable_info
ALTER TABLE t1 MODIFY f BIT(15);
ALTER TABLE t1 MODIFY f BIT(8);
--disable_info
SELECT HEX(f) FROM t1;
DROP TABLE t1;
eval CREATE TABLE t1 (b BIT NOT NULL) $engine DEFAULT CHARSET utf16;
INSERT INTO t1 SET b=b'1';
--enable_info
ALTER TABLE t1 CHANGE b c BIT NOT NULL;
--disable_info
SELECT HEX(c) FROM t1;
DROP TABLE t1;
dec $format;
}
disconnect analyze;
......
......@@ -9016,7 +9016,6 @@ static void get_type(const Field& f, ulint& prtype, ulint& mtype, ulint& len)
@param table_name Table name in MySQL
@param pos 0-based index to user_table->cols[] or user_table->v_cols[]
@param f new column
@param cf column modification
@param is_v if it's a virtual column
@retval true Failure
@retval false Success */
......@@ -9028,7 +9027,6 @@ innobase_rename_or_enlarge_column_try(
const char* table_name,
ulint pos,
const Field& f,
const Create_field& cf,
bool is_v)
{
dict_col_t* col;
......@@ -9052,7 +9050,7 @@ innobase_rename_or_enlarge_column_try(
ulint prtype, mtype, len;
get_type(f, prtype, mtype, len);
DBUG_ASSERT(!dtype_is_string_type(col->mtype)
|| col->mbminlen == cf.charset->mbminlen);
|| col->mbminlen == f.charset()->mbminlen);
DBUG_ASSERT(col->len <= len);
#ifdef UNIV_DEBUG
......@@ -9152,7 +9150,7 @@ innobase_rename_or_enlarge_columns_try(
if (cf->field == *fp) {
if (innobase_rename_or_enlarge_column_try(
ctx->old_table, trx, table_name,
idx, **af, *cf, is_v)) {
idx, **af, is_v)) {
DBUG_RETURN(true);
}
break;
......@@ -9208,8 +9206,6 @@ innobase_rename_or_enlarge_columns_cache(
->m_col
: dict_table_get_nth_col(user_table, col_n);
const bool is_string= dtype_is_string_type(col->mtype);
DBUG_ASSERT(!is_string
|| (*af)->charset() == cf->charset);
DBUG_ASSERT(col->mbminlen
== (is_string
? (*af)->charset()->mbminlen : 0));
......@@ -9227,7 +9223,7 @@ innobase_rename_or_enlarge_columns_cache(
dict_mem_table_col_rename(
user_table, col_n,
cf->field->field_name.str,
cf->field_name.str, is_virtual);
(*af)->field_name.str, is_virtual);
}
break;
......
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