[MDEV-11117] CHECK constraint fails on intermediate step of ALTER Created: 2016-10-23  Updated: 2020-04-27  Resolved: 2017-04-18

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table
Affects Version/s: 10.2
Fix Version/s: 10.2.6

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Jacob Mathew (Inactive)
Resolution: Fixed Votes: 0
Labels: 10.2-ga

Issue Links:
Relates
relates to MDEV-7563 Support CHECK constraint as in (or cl... Closed
Sprint: 10.2.6-3

 Description   

MariaDB [test]> create table t1 (a int, check(a>0 or a is null));
Query OK, 0 rows affected (0.41 sec)
 
MariaDB [test]> insert into t1 values (null);
Query OK, 1 row affected (0.06 sec)
 
MariaDB [test]> alter table t1 modify a int auto_increment primary key;
ERROR 4025 (23000): CONSTRAINT `CONSTRAINT_1` failed for `test`.`#sql-4c9e_4`

If there were no CHECK, a column would have been given the value 1 which actually satisfies the condition.

MariaDB [test]> set check_constraint_checks=0;
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> alter table t1 modify a int auto_increment primary key;
Query OK, 1 row affected (1.01 sec)
Records: 1  Duplicates: 0  Warnings: 0
 
MariaDB [test]> select * from t1;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

But apparently the column gets the intermediate value 0 which is checked before the auto_increment is applied.



 Comments   
Comment by Jacob Mathew (Inactive) [ 2017-02-16 ]

At the point when the check constraint is evaluated during the ALTER TABLE, the information that the column is NULLable and that the row's column value is NULL has been removed, but the column's value has not yet been updated with the auto-increment value, so the check constraint appears to be violated.

Comment by Jacob Mathew (Inactive) [ 2017-02-17 ]

ALTER TABLE is unnecessary to reproduce the problem regarding check constraints on an auto-increment column:

MariaDB [test]> create or replace table t2( a int auto_increment primary key, b int );
Query OK, 0 rows affected (0.10 sec)
 
MariaDB [test]> insert into t2( b ) values( NULL );
Query OK, 1 row affected (4.40 sec)
 
MariaDB [test]> select * from t2;
+---+------+
| a | b    |
+---+------+
| 1 | NULL |
+---+------+
1 row in set (0.00 sec)

Without the check constraint, the auto-increment column gets a value of 1. Here is what happens with the check constraint:

MariaDB [test]> create or replace table t2( a int auto_increment primary key, b int, check( a > 0 or a is null ) );
Query OK, 0 rows affected (0.09 sec)
 
MariaDB [test]> insert into t2( b ) values( NULL );
ERROR 4025 (23000): CONSTRAINT `CONSTRAINT_1` failed for `test`.`t2`
MariaDB [test]>

This occurs because auto-increment columns are given their incremented value as part of the storage engine process of writing a row, whereas check constraints are evaluated on the row prior to writing the row, at a time when the auto-increment column has been cleared and therefore has a value of zero.

Comment by Sergei Golubchik [ 2017-02-19 ]

Let's disallow auto-increment columns in CHECK constraints. They are similarly disallowed in virtual columns and should be disallowed in DEFAULT expressions too (please check that).

We'd need to refactor auto-increment implementation to make all this working as expected. It cannot be done in 10.2.

Comment by Jacob Mathew (Inactive) [ 2017-04-04 ]

I have fixed the bug by disallowing auto-increment columns in CHECK constraints, DEFAULT expressions and VIRTUAL COLUMN expressions in commit https://github.com/MariaDB/server/commit/b7aa15458db95149af4f473a90009844a16e9db8.

Comment by Jacob Mathew (Inactive) [ 2017-04-04 ]

Hi Sergei,

I've fixed the bug by disallowing auto-increment columns in CHECK constraints, DEFAULT value expressions and VIRTUAL COLUMN expressions, in commit https://github.com/MariaDB/server/commit/b7aa15458db95149af4f473a90009844a16e9db8. Please review.

Thanks,
Jacob

Comment by Jacob Mathew (Inactive) [ 2017-04-18 ]

I have merged the final version of the fix, committed in https://github.com/MariaDB/server/commit/38af34bb2143f2a7ce82d2e241d8995f419a7f29, into the 10.2 branch.

Comment by Jacob Mathew (Inactive) [ 2017-04-18 ]

I have merged the final version of the fix, committed in https://github.com/MariaDB/server/commit/38af34bb2143f2a7ce82d2e241d8995f419a7f29, into the 10.2 branch.

Comment by Oleksandr Diedyk [ 2020-04-27 ]

By making this fix, you've denied using columns in kind of 'recursive' approach.
I have this table which defines nodes and hierarchy between them

create table `track_tree` (
    `node_id` bigint not null auto_increment primary key,
    `parent_node_id` bigint,
    constraint `track_tree_node_id_parent_node_id_ck` check (parent_node_id <> node_id)
)

So check constraint here is not allowed anymore.
Can you suggest any workaround besides having separate table for "relations" between nodes?

Comment by Sergei Golubchik [ 2020-04-27 ]

because of the way auto-increment columns are implemented, neither check constraints, nor virtual columns, not default expressions work with them, unfortunately.

as a workaround you might try to use sequences, perhaps they'll help.

Generated at Thu Feb 08 07:47:26 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.