Fix check in jobsets

The current check happening in jobsets is incorrect.
The wanted constraint is stated as follow :
- If type is 0 (legacy), then the flake field should be null, and
  both nixExprInput and nixExprPath should be non-null
- If type is 1 (flake), then the flake field should be non-null, and
  both nixExprInput and nixExprPath should be null

The current version will not catch (i.e. it will accept) situations
where you have for instance :
type = 1, nixExprPath null, nixExprInput non-null, flake non-null

This commit fixes that.

I split(ted) that into two constraints, to make it more readable and
easier to extend if a new type appears in the future.

The complete query could be instead :
( type = 0
  AND nixExprInput IS NOT NULL AND nixExprPath IS NOT NULL AND flake IS NULL )
OR ( type = 1
  AND nixExprInput IS NULL AND nixExprPath IS NULL AND flake IS NOT NULL )

(but an "OR" cannot be split, hence the other formulation)
This commit is contained in:
Ismaël Bouya 2021-02-01 19:03:31 +01:00
parent bc12fe19f9
commit 339a09f2e4
No known key found for this signature in database
GPG key ID: FD1D4EF57FA95902
2 changed files with 17 additions and 3 deletions

View file

@ -84,9 +84,14 @@ create table Jobsets (
startTime integer, -- if jobset is currently running
type integer not null default 0, -- 0 == legacy, 1 == flake
flake text,
check (schedulingShares > 0),
check ((type = 0) = (nixExprInput is not null and nixExprPath is not null)),
check ((type = 1) = (flake is not null)),
constraint jobsets_schedulingshares_nonzero_check check (schedulingShares > 0),
constraint jobsets_type_known_check check (type = 0 or type = 1),
-- If the type is 0, then nixExprInput and nixExprPath should be non-null and other type-specific fields should be null
-- Otherwise the check passes
constraint jobsets_legacy_paths_check check ((type = 0) = (nixExprInput is not null and nixExprPath is not null and flake is null)),
-- If the type is 1, then flake should be non-null and other type-specific fields should be null
-- Otherwise the check passes
constraint jobsets_flake_paths_check check ((type = 1) = (nixExprInput is null and nixExprPath is null and flake is not null)),
primary key (project, name),
foreign key (project) references Projects(name) on delete cascade on update cascade,
constraint Jobsets_id_unique UNIQUE(id)

9
src/sql/upgrade-74.sql Normal file
View file

@ -0,0 +1,9 @@
alter table Jobsets add constraint jobsets_type_known_check check (type = 0 or type = 1);
alter table Jobsets add constraint jobsets_legacy_paths_check check ((type = 0) = (nixExprInput is not null and nixExprPath is not null and flake is null));
alter table Jobsets add constraint jobsets_flake_paths_check check ((type = 1) = (nixExprInput is null and nixExprPath is null and flake is not null));
alter table Jobsets add constraint jobsets_schedulingshares_nonzero_check check (schedulingShares > 0);
alter table Jobsets drop constraint if exists jobsets_schedulingshares_check;
alter table Jobsets drop constraint if exists jobsets_check;
alter table Jobsets drop constraint if exists jobsets_check1;
alter table Jobsets drop constraint if exists jobsets_check2;