mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error
partially revert 76063c2a13
. Item::clone() is not an all-purpose
Item copying machine, it was specifically created for pushdown
of predicates into derived tables and views and it does not
copy everything. In particular, it does not copy Item_func_regex.
Fix the bug differently by preserving the old constraint name.
But keep setting automatic_name=true to have it regenerated
for cases like ALTER TABLE ... ADD CONSTRAINT.
This commit is contained in:
@ -235,3 +235,15 @@ a b
|
|||||||
insert t1 (b) values (1);
|
insert t1 (b) values (1);
|
||||||
ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
|
ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error
|
||||||
|
#
|
||||||
|
create table t1 (id varchar(2), constraint id check (id regexp '[a-z]'));
|
||||||
|
alter table t1 force;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`id` varchar(2) DEFAULT NULL,
|
||||||
|
CONSTRAINT `id` CHECK (`id` regexp '[a-z]')
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
@ -176,3 +176,11 @@ select * from t1 where a is null;
|
|||||||
--error ER_CONSTRAINT_FAILED
|
--error ER_CONSTRAINT_FAILED
|
||||||
insert t1 (b) values (1);
|
insert t1 (b) values (1);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error
|
||||||
|
--echo #
|
||||||
|
create table t1 (id varchar(2), constraint id check (id regexp '[a-z]'));
|
||||||
|
alter table t1 force;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
@ -76,9 +76,8 @@ static int copy_data_between_tables(THD *, TABLE *,TABLE *,
|
|||||||
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
|
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
|
||||||
uint *, handler *, KEY **, uint *, int);
|
uint *, handler *, KEY **, uint *, int);
|
||||||
static uint blob_length_by_type(enum_field_types type);
|
static uint blob_length_by_type(enum_field_types type);
|
||||||
static bool fix_constraints_names(THD *thd, List<Virtual_column_info>
|
static bool fix_constraints_names(THD *, List<Virtual_column_info> *,
|
||||||
*check_constraint_list,
|
const HA_CREATE_INFO *);
|
||||||
const HA_CREATE_INFO *create_info);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Helper function for explain_filename
|
@brief Helper function for explain_filename
|
||||||
@ -4347,8 +4346,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
const Virtual_column_info *dup_check;
|
const Virtual_column_info *dup_check;
|
||||||
while ((dup_check= dup_it++) && dup_check != check)
|
while ((dup_check= dup_it++) && dup_check != check)
|
||||||
{
|
{
|
||||||
if (!dup_check->name.length || dup_check->automatic_name)
|
|
||||||
continue;
|
|
||||||
if (!lex_string_cmp(system_charset_info,
|
if (!lex_string_cmp(system_charset_info,
|
||||||
&check->name, &dup_check->name))
|
&check->name, &dup_check->name))
|
||||||
{
|
{
|
||||||
@ -8682,37 +8679,28 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: `check` is TABLE resident, we must keep it intact.
|
|
||||||
if (keep)
|
|
||||||
{
|
|
||||||
check= check->clone(thd);
|
|
||||||
if (!check)
|
|
||||||
{
|
|
||||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (share->period.constr_name.streq(check->name.str))
|
if (share->period.constr_name.streq(check->name.str))
|
||||||
{
|
{
|
||||||
if (drop_period)
|
if (!drop_period && !keep)
|
||||||
{
|
|
||||||
keep= false;
|
|
||||||
}
|
|
||||||
else if(!keep)
|
|
||||||
{
|
{
|
||||||
my_error(ER_PERIOD_CONSTRAINT_DROP, MYF(0), check->name.str,
|
my_error(ER_PERIOD_CONSTRAINT_DROP, MYF(0), check->name.str,
|
||||||
share->period.name.str);
|
share->period.name.str);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
keep= keep && !drop_period;
|
||||||
|
|
||||||
|
DBUG_ASSERT(create_info->period_info.constr == NULL || drop_period);
|
||||||
|
|
||||||
|
if (keep)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(create_info->period_info.constr == NULL);
|
Item *expr_copy= check->expr->get_copy(thd);
|
||||||
|
check= new Virtual_column_info();
|
||||||
|
check->name= share->period.constr_name;
|
||||||
|
check->automatic_name= true;
|
||||||
|
check->expr= expr_copy;
|
||||||
create_info->period_info.constr= check;
|
create_info->period_info.constr= check;
|
||||||
create_info->period_info.constr->automatic_name= true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if the constraint depends on *only* on dropped fields */
|
/* see if the constraint depends on *only* on dropped fields */
|
||||||
if (keep && dropped_fields)
|
if (keep && dropped_fields)
|
||||||
{
|
{
|
||||||
|
@ -57,13 +57,7 @@ static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint,
|
|||||||
*/
|
*/
|
||||||
static uchar *extra2_write_len(uchar *pos, size_t len)
|
static uchar *extra2_write_len(uchar *pos, size_t len)
|
||||||
{
|
{
|
||||||
/* TODO: should be
|
DBUG_ASSERT(len);
|
||||||
if (len > 0 && len <= 255)
|
|
||||||
*pos++= (uchar)len;
|
|
||||||
...
|
|
||||||
because extra2_read_len() uses 0 for 2-byte lengths.
|
|
||||||
extra2_str_size() must be fixed too.
|
|
||||||
*/
|
|
||||||
if (len <= 255)
|
if (len <= 255)
|
||||||
*pos++= (uchar)len;
|
*pos++= (uchar)len;
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user