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