diff options
author | Monty <monty@mariadb.org> | 2019-02-13 18:21:19 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2019-02-13 18:21:19 +0200 |
commit | 438811b4b28fab6c775522bc35b53923c8e1e9c4 (patch) | |
tree | 38b66cc39cb7126abd3148559d9231a37e88972f | |
parent | 44898d28f0f2185a4a8ff109c58972d28b8cae95 (diff) | |
download | mariadb-git-438811b4b28fab6c775522bc35b53923c8e1e9c4.tar.gz |
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
-rw-r--r-- | mysql-test/main/constraints.result | 17 | ||||
-rw-r--r-- | mysql-test/main/constraints.test | 20 | ||||
-rw-r--r-- | sql/field.cc | 1 | ||||
-rw-r--r-- | sql/table.cc | 25 |
4 files changed, 55 insertions, 8 deletions
diff --git a/mysql-test/main/constraints.result b/mysql-test/main/constraints.result index 3c061989fd3..aba226cdd33 100644 --- a/mysql-test/main/constraints.result +++ b/mysql-test/main/constraints.result @@ -111,3 +111,20 @@ long_enough_name CREATE TABLE `long_enough_name` ( CONSTRAINT `constr` CHECK (`f6` >= 0) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE long_enough_name; +create table t1 (a int check (a>10)) select 100 as 'a'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL CHECK (`a` > 10) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a text default(length(now())) check (length(a) > 1)); +insert into t1 values (); +insert into t1 values ("ccc"); +insert into t1 values (""); +ERROR 23000: CONSTRAINT `t1.a` failed for `test`.`t1` +select * from t1; +a +19 +ccc +drop table t1; diff --git a/mysql-test/main/constraints.test b/mysql-test/main/constraints.test index fe51e5060dc..c06f585d04f 100644 --- a/mysql-test/main/constraints.test +++ b/mysql-test/main/constraints.test @@ -102,3 +102,23 @@ SELECT * FROM long_enough_name AS tbl; SHOW CREATE TABLE long_enough_name; DROP TABLE long_enough_name; + +# +# Check that we don't loose constraints as part of CREATE ... SELECT +# + +create table t1 (a int check (a>10)) select 100 as 'a'; +show create table t1; +drop table t1; + +# +# Check that we constraints on field with default expressions work +# + +create table t1 (a text default(length(now())) check (length(a) > 1)); +insert into t1 values (); +insert into t1 values ("ccc"); +--error ER_CONSTRAINT_FAILED +insert into t1 values (""); +select * from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index fbaf3c6ea91..a20525b2764 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11047,6 +11047,7 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field, interval= dup_field->interval; vcol_info= dup_field->vcol_info; invisible= dup_field->invisible; + check_constraint= dup_field->check_constraint; } diff --git a/sql/table.cc b/sql/table.cc index a44e0fcc0a5..d4b1be17c11 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -51,7 +51,8 @@ static Virtual_column_info * unpack_vcol_info_from_frm(THD *, MEM_ROOT *, TABLE *, String *, Virtual_column_info **, bool *); -static bool check_vcol_forward_refs(Field *, Virtual_column_info *); +static bool check_vcol_forward_refs(Field *, Virtual_column_info *, + bool check_constraint); /* INFORMATION_SCHEMA name */ 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, for (field_ptr= table->field; *field_ptr; field_ptr++) { Field *field= *field_ptr; - if (check_vcol_forward_refs(field, field->vcol_info) || - check_vcol_forward_refs(field, field->check_constraint) || - check_vcol_forward_refs(field, field->default_value)) + if (check_vcol_forward_refs(field, field->vcol_info, 0) || + check_vcol_forward_refs(field, field->check_constraint, 1) || + check_vcol_forward_refs(field, field->default_value, 0)) goto end; } @@ -3087,11 +3088,19 @@ end: DBUG_RETURN(vcol_info); } -static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol) +static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol, + bool check_constraint) { - bool res= vcol && - vcol->expr->walk(&Item::check_field_expression_processor, 0, - field); + bool res; + uint32 flags= field->flags; + if (check_constraint) + { + /* Check constraints can refer it itself */ + field->flags|= NO_DEFAULT_VALUE_FLAG; + } + res= (vcol && + vcol->expr->walk(&Item::check_field_expression_processor, 0, field)); + field->flags= flags; return res; } |