Commit 0a7faed7 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-22771 Instant extension of CHAR column is wrongly allowed

commit 854c219a (MDEV-17301)
broke a constraint: Fixed-length columns cannot be extended in InnoDB
without rebuilding the table.

ha_innobase::can_convert_string(): Correct the condition. We must
not allow any instantaneous change to the length of CHAR columns
measured in characters. For any format other than ROW_FORMAT=REDUNDANT,
we can allow the length in bytes to be extended if mbminlen<mbmaxlen held
before the change of the character set.
parent 956f21c3
--- instant_alter_convert.result
+++ instant_alter_convert,utf8.result
@@ -37,7 +37,7 @@
test.t check status OK
@@ -38,7 +38,7 @@
best.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 200
+a 13 2100FE 600
# CHAR enlargement
alter table t modify a char(220), algorithm=instant;
select count(a) from t where a = @bigval;
@@ -51,7 +51,7 @@
test.t check status OK
alter table t modify a char(220);
affected rows: 2
@@ -54,7 +54,7 @@
best.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 220
+a 13 2100FE 660
ALTER TABLE t CHANGE COLUMN a a CHAR(230) BINARY;
affected rows: 2
info: Records: 2 Duplicates: 0 Warnings: 0
@@ -69,7 +69,7 @@
best.t check status OK
call check_table('t');
name mtype prtype len
-a 13 2F00FE 230
+a 13 5300FE 690
# Convert from VARCHAR to a bigger CHAR
alter table t modify a varchar(200), algorithm=instant;
ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type. Try ALGORITHM=COPY
@@ -72,7 +72,7 @@
test.t check status OK
alter table t modify a varchar(200);
affected rows: 2
@@ -92,7 +92,7 @@
best.t check status OK
call check_table('t');
name mtype prtype len
-a 2 800FE 255
+a 13 2100FE 765
# BINARY/VARBINARY test
create or replace table t (a varbinary(300));
alter table t modify a binary(255), algorithm=instant;
insert into t values(NULL);
......@@ -64,6 +64,15 @@ select a, length(a) from t where a = 'z';
check table t extended;
call check_table('t');
--enable_info
ALTER TABLE t CHANGE COLUMN a a CHAR(230) BINARY;
ALTER TABLE t ADD COLUMN b INT FIRST;
ALTER TABLE t DROP b;
--disable_info
check table t extended;
call check_table('t');
--echo # Convert from VARCHAR to a bigger CHAR
--enable_info
alter table t modify a varchar(200);
......
......@@ -20986,43 +20986,35 @@ is_part_of_a_primary_key(const Field* field)
&& field->part_of_key.is_set(s->primary_key);
}
bool
ha_innobase::can_convert_string(const Field_string* field,
const Column_definition& new_type) const
bool ha_innobase::can_convert_string(const Field_string *field,
const Column_definition &new_type) const
{
DBUG_ASSERT(!field->compression_method());
if (new_type.type_handler() != field->type_handler()) {
return false;
}
DBUG_ASSERT(!field->compression_method());
if (new_type.type_handler() != field->type_handler())
return false;
if (new_type.char_length < field->char_length()) {
return false;
}
if (new_type.char_length != field->char_length())
return false;
if (new_type.charset != field->charset()) {
if (new_type.length != field->max_display_length()
&& !m_prebuilt->table->not_redundant()) {
return IS_EQUAL_NO;
}
const Charset field_cs(field->charset());
Charset field_cs(field->charset());
if (!field_cs.encoding_allows_reinterpret_as(
new_type.charset)) {
return false;
}
if (new_type.length != field->max_display_length() &&
(!m_prebuilt->table->not_redundant() ||
field_cs.mbminlen() == field_cs.mbmaxlen()))
return false;
if (!field_cs.eq_collation_specific_names(new_type.charset)) {
return !is_part_of_a_primary_key(field);
}
if (new_type.charset != field->charset())
{
if (!field_cs.encoding_allows_reinterpret_as(new_type.charset))
return false;
return true;
}
if (!field_cs.eq_collation_specific_names(new_type.charset))
return !is_part_of_a_primary_key(field);
if (new_type.length != field->max_display_length()) {
return false;
}
return true;
}
return true;
return true;
}
static bool
......
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