diff --git a/src/sql/upgrade-79.sql b/src/sql/upgrade-79.sql new file mode 100644 index 00000000..348b19fa --- /dev/null +++ b/src/sql/upgrade-79.sql @@ -0,0 +1,49 @@ + + +-- Records of RunCommand executions +-- +-- The intended flow is: +-- +-- 1. Create a RunCommandLogs entry when the task is "queued" to run +-- 2. Update the start_time when it begins +-- 3. Update the end_time and exit_code when it completes +create table RunCommandLogs ( + id serial primary key not null, + job_matcher text not null, + build_id integer not null, + -- TODO: evaluation_id integer not null, + -- can we do this in a principled way? a build can be part of many evaluations + -- but a "bug" of RunCommand, imho, is that it should probably run per evaluation? + command text not null, + start_time integer, + end_time integer, + error_number integer, + exit_code integer, + signal integer, + core_dumped boolean, + + foreign key (build_id) references Builds(id) on delete cascade, + -- foreign key (evaluation_id) references Builds(id) on delete cascade, + + + constraint RunCommandLogs_not_started_no_exit_time_no_code check ( + -- If start time is null, then end_time, exit_code, signal, and core_dumped should be null. + -- A logical implication operator would be nice :). + (start_time is not null) or ( + end_time is null + and error_number is null + and exit_code is null + and signal is null + and core_dumped is null + ) + ), + constraint RunCommandLogs_end_time_has_start_time check ( + -- If end time is not null, then end_time, exit_code, and core_dumped should not be null + (end_time is null) or (start_time is not null) + ) + + -- Note: if exit_code is not null then signal and core_dumped must be null. + -- Similarly, if signal is not null then exit_code must be null and + -- core_dumped must not be null. However, these semantics are tricky + -- to encode as constraints and probably provide limited actual value. +);