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 startTime integer, -- if jobset is currently running
type integer not null default 0, -- 0 == legacy, 1 == flake type integer not null default 0, -- 0 == legacy, 1 == flake
flake text, flake text,
check (schedulingShares > 0), constraint jobsets_schedulingshares_nonzero_check check (schedulingShares > 0),
check ((type = 0) = (nixExprInput is not null and nixExprPath is not null)), constraint jobsets_type_known_check check (type = 0 or type = 1),
check ((type = 1) = (flake is not null)), -- 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), primary key (project, name),
foreign key (project) references Projects(name) on delete cascade on update cascade, foreign key (project) references Projects(name) on delete cascade on update cascade,
constraint Jobsets_id_unique UNIQUE(id) 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;