]> xenbits.xensource.com Git - osstest.git/commitdiff
host lifecycle: Prevent referential integrity violation
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 27 Aug 2020 17:48:36 +0000 (18:48 +0100)
committerIan Jackson <iwj@xenproject.org>
Wed, 7 Oct 2020 17:39:48 +0000 (18:39 +0100)
We can't use normal constraints for either of these, sadly.

We can make the constraints into a single query which says "OK".

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Osstest/JobDB/Executive.pm

index 3a8308e91066a351092a18eab13723ececd208ea..f69ce277457721723af05ebeca51303fb06104a8 100644 (file)
@@ -553,6 +553,28 @@ END
                ON h.taskid = t.taskid
             WHERE h.hostname = ?
          ORDER BY h.lcseq;
+END
+    # We simulate two foreign key constraints which can't be in the
+    # db schema, by checking the values we are going to insert.
+    #
+    # For "resources" we would need a foreign key constraint
+    # with a literal value as part of the foreign key, which is
+    # not supported until PostgreSQL 13.
+    #
+    # For "tasks" we only want to apply the constraint on inserts into
+    # "host_lifecycle" - in particular, we want to allow delet6ions
+    # from "tasks" to render the taskid foreign key unresolvable.
+    # This could be done with a trigger, but since here is the only
+    # place we do insertions into host_lifecycle, this seems easier.
+    my $constraintsq = $dbh_tests->prepare(<<END);
+           SELECT * FROM
+            (SELECT 1 AS ok
+               FROM resources where restype='host' and resname=?) 
+              hostname_ok
+             NATURAL JOIN
+             (SELECT 1 AS ok
+                FROM tasks where taskid=? AND live)
+              taskid_ok;
 END
     my $insertq = $dbh_tests->prepare(<<END);
         INSERT INTO host_lifecycle
@@ -632,6 +654,9 @@ END
                push @lifecycle, "$omarks$otj:$o->{stepno}$osuffix";
            }
        }
+       $constraintsq->execute($hostname, $ttaskid);
+       $constraintsq->fetchrow_array() or confess "$hostname ?";
+
        if (defined $flight) {
            $insertq->execute($hostname, $ttaskid,
                              $flight, $job,