Skip to content

Commit 2a78107

Browse files
committed
MDEV-22775: Merge 10.4 into 10.5
2 parents 7b48da4 + 58780b5 commit 2a78107

File tree

15 files changed

+340
-123
lines changed

15 files changed

+340
-123
lines changed

mysql-test/suite/innodb/r/instant_alter_charset.result

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,3 +2032,14 @@ ALTER TABLE t1 MODIFY a VARCHAR(2)
20322032
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
20332033
INSERT INTO t1 VALUES ('a');
20342034
DROP TABLE t1;
2035+
#
2036+
# MDEV-22775 [HY000][1553] Changing name of primary key column with foreign key constraint fails.
2037+
#
2038+
create table t1 (id int primary key) engine=innodb default charset=utf8;
2039+
create table t2 (input_id int primary key, id int not null,
2040+
key a (id),
2041+
constraint a foreign key (id) references t1 (id)
2042+
)engine=innodb default charset=utf8;
2043+
alter table t1 change id id2 int;
2044+
drop table t2;
2045+
drop table t1;

mysql-test/suite/innodb/t/instant_alter_charset.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,3 +843,17 @@ ALTER TABLE t1 MODIFY a VARCHAR(2)
843843
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
844844
INSERT INTO t1 VALUES ('a');
845845
DROP TABLE t1;
846+
847+
848+
--echo #
849+
--echo # MDEV-22775 [HY000][1553] Changing name of primary key column with foreign key constraint fails.
850+
--echo #
851+
852+
create table t1 (id int primary key) engine=innodb default charset=utf8;
853+
create table t2 (input_id int primary key, id int not null,
854+
key a (id),
855+
constraint a foreign key (id) references t1 (id)
856+
)engine=innodb default charset=utf8;
857+
alter table t1 change id id2 int;
858+
drop table t2;
859+
drop table t1;

plugin/type_inet/sql_type_inet.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,19 +458,21 @@ class Type_handler_inet6: public Type_handler
458458
MEM_ROOT *mem_root,
459459
Column_definition *def,
460460
handler *file,
461-
ulonglong table_flags) const override
461+
ulonglong table_flags,
462+
const Column_derived_attributes
463+
*derived_attr)
464+
const override
462465
{
463-
def->create_length_to_internal_length_simple();
466+
def->prepare_stage1_simple(&my_charset_numeric);
464467
return false;
465468
}
466469

467470
bool Column_definition_redefine_stage1(Column_definition *def,
468471
const Column_definition *dup,
469-
const handler *file,
470-
const Schema_specification_st *schema)
472+
const handler *file)
471473
const override
472474
{
473-
def->redefine_stage1_common(dup, file, schema);
475+
def->redefine_stage1_common(dup, file);
474476
def->set_compression_method(dup->compression_method());
475477
def->create_length_to_internal_length_string();
476478
return false;

sql/field.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10828,16 +10828,26 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
1082810828
CREATE TABLE t1 (a INT) AS SELECT a FROM t2;
1082910829
See Type_handler::Column_definition_redefine_stage1()
1083010830
for data type specific code.
10831+
10832+
@param this - The field definition corresponding to the expression
10833+
in the "AS SELECT.." part.
10834+
10835+
@param dup_field - The field definition from the "CREATE TABLE (...)" part.
10836+
It has already underwent prepare_stage1(), so
10837+
must be fully initialized:
10838+
-- dup_field->charset is set and BINARY
10839+
sorting style is applied, see find_bin_collation().
10840+
10841+
@param file - The table handler
1083110842
*/
1083210843
void
1083310844
Column_definition::redefine_stage1_common(const Column_definition *dup_field,
10834-
const handler *file,
10835-
const Schema_specification_st *schema)
10845+
const handler *file)
1083610846
{
1083710847
set_handler(dup_field->type_handler());
1083810848
default_value= dup_field->default_value;
10839-
charset= dup_field->charset ? dup_field->charset :
10840-
schema->default_table_charset;
10849+
DBUG_ASSERT(dup_field->charset); // Set by prepare_stage1()
10850+
charset= dup_field->charset;
1084110851
length= dup_field->char_length;
1084210852
pack_length= dup_field->pack_length;
1084310853
decimals= dup_field->decimals;

sql/field.h

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5131,6 +5131,11 @@ class Column_definition_attributes
51315131
bool frm_unpack_temporal_with_dec(TABLE_SHARE *share, uint intlen,
51325132
const uchar *buff);
51335133
void set_length_and_dec(const Lex_length_and_dec_st &attr);
5134+
CHARSET_INFO *explicit_or_derived_charset(const Column_derived_attributes
5135+
*derived_attr) const
5136+
{
5137+
return charset ? charset : derived_attr->charset();
5138+
}
51345139
};
51355140

51365141

@@ -5266,6 +5271,15 @@ class Column_definition: public Sql_alloc,
52665271
void create_length_to_internal_length_bit();
52675272
void create_length_to_internal_length_newdecimal();
52685273

5274+
/*
5275+
Prepare the "charset" member for string data types,
5276+
such as CHAR, VARCHAR, TEXT, ENUM, SET:
5277+
- derive the charset if not specified explicitly
5278+
- find a _bin collation if the BINARY comparison style was specified, e.g.:
5279+
CREATE TABLE t1 (a VARCHAR(10) BINARY) CHARSET utf8;
5280+
*/
5281+
bool prepare_charset_for_string(const Column_derived_attributes *dattr);
5282+
52695283
/**
52705284
Prepare a SET/ENUM field.
52715285
Create "interval" from "interval_list" if needed, and adjust "length".
@@ -5301,23 +5315,33 @@ class Column_definition: public Sql_alloc,
53015315
bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root);
53025316

53035317
bool prepare_stage1(THD *thd, MEM_ROOT *mem_root,
5304-
handler *file, ulonglong table_flags);
5318+
handler *file, ulonglong table_flags,
5319+
const Column_derived_attributes *derived_attr);
5320+
void prepare_stage1_simple(CHARSET_INFO *cs)
5321+
{
5322+
charset= cs;
5323+
create_length_to_internal_length_simple();
5324+
}
53055325
bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root,
53065326
handler *file, ulonglong table_flags);
53075327
bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root,
53085328
handler *file, ulonglong table_flags);
53095329
bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
53105330
handler *file, ulonglong table_flags);
53115331

5332+
bool bulk_alter(const Column_derived_attributes *derived_attr,
5333+
const Column_bulk_alter_attributes *bulk_attr)
5334+
{
5335+
return type_handler()->Column_definition_bulk_alter(this,
5336+
derived_attr,
5337+
bulk_attr);
5338+
}
53125339
void redefine_stage1_common(const Column_definition *dup_field,
5313-
const handler *file,
5314-
const Schema_specification_st *schema);
5315-
bool redefine_stage1(const Column_definition *dup_field, const handler *file,
5316-
const Schema_specification_st *schema)
5340+
const handler *file);
5341+
bool redefine_stage1(const Column_definition *dup_field, const handler *file)
53175342
{
53185343
const Type_handler *handler= dup_field->type_handler();
5319-
return handler->Column_definition_redefine_stage1(this, dup_field,
5320-
file, schema);
5344+
return handler->Column_definition_redefine_stage1(this, dup_field, file);
53215345
}
53225346
bool prepare_stage2(handler *handler, ulonglong table_flags);
53235347
bool prepare_stage2_blob(handler *handler,

sql/handler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,7 +2167,7 @@ struct Vers_parse_info: public Table_period_info
21672167

21682168
struct Table_scope_and_contents_source_pod_st // For trivial members
21692169
{
2170-
CHARSET_INFO *table_charset;
2170+
CHARSET_INFO *alter_table_convert_to_charset;
21712171
LEX_CUSTRING tabledef_version;
21722172
LEX_CSTRING connect_string;
21732173
LEX_CSTRING comment;
@@ -2316,7 +2316,7 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
23162316
DBUG_ASSERT(cs);
23172317
if (check_conflicting_charset_declarations(cs))
23182318
return true;
2319-
table_charset= default_table_charset= cs;
2319+
alter_table_convert_to_charset= default_table_charset= cs;
23202320
used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
23212321
return false;
23222322
}

sql/sql_partition.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2313,6 +2313,8 @@ static int add_column_list_values(String *str, partition_info *part_info,
23132313
*/
23142314
if (create_info)
23152315
{
2316+
const Column_derived_attributes
2317+
derived_attr(create_info->default_table_charset);
23162318
Create_field *sql_field;
23172319

23182320
if (!(sql_field= get_sql_field(field_name,
@@ -2324,7 +2326,7 @@ static int add_column_list_values(String *str, partition_info *part_info,
23242326
th= sql_field->type_handler();
23252327
if (th->partition_field_check(sql_field->field_name, item_expr))
23262328
return 1;
2327-
field_cs= get_sql_field_charset(sql_field, create_info);
2329+
field_cs= sql_field->explicit_or_derived_charset(&derived_attr);
23282330
}
23292331
else
23302332
{

sql/sql_table.cc

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,6 +3043,15 @@ bool check_duplicates_in_interval(const char *set_or_name,
30433043
}
30443044

30453045

3046+
bool Column_definition::
3047+
prepare_charset_for_string(const Column_derived_attributes *dattr)
3048+
{
3049+
if (!charset)
3050+
charset= dattr->charset();
3051+
return (flags & BINCMP_FLAG) && !(charset= find_bin_collation(charset));
3052+
}
3053+
3054+
30463055
bool Column_definition::prepare_stage2_blob(handler *file,
30473056
ulonglong table_flags,
30483057
uint field_flags)
@@ -3123,38 +3132,6 @@ bool Column_definition::prepare_stage2(handler *file,
31233132
}
31243133

31253134

3126-
/*
3127-
Get character set from field object generated by parser using
3128-
default values when not set.
3129-
3130-
SYNOPSIS
3131-
get_sql_field_charset()
3132-
sql_field The sql_field object
3133-
create_info Info generated by parser
3134-
3135-
RETURN VALUES
3136-
cs Character set
3137-
*/
3138-
3139-
CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
3140-
HA_CREATE_INFO *create_info)
3141-
{
3142-
CHARSET_INFO *cs= sql_field->charset;
3143-
3144-
if (!cs)
3145-
cs= create_info->default_table_charset;
3146-
/*
3147-
table_charset is set only in ALTER TABLE t1 CONVERT TO CHARACTER SET csname
3148-
if we want change character set for all varchar/char columns.
3149-
But the table charset must not affect the BLOB fields, so don't
3150-
allow to change my_charset_bin to somethig else.
3151-
*/
3152-
if (create_info->table_charset && cs != &my_charset_bin)
3153-
cs= create_info->table_charset;
3154-
return cs;
3155-
}
3156-
3157-
31583135
/**
31593136
Modifies the first column definition whose SQL type is TIMESTAMP
31603137
by adding the features DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
@@ -3327,11 +3304,14 @@ bool Column_definition::prepare_stage1_bit(THD *thd,
33273304
bool Column_definition::prepare_stage1(THD *thd,
33283305
MEM_ROOT *mem_root,
33293306
handler *file,
3330-
ulonglong table_flags)
3307+
ulonglong table_flags,
3308+
const Column_derived_attributes
3309+
*derived_attr)
33313310
{
33323311
return type_handler()->Column_definition_prepare_stage1(thd, mem_root,
33333312
this, file,
3334-
table_flags);
3313+
table_flags,
3314+
derived_attr);
33353315
}
33363316

33373317

@@ -3598,6 +3578,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
35983578
int select_field_count= C_CREATE_SELECT(create_table_mode);
35993579
bool tmp_table= create_table_mode == C_ALTER_TABLE;
36003580
bool is_hash_field_needed= false;
3581+
const Column_derived_attributes dattr(create_info->default_table_charset);
3582+
const Column_bulk_alter_attributes
3583+
battr(create_info->alter_table_convert_to_charset);
36013584
DBUG_ENTER("mysql_prepare_create_table");
36023585

36033586
DBUG_EXECUTE_IF("test_pseudo_invisible",{
@@ -3653,26 +3636,27 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
36533636

36543637
for (field_no=0; (sql_field=it++) ; field_no++)
36553638
{
3639+
/* Virtual fields are always NULL */
3640+
if (sql_field->vcol_info)
3641+
sql_field->flags&= ~NOT_NULL_FLAG;
3642+
36563643
/*
36573644
Initialize length from its original value (number of characters),
36583645
which was set in the parser. This is necessary if we're
36593646
executing a prepared statement for the second time.
36603647
*/
36613648
sql_field->length= sql_field->char_length;
3662-
/* Set field charset. */
3663-
sql_field->charset= get_sql_field_charset(sql_field, create_info);
3664-
if ((sql_field->flags & BINCMP_FLAG) &&
3665-
!(sql_field->charset= find_bin_collation(sql_field->charset)))
3666-
DBUG_RETURN(true);
36673649

3668-
/* Virtual fields are always NULL */
3669-
if (sql_field->vcol_info)
3670-
sql_field->flags&= ~NOT_NULL_FLAG;
3650+
if (sql_field->bulk_alter(&dattr, &battr))
3651+
DBUG_RETURN(true);
36713652

36723653
if (sql_field->prepare_stage1(thd, thd->mem_root,
3673-
file, file->ha_table_flags()))
3654+
file, file->ha_table_flags(),
3655+
&dattr))
36743656
DBUG_RETURN(true);
36753657

3658+
DBUG_ASSERT(sql_field->charset);
3659+
36763660
if (sql_field->real_field_type() == MYSQL_TYPE_BIT &&
36773661
file->ha_table_flags() & HA_CAN_BIT_FIELD)
36783662
total_uneven_bit_length+= sql_field->length & 7;
@@ -3723,7 +3707,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
37233707
if (!(sql_field->flags & NOT_NULL_FLAG))
37243708
null_fields--;
37253709

3726-
if (sql_field->redefine_stage1(dup_field, file, create_info))
3710+
if (sql_field->redefine_stage1(dup_field, file))
37273711
DBUG_RETURN(true);
37283712

37293713
it2.remove(); // Remove first (create) definition
@@ -4764,7 +4748,9 @@ bool Column_definition::prepare_blob_field(THD *thd)
47644748

47654749
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
47664750
{
4767-
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY) ||
4751+
DBUG_ASSERT(charset);
4752+
const Column_derived_attributes dattr(&my_charset_bin);
4753+
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY, &dattr) ||
47684754
prepare_stage2(NULL, HA_CAN_GEOMETRY);
47694755
}
47704756

@@ -11946,8 +11932,8 @@ bool Sql_cmd_create_table_like::execute(THD *thd)
1194611932
{
1194711933
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
1194811934
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
11949-
create_info.default_table_charset= create_info.table_charset;
11950-
create_info.table_charset= 0;
11935+
create_info.default_table_charset= create_info.alter_table_convert_to_charset;
11936+
create_info.alter_table_convert_to_charset= 0;
1195111937
}
1195211938

1195311939
/*

sql/sql_table.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,6 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
258258
const char *table_path=0);
259259
void close_cached_table(THD *thd, TABLE *table);
260260
void sp_prepare_create_field(THD *thd, Column_definition *sql_field);
261-
CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
262-
HA_CREATE_INFO *create_info);
263261
bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags);
264262
int write_bin_log(THD *thd, bool clear_error,
265263
char const *query, ulong query_length,

0 commit comments

Comments
 (0)