Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ update_permissions:
updated_by: "x-hasura-user-id"
- role: user
permission:
columns: [name, owner, description]
columns: [name, owner, duration, description, start_time]
filter: {"owner":{"_eq":"X-Hasura-User-Id"}}
set:
updated_by: "x-hasura-user-id"
Expand Down
583 changes: 583 additions & 0 deletions deployment/hasura/migrations/Aerie/35_change_plan_bounds/down.sql

Large diffs are not rendered by default.

660 changes: 660 additions & 0 deletions deployment/hasura/migrations/Aerie/35_change_plan_bounds/up.sql

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions deployment/postgres-init-db/sql/applied_migrations.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ call migrations.mark_migration_applied(31);
call migrations.mark_migration_applied(32);
call migrations.mark_migration_applied(33);
call migrations.mark_migration_applied(34);
call migrations.mark_migration_applied(35);
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ create procedure merlin.begin_merge(_merge_request_id integer, review_username t
snapshot_id_supplying integer;
plan_id_receiving integer;
merge_base_id integer;
start_time_receiving timestamptz;
duration_receiving interval;
start_time_supplying timestamptz;
duration_supplying interval;
begin
-- validate id and status
select id, status
Expand All @@ -50,6 +54,22 @@ begin
where id = _merge_request_id
into plan_id_receiving, snapshot_id_supplying;

-- ensure that the plans cover the same boundaries
select start_time, duration
from merlin.plan
where plan.id = plan_id_receiving
into start_time_receiving, duration_receiving;

select plan_start_time, plan_duration
from merlin.plan_snapshot ps
where ps.snapshot_id = snapshot_id_supplying
into start_time_supplying, duration_supplying;

if start_time_receiving is distinct from start_time_supplying or
duration_receiving is distinct from duration_supplying then
raise exception 'Cannot begin merge request between plans with different bounds';
end if;

-- ensure the plan receiving changes isn't locked
if (select is_locked from merlin.plan where plan.id=plan_id_receiving) then
raise exception 'Cannot begin merge request. Plan to receive changes is locked.';
Expand All @@ -71,7 +91,6 @@ begin
reviewer_username = review_username
where id = _merge_request_id;


-- perform diff between mb and s_sc (s_diff)
-- delete is B minus A on key
-- add is A minus B on key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,27 @@ declare
merge_request_id integer;
model_id_receiving integer;
model_id_supplying integer;
start_time_receiving timestamptz;
duration_receiving interval;
start_time_supplying timestamptz;
duration_supplying interval;
begin
if plan_id_receiving = plan_id_supplying then
raise exception 'Cannot create a merge request between a plan and itself.';
end if;
select id from merlin.plan where plan.id = plan_id_receiving into validate_planIds;

select id, model_id, start_time, duration
from merlin.plan
where plan.id = plan_id_receiving
into validate_planIds, model_id_receiving, start_time_receiving, duration_receiving;
if validate_planIds is null then
raise exception 'Plan receiving changes (Plan %) does not exist.', plan_id_receiving;
end if;
select id from merlin.plan where plan.id = plan_id_supplying into validate_planIds;

select id, model_id, start_time, duration
from merlin.plan
where plan.id = plan_id_supplying
into validate_planIds, model_id_supplying, start_time_supplying, duration_supplying;
if validate_planIds is null then
raise exception 'Plan supplying changes (Plan %) does not exist.', plan_id_supplying;
end if;
Expand All @@ -28,12 +40,15 @@ begin
raise exception 'Cannot create merge request between unrelated plans.';
end if;

select model_id from merlin.plan where plan.id = plan_id_receiving into model_id_receiving;
select model_id from merlin.plan where plan.id = plan_id_supplying into model_id_supplying;
if model_id_receiving is distinct from model_id_supplying then
raise exception 'Cannot create merge request: plan supplying changes is using a different model (%) than the receiving plan (%)', model_id_supplying, model_id_receiving;
end if;

if (start_time_receiving is distinct from start_time_supplying) or
(duration_receiving is distinct from duration_supplying) then
raise exception 'Cannot create merge request between plans with different bounds';
end if;

insert into merlin.merge_request(plan_id_receiving_changes, snapshot_id_supplying_changes, merge_base_snapshot_id, requester_username)
values(plan_id_receiving, supplying_snapshot_id, merge_base_snapshot_id, request_username)
returning id into merge_request_id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ begin
raise exception 'Plan % does not exist.', _plan_id;
end if;

insert into merlin.plan_snapshot(plan_id, model_id, revision, snapshot_name, description, taken_by)
select id, model_id, revision, _snapshot_name, _description, _user
insert into merlin.plan_snapshot(plan_id, model_id, revision, plan_start_time, plan_duration,
snapshot_name, description, taken_by)
select id, model_id, revision, start_time, duration,
_snapshot_name, _description, _user
from merlin.plan where id = _plan_id
returning snapshot_id into inserted_snapshot_id;

insert into merlin.plan_snapshot_activities(
snapshot_id, id, name, source_scheduling_goal_id, source_scheduling_goal_invocation_id, created_at, created_by,
last_modified_at, last_modified_by, start_offset, type,
Expand All @@ -33,10 +36,12 @@ begin
last_modified_at, last_modified_by, start_offset, type,
arguments, last_modified_arguments_at, metadata, anchor_id, anchored_to_start
from merlin.activity_directive where activity_directive.plan_id = _plan_id;

insert into merlin.preset_to_snapshot_directive(preset_id, activity_id, snapshot_id)
select ptd.preset_id, ptd.activity_id, inserted_snapshot_id
from merlin.preset_to_directive ptd
where ptd.plan_id = _plan_id;

insert into tags.snapshot_activity_tags(snapshot_id, directive_id, tag_id)
select inserted_snapshot_id, directive_id, tag_id
from tags.activity_directive_tags adt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ create procedure merlin.restore_from_snapshot(_plan_id integer, _snapshot_id int
_snapshot_name text;
_plan_name text;
_model_id integer;
_plan_start_time timestamptz;
_plan_duration interval;
begin
-- Input Validation
select name from merlin.plan where id = _plan_id into _plan_name;
Expand All @@ -23,17 +25,23 @@ create procedure merlin.restore_from_snapshot(_plan_id integer, _snapshot_id int
_snapshot_id, _plan_name, _plan_id;
end if;
end if;
select model_id from merlin.plan_snapshot where snapshot_id = _snapshot_id into _model_id;

select model_id, plan_start_time, plan_duration
from merlin.plan_snapshot
where snapshot_id = _snapshot_id
into _model_id, _plan_start_time, _plan_duration;
if not exists(select from merlin.mission_model m where m.id = _model_id) then
raise exception 'Cannot Restore: Model with ID % does not exist.', _model_id;
end if;

-- Catch Plan_Locked
call merlin.plan_locked_exception(_plan_id);

-- Update model_id of the plan
-- Update model_id and bounds of the plan
update merlin.plan
set model_id = _model_id
set model_id = _model_id,
start_time = _plan_start_time,
duration = _plan_duration
where id = _plan_id;

-- Record the Union of Activities in Plan and Snapshot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ end$$;
create trigger increment_plan_revision_on_directive_update_trigger
after update on merlin.activity_directive
for each row
when (pg_trigger_depth() < 1)
execute function merlin.increment_plan_revision_on_directive_update();

create function merlin.increment_plan_revision_on_directive_delete()
Expand Down
52 changes: 52 additions & 0 deletions deployment/postgres-init-db/sql/tables/merlin/plan.sql
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,58 @@ for each row
when (pg_trigger_depth() < 1)
execute function util_functions.increment_revision_update();

create function merlin.cascade_plan_bounds_update()
returns trigger
language plpgsql as $$
begin
-- prevent adjustment if the plan is locked
if old.is_locked then
raise exception 'Cannot adjust bounds of locked plan.';
end if;

-- Take a backup snapshot
perform merlin.create_snapshot(
old.id,
'Plan Bound Adjustment',
'Automatic snapshot made before adjusting plan bounds from ' ||
'['|| old.start_time ||' - '|| old.start_time + old.duration || '] to ' ||
'[' || new.start_time || ' - ' || new.start_time + new.duration || ']',
null);

-- Update activities that are anchored to the plan bounds
update merlin.activity_directive ad
set start_offset = start_offset + (new.start_time - old.start_time)
where anchor_id is null
and anchored_to_start -- anchored to plan start
and ad.plan_id = old.id;

update merlin.activity_directive ad
set start_offset = start_offset + (new.duration - old.duration)
where anchor_id is null
and not anchored_to_start -- anchored to plan end
and ad.plan_id = old.id;

-- Update associated dataset offsets (simulation and plan)
update merlin.simulation_dataset
set offset_from_plan_start = offset_from_plan_start + (new.start_time - old.start_time)
from merlin.simulation sim_spec
where simulation_id = sim_spec.id
and sim_spec.plan_id = old.id;

update merlin.plan_dataset
set offset_from_plan_start = offset_from_plan_start + (new.start_time - old.start_time)
where plan_id = old.id;

return new;
end;
$$;

create trigger cascade_plan_bounds_on_update
before update on merlin.plan
for each row
when (old.start_time is distinct from new.start_time or old.duration is distinct from new.duration)
execute function merlin.cascade_plan_bounds_update();

-- Delete Triggers

create function merlin.cleanup_on_delete()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ create table merlin.plan_snapshot(
references merlin.mission_model
on delete set null,
revision integer not null,
plan_start_time timestamptz not null,
plan_duration interval not null,

snapshot_name text,
description text,
taken_by text,
taken_at timestamptz not null default now(),
constraint snapshot_name_unique_per_plan
unique (plan_id, snapshot_name)
taken_at timestamptz not null default now()
);

comment on table merlin.plan_snapshot is e''
Expand All @@ -31,6 +31,10 @@ comment on column merlin.plan_snapshot.model_id is e''
'The model that this plan was using at the time the snapshot was taken.';
comment on column merlin.plan_snapshot.revision is e''
'The revision of the plan at the time the snapshot was taken.';
comment on column merlin.plan_snapshot.plan_start_time is e''
'The start time of the plan at the time the snapshot was taken.';
comment on column merlin.plan_snapshot.plan_duration is e''
'The duration of the plan at the time the snapshot was taken.';
comment on column merlin.plan_snapshot.snapshot_name is e''
'A human-readable name for the snapshot.';
comment on column merlin.plan_snapshot.description is e''
Expand Down
Loading