mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-22771 Instant extension of CHAR column is wrongly allowed
commit 854c219a7f
(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.
This commit is contained in:
parent
956f21c3b0
commit
0a7faed75a
4 changed files with 50 additions and 40 deletions
|
@ -1,29 +1,38 @@
|
|||
--- 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);
|
||||
|
|
Binary file not shown.
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue