Skip to content

Commit

Permalink
MDEV-7563 Support CHECK constraint as in (or close to) SQL Standard
Browse files Browse the repository at this point in the history
MDEV-10134 Add full support for DEFAULT

- Added support for using tables with MySQL 5.7 virtual fields,
  including MySQL 5.7 syntax
- Better error messages also for old cases
- CREATE ... SELECT now also updates timestamp columns
- Blob can now have default values
- Added new system variable "check_constraint_checks", to turn of
  CHECK constraint checking if needed.
- Removed some engine independent tests in suite vcol to only test myisam
- Moved some tests from 'include' to 't'. Should some day be done for all tests.
- FRM version increased to 11 if one uses virtual fields or constraints
- Changed to use a bitmap to check if a field has got a value, instead of
  setting HAS_EXPLICIT_VALUE bit in field flags
- Expressions can now be up to 65K in total
- Ensure we are not refering to uninitialized fields when handling virtual fields or defaults
- Changed check_vcol_func_processor() to return a bitmap of used types
- Had to change some functions that calculated cached value in fix_fields to do
  this in val() or getdate() instead.
- store_now_in_TIME() now takes a THD argument
- fill_record() now updates default values
- Add a lookahead for NOT NULL, to be able to handle DEFAULT 1+1 NOT NULL
- Automatically generate a name for constraints that doesn't have a name
- Added support for ALTER TABLE DROP CONSTRAINT
- Ensure that partition functions register virtual fields used. This fixes
  some bugs when using virtual fields in a partitioning function
  • Loading branch information
montywi authored and vuvova committed Jun 30, 2016
1 parent 23d03a1 commit db7edfe
Show file tree
Hide file tree
Showing 165 changed files with 5,793 additions and 6,325 deletions.
2 changes: 0 additions & 2 deletions include/mysql_com.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ enum enum_server_command
#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25 */
#define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT)
#define FIELD_IS_DROPPED (1<< 26) /* Intern: Field is being dropped */
#define HAS_EXPLICIT_VALUE (1 << 27) /* An INSERT/UPDATE operation supplied
an explicit default value */

#define REFRESH_GRANT (1ULL << 0) /* Refresh grant tables */
#define REFRESH_LOG (1ULL << 1) /* Start on new log file */
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/extra/rpl_tests/rpl_extra_col_master.test
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ SELECT f1,f2,f3,f4,f5,f6,f7,f8,f9,

--disable_query_log
call mtr.add_suppression("Slave SQL.*Table definition on master and slave does not match: Column 2 type mismatch.* 1535");
call mtr.add_suppression("Slave.*Can.t DROP .c7.; check that column.key exists.* error.* 1091");
call mtr.add_suppression("Slave.*Can.t DROP .c7.; check that .* exists.* error.* 1091");
call mtr.add_suppression("Slave.*Unknown column .c7. in .t15.* error.* 1054");
call mtr.add_suppression("Slave.*Key column .c6. doesn.t exist in table.* error.* 1072");
call mtr.add_suppression("Slave SQL.*Column 2 of table .test.t1.. cannot be converted from type.* error.* 1677");
Expand Down
62 changes: 27 additions & 35 deletions mysql-test/include/function_defaults.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,43 @@ SET TIME_ZONE = "+00:00";
--echo # Test of errors for column data types that dont support function
--echo # defaults.
--echo #
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a BIT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a TINYINT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a SMALLINT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a MEDIUMINT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a INT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a BIGINT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a FLOAT DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a DECIMAL DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a DATE DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a TIME DEFAULT $current_timestamp );
--error ER_INVALID_DEFAULT
eval CREATE TABLE t1( a YEAR DEFAULT $current_timestamp );

eval CREATE OR REPLACE TABLE t1( a BIT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a TINYINT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a SMALLINT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a MEDIUMINT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a INT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a BIGINT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a FLOAT DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a DECIMAL DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a DATE DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a TIME DEFAULT $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a YEAR DEFAULT $current_timestamp );

--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a BIT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a BIT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a TINYINT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a TINYINT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a SMALLINT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a SMALLINT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a MEDIUMINT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a MEDIUMINT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a INT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a INT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a BIGINT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a BIGINT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a FLOAT ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a FLOAT ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a DECIMAL ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a DECIMAL ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a DATE ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a DATE ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a TIME ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a TIME ON UPDATE $current_timestamp );
--error ER_INVALID_ON_UPDATE
eval CREATE TABLE t1( a YEAR ON UPDATE $current_timestamp );
eval CREATE OR REPLACE TABLE t1( a YEAR ON UPDATE $current_timestamp );

drop table if exists t1;

--echo #
--echo # Test that the default clause behaves like NOW() regarding time zones.
Expand Down Expand Up @@ -1066,7 +1058,7 @@ SELECT * FROM v1;
--echo # 1970-01-01 03:33:20
SET TIMESTAMP = 2000.000234;

--error ER_VIEW_CHECK_FAILED
--error ER_CONSTRAINT_FAILED
UPDATE v1 SET a = 2;
SELECT * FROM t1;

Expand All @@ -1091,7 +1083,7 @@ SELECT * FROM v1;

SET TIMESTAMP = 1.126789;

--error ER_VIEW_CHECK_FAILED
--error ER_CONSTRAINT_FAILED
INSERT INTO v1 ( c ) VALUES ( 1 ) ON DUPLICATE KEY UPDATE c = 2;

SELECT * FROM v1;
Expand Down
22 changes: 12 additions & 10 deletions mysql-test/r/alter_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,12 @@ t1 CREATE TABLE `t1` (
UNIQUE KEY `b` (`b`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t1 DROP PRIMARY KEY;
ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists
ERROR 42000: Can't DROP 'PRIMARY'; check that constraint/column/key exists
DROP TABLE t1;
create table t1 (a int, b int, key(a));
insert into t1 values (1,1), (2,2);
alter table t1 drop key no_such_key;
ERROR 42000: Can't DROP 'no_such_key'; check that column/key exists
ERROR 42000: Can't DROP 'no_such_key'; check that constraint/column/key exists
alter table t1 drop key a;
drop table t1;
CREATE TABLE T12207(a int) ENGINE=MYISAM;
Expand Down Expand Up @@ -1374,7 +1374,7 @@ Note 1060 Duplicate column name 'lol'
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
Warnings:
Note 1091 Can't DROP 'lol'; check that column/key exists
Note 1091 Can't DROP 'lol'; check that constraint/column/key exists
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
Warnings:
Expand All @@ -1385,7 +1385,7 @@ Note 1054 Unknown column 'lol' in 't1'
DROP INDEX IF EXISTS x_param ON t1;
DROP INDEX IF EXISTS x_param ON t1;
Warnings:
Note 1091 Can't DROP 'x_param'; check that column/key exists
Note 1091 Can't DROP 'x_param'; check that constraint/column/key exists
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
Warnings:
Expand Down Expand Up @@ -1416,7 +1416,7 @@ Note 1060 Duplicate column name 'lol'
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
Warnings:
Note 1091 Can't DROP 'lol'; check that column/key exists
Note 1091 Can't DROP 'lol'; check that constraint/column/key exists
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
Warnings:
Expand All @@ -1427,7 +1427,7 @@ Note 1054 Unknown column 'lol' in 't1'
DROP INDEX IF EXISTS x_param ON t1;
DROP INDEX IF EXISTS x_param ON t1;
Warnings:
Note 1091 Can't DROP 'x_param'; check that column/key exists
Note 1091 Can't DROP 'x_param'; check that constraint/column/key exists
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
Warnings:
Expand All @@ -1447,7 +1447,7 @@ Note 1061 Duplicate key name 'fk'
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS fk;
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS fk;
Warnings:
Note 1091 Can't DROP 'fk'; check that column/key exists
Note 1091 Can't DROP 'fk'; check that constraint/column/key exists
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
Expand All @@ -1461,7 +1461,7 @@ Note 1061 Duplicate key name 't2_ibfk_1'
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1;
ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1;
Warnings:
Note 1091 Can't DROP 't2_ibfk_1'; check that column/key exists
Note 1091 Can't DROP 't2_ibfk_1'; check that constraint/column/key exists
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
Expand All @@ -1486,10 +1486,10 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t2 DROP KEY k_id, DROP KEY IF EXISTS k_id;
Warnings:
Note 1091 Can't DROP 'k_id'; check that column/key exists
Note 1091 Can't DROP 'k_id'; check that constraint/column/key exists
ALTER TABLE t2 DROP COLUMN a, DROP COLUMN IF EXISTS a;
Warnings:
Note 1091 Can't DROP 'a'; check that column/key exists
Note 1091 Can't DROP 'a'; check that constraint/column/key exists
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
Expand Down Expand Up @@ -1667,6 +1667,8 @@ ALTER TABLE m1 ENABLE KEYS, ALGORITHM= INPLACE, LOCK= EXCLUSIVE;
affected rows: 0
ALTER TABLE m1 ENABLE KEYS, ALGORITHM= COPY, LOCK= NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.
ALTER ONLINE TABLE m1 ADD COLUMN c int;
ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED.
ALTER TABLE m1 ENABLE KEYS, ALGORITHM= COPY, LOCK= SHARED;
affected rows: 2
info: Records: 2 Duplicates: 0 Warnings: 0
Expand Down
97 changes: 97 additions & 0 deletions mysql-test/r/check_constraint.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
set @save_check_constraint=@@check_constraint_checks;
create table t1 (a int check(a>10), b int check (b > 20), constraint `min` check (a+b > 100), constraint `max` check (a+b <500)) engine=myisam;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL CHECK (a>10),
`b` int(11) DEFAULT NULL CHECK (b > 20),
CONSTRAINT `min` CHECK (a+b > 100),
CONSTRAINT `max` CHECK (a+b <500)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (100,100);
insert into t1 values (1,1);
ERROR HY000: CONSTRAINT 'a' failed for 'test.t1'
insert into t1 values (20,1);
ERROR HY000: CONSTRAINT 'b' failed for 'test.t1'
insert into t1 values (20,30);
ERROR HY000: CONSTRAINT 'min' failed for 'test.t1'
insert into t1 values (500,500);
ERROR HY000: CONSTRAINT 'max' failed for 'test.t1'
insert into t1 values (101,101),(102,102),(600,600),(103,103);
ERROR HY000: CONSTRAINT 'max' failed for 'test.t1'
select * from t1;
a b
100 100
101 101
102 102
truncate table t1;
insert ignore into t1 values (101,101),(102,102),(600,600),(103,103);
Warnings:
Warning 1369 CONSTRAINT 'max' failed for 'test.t1'
select * from t1;
a b
101 101
102 102
103 103
set check_constraint_checks=0;
truncate table t1;
insert into t1 values (101,101),(102,102),(600,600),(103,103);
select * from t1;
a b
101 101
102 102
600 600
103 103
set check_constraint_checks=@save_check_constraint;
alter table t1 add c int default 0 check (c < 10);
ERROR HY000: CONSTRAINT 'max' failed for table
set check_constraint_checks=0;
alter table t1 add c int default 0 check (c < 10);
alter table t1 add check (a+b+c < 500);
set check_constraint_checks=@save_check_constraint;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL CHECK (a>10),
`b` int(11) DEFAULT NULL CHECK (b > 20),
`c` int(11) DEFAULT '0' CHECK (c < 10),
CONSTRAINT `min` CHECK (a+b > 100),
CONSTRAINT `max` CHECK (a+b <500),
CONSTRAINT `CONSTRAINT_1` CHECK (a+b+c < 500)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values(105,105,105);
ERROR HY000: CONSTRAINT 'c' failed for 'test.t1'
insert into t1 values(249,249,9);
ERROR HY000: CONSTRAINT 'CONSTRAINT_1' failed for 'test.t1'
insert into t1 values(105,105,9);
select * from t1;
a b c
101 101 0
102 102 0
600 600 0
103 103 0
105 105 9
create table t2 like t1;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL CHECK (a>10),
`b` int(11) DEFAULT NULL CHECK (b > 20),
`c` int(11) DEFAULT '0' CHECK (c < 10),
CONSTRAINT `min` CHECK (a+b > 100),
CONSTRAINT `max` CHECK (a+b <500),
CONSTRAINT `CONSTRAINT_1` CHECK (a+b+c < 500)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
alter table t2 drop constraint c;
ERROR 42000: Can't DROP 'c'; check that constraint/column/key exists
alter table t2 drop constraint min;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL CHECK (a>10),
`b` int(11) DEFAULT NULL CHECK (b > 20),
`c` int(11) DEFAULT '0' CHECK (c < 10),
CONSTRAINT `max` CHECK (a+b <500),
CONSTRAINT `CONSTRAINT_1` CHECK (a+b+c < 500)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2;
27 changes: 27 additions & 0 deletions mysql-test/r/constraints.result
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
drop table if exists t1;
create table t1 (a int check (a>0));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL CHECK (a>0)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1);
insert into t1 values (0);
ERROR HY000: CONSTRAINT 'a' failed for 'test.t1'
drop table t1;
create table t1 (a int, b int, check (a>b));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
CONSTRAINT `CONSTRAINT_1` CHECK (a>b)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1,0);
insert into t1 values (0,1);
ERROR HY000: CONSTRAINT 'CONSTRAINT_1' failed for 'test.t1'
drop table t1;
create table t1 (a int ,b int, constraint abc check (a>b));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
CONSTRAINT `abc` CHECK (a>b)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1,0);
insert into t1 values (0,1);
ERROR HY000: CONSTRAINT 'abc' failed for 'test.t1'
drop table t1;
create table t1 (a int null);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values (1),(NULL);
drop table t1;
create table t1 (a int null);
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/r/create_drop_binlog.result
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ t1 CREATE TABLE `t1` (
DROP INDEX IF EXISTS i1 ON t1;
DROP INDEX IF EXISTS i1 ON t1;
Warnings:
Note 1091 Can't DROP 'i1'; check that column/key exists
Note 1091 Can't DROP 'i1'; check that constraint/column/key exists
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/r/create_drop_index.result
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP INDEX IF EXISTS i1 ON t1;
Warnings:
Note 1091 Can't DROP 'i1'; check that column/key exists
Note 1091 Can't DROP 'i1'; check that constraint/column/key exists
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
Expand Down
Loading

0 comments on commit db7edfe

Please sign in to comment.