Skip to content

Commit 438811b

Browse files
committed
Fixed two bugs related to column level constraints
- CREATE TABLE ... SELECT drops constraints for columns that are both in the create and select part. - Fixed by copying the constraint in Column_definiton::redefine_stage1_common() - If one has both a default expression and check constraint for a column, one can get the error "Expression for field `a` is refering to uninitialized field `a`. - Fixed by ignoring default expressions for current column when checking for CHECK constraint
1 parent 44898d2 commit 438811b

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed

mysql-test/main/constraints.result

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,20 @@ long_enough_name CREATE TABLE `long_enough_name` (
111111
CONSTRAINT `constr` CHECK (`f6` >= 0)
112112
) ENGINE=MyISAM DEFAULT CHARSET=latin1
113113
DROP TABLE long_enough_name;
114+
create table t1 (a int check (a>10)) select 100 as 'a';
115+
show create table t1;
116+
Table Create Table
117+
t1 CREATE TABLE `t1` (
118+
`a` int(11) DEFAULT NULL CHECK (`a` > 10)
119+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
120+
drop table t1;
121+
create table t1 (a text default(length(now())) check (length(a) > 1));
122+
insert into t1 values ();
123+
insert into t1 values ("ccc");
124+
insert into t1 values ("");
125+
ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1`
126+
select * from t1;
127+
a
128+
19
129+
ccc
130+
drop table t1;

mysql-test/main/constraints.test

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,23 @@ SELECT * FROM long_enough_name AS tbl;
102102
SHOW CREATE TABLE long_enough_name;
103103

104104
DROP TABLE long_enough_name;
105+
106+
#
107+
# Check that we don't loose constraints as part of CREATE ... SELECT
108+
#
109+
110+
create table t1 (a int check (a>10)) select 100 as 'a';
111+
show create table t1;
112+
drop table t1;
113+
114+
#
115+
# Check that we constraints on field with default expressions work
116+
#
117+
118+
create table t1 (a text default(length(now())) check (length(a) > 1));
119+
insert into t1 values ();
120+
insert into t1 values ("ccc");
121+
--error ER_CONSTRAINT_FAILED
122+
insert into t1 values ("");
123+
select * from t1;
124+
drop table t1;

sql/field.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11047,6 +11047,7 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field,
1104711047
interval= dup_field->interval;
1104811048
vcol_info= dup_field->vcol_info;
1104911049
invisible= dup_field->invisible;
11050+
check_constraint= dup_field->check_constraint;
1105011051
}
1105111052

1105211053

sql/table.cc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@
5151

5252
static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *,
5353
TABLE *, String *, Virtual_column_info **, bool *);
54-
static bool check_vcol_forward_refs(Field *, Virtual_column_info *);
54+
static bool check_vcol_forward_refs(Field *, Virtual_column_info *,
55+
bool check_constraint);
5556

5657
/* INFORMATION_SCHEMA name */
5758
LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")};
@@ -1135,9 +1136,9 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
11351136
for (field_ptr= table->field; *field_ptr; field_ptr++)
11361137
{
11371138
Field *field= *field_ptr;
1138-
if (check_vcol_forward_refs(field, field->vcol_info) ||
1139-
check_vcol_forward_refs(field, field->check_constraint) ||
1140-
check_vcol_forward_refs(field, field->default_value))
1139+
if (check_vcol_forward_refs(field, field->vcol_info, 0) ||
1140+
check_vcol_forward_refs(field, field->check_constraint, 1) ||
1141+
check_vcol_forward_refs(field, field->default_value, 0))
11411142
goto end;
11421143
}
11431144

@@ -3087,11 +3088,19 @@ unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table,
30873088
DBUG_RETURN(vcol_info);
30883089
}
30893090

3090-
static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
3091+
static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol,
3092+
bool check_constraint)
30913093
{
3092-
bool res= vcol &&
3093-
vcol->expr->walk(&Item::check_field_expression_processor, 0,
3094-
field);
3094+
bool res;
3095+
uint32 flags= field->flags;
3096+
if (check_constraint)
3097+
{
3098+
/* Check constraints can refer it itself */
3099+
field->flags|= NO_DEFAULT_VALUE_FLAG;
3100+
}
3101+
res= (vcol &&
3102+
vcol->expr->walk(&Item::check_field_expression_processor, 0, field));
3103+
field->flags= flags;
30953104
return res;
30963105
}
30973106

0 commit comments

Comments
 (0)