← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:db-baseline-2211 into launchpad:db-devel

 

Colin Watson has proposed merging ~cjwatson/launchpad:db-baseline-2211 into launchpad:db-devel.

Commit message:
Rebaseline schema, version 2211

Requested reviews:
  William Grant (wgrant): db
  Launchpad code reviewers (launchpad-reviewers): db

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/426916

This should allow `make schema` to work on focal.
-- 
The attached diff has been truncated due to its size.
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:db-baseline-2211 into launchpad:db-devel.
diff --git a/database/schema/Makefile b/database/schema/Makefile
index 5d303fb..c3a6b0c 100644
--- a/database/schema/Makefile
+++ b/database/schema/Makefile
@@ -57,12 +57,11 @@ build_new_sampledata=./fti.py --null -d ${1} -q && \
 # The latest schema dump from production. Database patches are relative
 # to this baseline. This dump should be updated occasionally from production
 # to ensure that the development database remains in sync with reality
-# on production. It is generated using newbaseline.py in
-# bzr+ssh://devpad.canonical.com/code/stub/dbascripts
+# on production. It is generated using database/schema/newbaseline.py.
 #
-REV=2210
+REV=2211
 BASELINE=launchpad-${REV}-00-0.sql
-MD5SUM=36ae7078cd41916bbbd9c116b2e6aea7  launchpad-2210-00-0.sql
+MD5SUM=ab4516c1e0439619f6c3a8e248d0c37a  launchpad-2211-00-0.sql
 
 default: all
 
diff --git a/database/schema/patch-2210-00-0.sql b/database/schema/archive/patch-2210-00-0.sql
similarity index 100%
rename from database/schema/patch-2210-00-0.sql
rename to database/schema/archive/patch-2210-00-0.sql
diff --git a/database/schema/patch-2210-01-0.sql b/database/schema/archive/patch-2210-01-0.sql
similarity index 100%
rename from database/schema/patch-2210-01-0.sql
rename to database/schema/archive/patch-2210-01-0.sql
diff --git a/database/schema/patch-2210-01-1.sql b/database/schema/archive/patch-2210-01-1.sql
similarity index 100%
rename from database/schema/patch-2210-01-1.sql
rename to database/schema/archive/patch-2210-01-1.sql
diff --git a/database/schema/patch-2210-01-2.sql b/database/schema/archive/patch-2210-01-2.sql
similarity index 100%
rename from database/schema/patch-2210-01-2.sql
rename to database/schema/archive/patch-2210-01-2.sql
diff --git a/database/schema/patch-2210-01-3.sql b/database/schema/archive/patch-2210-01-3.sql
similarity index 100%
rename from database/schema/patch-2210-01-3.sql
rename to database/schema/archive/patch-2210-01-3.sql
diff --git a/database/schema/patch-2210-01-4.sql b/database/schema/archive/patch-2210-01-4.sql
similarity index 100%
rename from database/schema/patch-2210-01-4.sql
rename to database/schema/archive/patch-2210-01-4.sql
diff --git a/database/schema/patch-2210-03-0.sql b/database/schema/archive/patch-2210-03-0.sql
similarity index 100%
rename from database/schema/patch-2210-03-0.sql
rename to database/schema/archive/patch-2210-03-0.sql
diff --git a/database/schema/patch-2210-04-0.sql b/database/schema/archive/patch-2210-04-0.sql
similarity index 100%
rename from database/schema/patch-2210-04-0.sql
rename to database/schema/archive/patch-2210-04-0.sql
diff --git a/database/schema/patch-2210-05-0.sql b/database/schema/archive/patch-2210-05-0.sql
similarity index 100%
rename from database/schema/patch-2210-05-0.sql
rename to database/schema/archive/patch-2210-05-0.sql
diff --git a/database/schema/patch-2210-06-0.sql b/database/schema/archive/patch-2210-06-0.sql
similarity index 100%
rename from database/schema/patch-2210-06-0.sql
rename to database/schema/archive/patch-2210-06-0.sql
diff --git a/database/schema/patch-2210-06-1.sql b/database/schema/archive/patch-2210-06-1.sql
similarity index 100%
rename from database/schema/patch-2210-06-1.sql
rename to database/schema/archive/patch-2210-06-1.sql
diff --git a/database/schema/patch-2210-07-0.sql b/database/schema/archive/patch-2210-07-0.sql
similarity index 100%
rename from database/schema/patch-2210-07-0.sql
rename to database/schema/archive/patch-2210-07-0.sql
diff --git a/database/schema/patch-2210-08-0.sql b/database/schema/archive/patch-2210-08-0.sql
similarity index 100%
rename from database/schema/patch-2210-08-0.sql
rename to database/schema/archive/patch-2210-08-0.sql
diff --git a/database/schema/patch-2210-08-1.sql b/database/schema/archive/patch-2210-08-1.sql
similarity index 100%
rename from database/schema/patch-2210-08-1.sql
rename to database/schema/archive/patch-2210-08-1.sql
diff --git a/database/schema/patch-2210-08-2.sql b/database/schema/archive/patch-2210-08-2.sql
similarity index 100%
rename from database/schema/patch-2210-08-2.sql
rename to database/schema/archive/patch-2210-08-2.sql
diff --git a/database/schema/patch-2210-08-3.sql b/database/schema/archive/patch-2210-08-3.sql
similarity index 100%
rename from database/schema/patch-2210-08-3.sql
rename to database/schema/archive/patch-2210-08-3.sql
diff --git a/database/schema/patch-2210-08-4.sql b/database/schema/archive/patch-2210-08-4.sql
similarity index 100%
rename from database/schema/patch-2210-08-4.sql
rename to database/schema/archive/patch-2210-08-4.sql
diff --git a/database/schema/patch-2210-08-5.sql b/database/schema/archive/patch-2210-08-5.sql
similarity index 100%
rename from database/schema/patch-2210-08-5.sql
rename to database/schema/archive/patch-2210-08-5.sql
diff --git a/database/schema/patch-2210-08-6.sql b/database/schema/archive/patch-2210-08-6.sql
similarity index 100%
rename from database/schema/patch-2210-08-6.sql
rename to database/schema/archive/patch-2210-08-6.sql
diff --git a/database/schema/patch-2210-08-7.sql b/database/schema/archive/patch-2210-08-7.sql
similarity index 100%
rename from database/schema/patch-2210-08-7.sql
rename to database/schema/archive/patch-2210-08-7.sql
diff --git a/database/schema/patch-2210-08-8.sql b/database/schema/archive/patch-2210-08-8.sql
similarity index 100%
rename from database/schema/patch-2210-08-8.sql
rename to database/schema/archive/patch-2210-08-8.sql
diff --git a/database/schema/patch-2210-08-9.sql b/database/schema/archive/patch-2210-08-9.sql
similarity index 100%
rename from database/schema/patch-2210-08-9.sql
rename to database/schema/archive/patch-2210-08-9.sql
diff --git a/database/schema/patch-2210-09-0.sql b/database/schema/archive/patch-2210-09-0.sql
similarity index 100%
rename from database/schema/patch-2210-09-0.sql
rename to database/schema/archive/patch-2210-09-0.sql
diff --git a/database/schema/patch-2210-10-0.sql b/database/schema/archive/patch-2210-10-0.sql
similarity index 100%
rename from database/schema/patch-2210-10-0.sql
rename to database/schema/archive/patch-2210-10-0.sql
diff --git a/database/schema/patch-2210-10-1.sql b/database/schema/archive/patch-2210-10-1.sql
similarity index 100%
rename from database/schema/patch-2210-10-1.sql
rename to database/schema/archive/patch-2210-10-1.sql
diff --git a/database/schema/patch-2210-11-0.sql b/database/schema/archive/patch-2210-11-0.sql
similarity index 100%
rename from database/schema/patch-2210-11-0.sql
rename to database/schema/archive/patch-2210-11-0.sql
diff --git a/database/schema/patch-2210-11-1.sql b/database/schema/archive/patch-2210-11-1.sql
similarity index 100%
rename from database/schema/patch-2210-11-1.sql
rename to database/schema/archive/patch-2210-11-1.sql
diff --git a/database/schema/patch-2210-11-2.sql b/database/schema/archive/patch-2210-11-2.sql
similarity index 100%
rename from database/schema/patch-2210-11-2.sql
rename to database/schema/archive/patch-2210-11-2.sql
diff --git a/database/schema/patch-2210-11-3.sql b/database/schema/archive/patch-2210-11-3.sql
similarity index 100%
rename from database/schema/patch-2210-11-3.sql
rename to database/schema/archive/patch-2210-11-3.sql
diff --git a/database/schema/patch-2210-12-0.sql b/database/schema/archive/patch-2210-12-0.sql
similarity index 100%
rename from database/schema/patch-2210-12-0.sql
rename to database/schema/archive/patch-2210-12-0.sql
diff --git a/database/schema/patch-2210-13-0.sql b/database/schema/archive/patch-2210-13-0.sql
similarity index 100%
rename from database/schema/patch-2210-13-0.sql
rename to database/schema/archive/patch-2210-13-0.sql
diff --git a/database/schema/patch-2210-13-1.sql b/database/schema/archive/patch-2210-13-1.sql
similarity index 100%
rename from database/schema/patch-2210-13-1.sql
rename to database/schema/archive/patch-2210-13-1.sql
diff --git a/database/schema/patch-2210-14-0.sql b/database/schema/archive/patch-2210-14-0.sql
similarity index 100%
rename from database/schema/patch-2210-14-0.sql
rename to database/schema/archive/patch-2210-14-0.sql
diff --git a/database/schema/patch-2210-15-0.sql b/database/schema/archive/patch-2210-15-0.sql
similarity index 100%
rename from database/schema/patch-2210-15-0.sql
rename to database/schema/archive/patch-2210-15-0.sql
diff --git a/database/schema/patch-2210-15-1.sql b/database/schema/archive/patch-2210-15-1.sql
similarity index 100%
rename from database/schema/patch-2210-15-1.sql
rename to database/schema/archive/patch-2210-15-1.sql
diff --git a/database/schema/patch-2210-16-0.sql b/database/schema/archive/patch-2210-16-0.sql
similarity index 100%
rename from database/schema/patch-2210-16-0.sql
rename to database/schema/archive/patch-2210-16-0.sql
diff --git a/database/schema/patch-2210-17-0.sql b/database/schema/archive/patch-2210-17-0.sql
similarity index 100%
rename from database/schema/patch-2210-17-0.sql
rename to database/schema/archive/patch-2210-17-0.sql
diff --git a/database/schema/patch-2210-17-1.sql b/database/schema/archive/patch-2210-17-1.sql
similarity index 100%
rename from database/schema/patch-2210-17-1.sql
rename to database/schema/archive/patch-2210-17-1.sql
diff --git a/database/schema/patch-2210-18-0.sql b/database/schema/archive/patch-2210-18-0.sql
similarity index 100%
rename from database/schema/patch-2210-18-0.sql
rename to database/schema/archive/patch-2210-18-0.sql
diff --git a/database/schema/patch-2210-19-0.sql b/database/schema/archive/patch-2210-19-0.sql
similarity index 100%
rename from database/schema/patch-2210-19-0.sql
rename to database/schema/archive/patch-2210-19-0.sql
diff --git a/database/schema/patch-2210-20-0.sql b/database/schema/archive/patch-2210-20-0.sql
similarity index 100%
rename from database/schema/patch-2210-20-0.sql
rename to database/schema/archive/patch-2210-20-0.sql
diff --git a/database/schema/patch-2210-20-1.sql b/database/schema/archive/patch-2210-20-1.sql
similarity index 100%
rename from database/schema/patch-2210-20-1.sql
rename to database/schema/archive/patch-2210-20-1.sql
diff --git a/database/schema/patch-2210-21-0.sql b/database/schema/archive/patch-2210-21-0.sql
similarity index 100%
rename from database/schema/patch-2210-21-0.sql
rename to database/schema/archive/patch-2210-21-0.sql
diff --git a/database/schema/patch-2210-22-0.sql b/database/schema/archive/patch-2210-22-0.sql
similarity index 100%
rename from database/schema/patch-2210-22-0.sql
rename to database/schema/archive/patch-2210-22-0.sql
diff --git a/database/schema/patch-2210-22-1.sql b/database/schema/archive/patch-2210-22-1.sql
similarity index 100%
rename from database/schema/patch-2210-22-1.sql
rename to database/schema/archive/patch-2210-22-1.sql
diff --git a/database/schema/patch-2210-23-0.sql b/database/schema/archive/patch-2210-23-0.sql
similarity index 100%
rename from database/schema/patch-2210-23-0.sql
rename to database/schema/archive/patch-2210-23-0.sql
diff --git a/database/schema/patch-2210-24-0.sql b/database/schema/archive/patch-2210-24-0.sql
similarity index 100%
rename from database/schema/patch-2210-24-0.sql
rename to database/schema/archive/patch-2210-24-0.sql
diff --git a/database/schema/patch-2210-24-1.sql b/database/schema/archive/patch-2210-24-1.sql
similarity index 100%
rename from database/schema/patch-2210-24-1.sql
rename to database/schema/archive/patch-2210-24-1.sql
diff --git a/database/schema/patch-2210-25-0.sql b/database/schema/archive/patch-2210-25-0.sql
similarity index 100%
rename from database/schema/patch-2210-25-0.sql
rename to database/schema/archive/patch-2210-25-0.sql
diff --git a/database/schema/patch-2210-26-1.sql b/database/schema/archive/patch-2210-26-1.sql
similarity index 100%
rename from database/schema/patch-2210-26-1.sql
rename to database/schema/archive/patch-2210-26-1.sql
diff --git a/database/schema/patch-2210-26-2.sql b/database/schema/archive/patch-2210-26-2.sql
similarity index 100%
rename from database/schema/patch-2210-26-2.sql
rename to database/schema/archive/patch-2210-26-2.sql
diff --git a/database/schema/patch-2210-26-3.sql b/database/schema/archive/patch-2210-26-3.sql
similarity index 100%
rename from database/schema/patch-2210-26-3.sql
rename to database/schema/archive/patch-2210-26-3.sql
diff --git a/database/schema/patch-2210-26-4.sql b/database/schema/archive/patch-2210-26-4.sql
similarity index 100%
rename from database/schema/patch-2210-26-4.sql
rename to database/schema/archive/patch-2210-26-4.sql
diff --git a/database/schema/patch-2210-27-0.sql b/database/schema/archive/patch-2210-27-0.sql
similarity index 100%
rename from database/schema/patch-2210-27-0.sql
rename to database/schema/archive/patch-2210-27-0.sql
diff --git a/database/schema/patch-2210-28-0.sql b/database/schema/archive/patch-2210-28-0.sql
similarity index 100%
rename from database/schema/patch-2210-28-0.sql
rename to database/schema/archive/patch-2210-28-0.sql
diff --git a/database/schema/patch-2210-30-0.sql b/database/schema/archive/patch-2210-30-0.sql
similarity index 100%
rename from database/schema/patch-2210-30-0.sql
rename to database/schema/archive/patch-2210-30-0.sql
diff --git a/database/schema/patch-2210-30-1.sql b/database/schema/archive/patch-2210-30-1.sql
similarity index 100%
rename from database/schema/patch-2210-30-1.sql
rename to database/schema/archive/patch-2210-30-1.sql
diff --git a/database/schema/patch-2210-31-0.sql b/database/schema/archive/patch-2210-31-0.sql
similarity index 100%
rename from database/schema/patch-2210-31-0.sql
rename to database/schema/archive/patch-2210-31-0.sql
diff --git a/database/schema/patch-2210-32-0.sql b/database/schema/archive/patch-2210-32-0.sql
similarity index 100%
rename from database/schema/patch-2210-32-0.sql
rename to database/schema/archive/patch-2210-32-0.sql
diff --git a/database/schema/patch-2210-33-0.sql b/database/schema/archive/patch-2210-33-0.sql
similarity index 100%
rename from database/schema/patch-2210-33-0.sql
rename to database/schema/archive/patch-2210-33-0.sql
diff --git a/database/schema/patch-2210-33-1.sql b/database/schema/archive/patch-2210-33-1.sql
similarity index 100%
rename from database/schema/patch-2210-33-1.sql
rename to database/schema/archive/patch-2210-33-1.sql
diff --git a/database/schema/patch-2210-33-2.sql b/database/schema/archive/patch-2210-33-2.sql
similarity index 100%
rename from database/schema/patch-2210-33-2.sql
rename to database/schema/archive/patch-2210-33-2.sql
diff --git a/database/schema/patch-2210-34-0.sql b/database/schema/archive/patch-2210-34-0.sql
similarity index 100%
rename from database/schema/patch-2210-34-0.sql
rename to database/schema/archive/patch-2210-34-0.sql
diff --git a/database/schema/patch-2210-34-1.sql b/database/schema/archive/patch-2210-34-1.sql
similarity index 100%
rename from database/schema/patch-2210-34-1.sql
rename to database/schema/archive/patch-2210-34-1.sql
diff --git a/database/schema/patch-2210-35-0.sql b/database/schema/archive/patch-2210-35-0.sql
similarity index 100%
rename from database/schema/patch-2210-35-0.sql
rename to database/schema/archive/patch-2210-35-0.sql
diff --git a/database/schema/patch-2210-35-1.sql b/database/schema/archive/patch-2210-35-1.sql
similarity index 100%
rename from database/schema/patch-2210-35-1.sql
rename to database/schema/archive/patch-2210-35-1.sql
diff --git a/database/schema/patch-2210-36-0.sql b/database/schema/archive/patch-2210-36-0.sql
similarity index 100%
rename from database/schema/patch-2210-36-0.sql
rename to database/schema/archive/patch-2210-36-0.sql
diff --git a/database/schema/patch-2210-37-0.sql b/database/schema/archive/patch-2210-37-0.sql
similarity index 100%
rename from database/schema/patch-2210-37-0.sql
rename to database/schema/archive/patch-2210-37-0.sql
diff --git a/database/schema/patch-2210-37-1.sql b/database/schema/archive/patch-2210-37-1.sql
similarity index 100%
rename from database/schema/patch-2210-37-1.sql
rename to database/schema/archive/patch-2210-37-1.sql
diff --git a/database/schema/patch-2210-38-0.sql b/database/schema/archive/patch-2210-38-0.sql
similarity index 100%
rename from database/schema/patch-2210-38-0.sql
rename to database/schema/archive/patch-2210-38-0.sql
diff --git a/database/schema/patch-2210-38-1.sql b/database/schema/archive/patch-2210-38-1.sql
similarity index 100%
rename from database/schema/patch-2210-38-1.sql
rename to database/schema/archive/patch-2210-38-1.sql
diff --git a/database/schema/patch-2210-39-0.sql b/database/schema/archive/patch-2210-39-0.sql
similarity index 100%
rename from database/schema/patch-2210-39-0.sql
rename to database/schema/archive/patch-2210-39-0.sql
diff --git a/database/schema/patch-2210-39-1.sql b/database/schema/archive/patch-2210-39-1.sql
similarity index 100%
rename from database/schema/patch-2210-39-1.sql
rename to database/schema/archive/patch-2210-39-1.sql
diff --git a/database/schema/patch-2210-39-2.sql b/database/schema/archive/patch-2210-39-2.sql
similarity index 100%
rename from database/schema/patch-2210-39-2.sql
rename to database/schema/archive/patch-2210-39-2.sql
diff --git a/database/schema/patch-2210-40-0.sql b/database/schema/archive/patch-2210-40-0.sql
similarity index 100%
rename from database/schema/patch-2210-40-0.sql
rename to database/schema/archive/patch-2210-40-0.sql
diff --git a/database/schema/patch-2210-40-1.sql b/database/schema/archive/patch-2210-40-1.sql
similarity index 100%
rename from database/schema/patch-2210-40-1.sql
rename to database/schema/archive/patch-2210-40-1.sql
diff --git a/database/schema/patch-2210-41-0.sql b/database/schema/archive/patch-2210-41-0.sql
similarity index 100%
rename from database/schema/patch-2210-41-0.sql
rename to database/schema/archive/patch-2210-41-0.sql
diff --git a/database/schema/patch-2210-42-0.sql b/database/schema/archive/patch-2210-42-0.sql
similarity index 100%
rename from database/schema/patch-2210-42-0.sql
rename to database/schema/archive/patch-2210-42-0.sql
diff --git a/database/schema/patch-2210-43-0.sql b/database/schema/archive/patch-2210-43-0.sql
similarity index 100%
rename from database/schema/patch-2210-43-0.sql
rename to database/schema/archive/patch-2210-43-0.sql
diff --git a/database/schema/patch-2210-44-0.sql b/database/schema/archive/patch-2210-44-0.sql
similarity index 100%
rename from database/schema/patch-2210-44-0.sql
rename to database/schema/archive/patch-2210-44-0.sql
diff --git a/database/schema/patch-2210-44-1.sql b/database/schema/archive/patch-2210-44-1.sql
similarity index 100%
rename from database/schema/patch-2210-44-1.sql
rename to database/schema/archive/patch-2210-44-1.sql
diff --git a/database/schema/patch-2210-44-2.sql b/database/schema/archive/patch-2210-44-2.sql
similarity index 100%
rename from database/schema/patch-2210-44-2.sql
rename to database/schema/archive/patch-2210-44-2.sql
diff --git a/database/schema/patch-2210-44-3.sql b/database/schema/archive/patch-2210-44-3.sql
similarity index 100%
rename from database/schema/patch-2210-44-3.sql
rename to database/schema/archive/patch-2210-44-3.sql
diff --git a/database/schema/patch-2210-44-4.sql b/database/schema/archive/patch-2210-44-4.sql
similarity index 100%
rename from database/schema/patch-2210-44-4.sql
rename to database/schema/archive/patch-2210-44-4.sql
diff --git a/database/schema/patch-2210-45-0.sql b/database/schema/archive/patch-2210-45-0.sql
similarity index 100%
rename from database/schema/patch-2210-45-0.sql
rename to database/schema/archive/patch-2210-45-0.sql
diff --git a/database/schema/patch-2210-46-0.sql b/database/schema/archive/patch-2210-46-0.sql
similarity index 100%
rename from database/schema/patch-2210-46-0.sql
rename to database/schema/archive/patch-2210-46-0.sql
diff --git a/database/schema/patch-2210-47-0.sql b/database/schema/archive/patch-2210-47-0.sql
similarity index 100%
rename from database/schema/patch-2210-47-0.sql
rename to database/schema/archive/patch-2210-47-0.sql
diff --git a/database/schema/patch-2210-48-0.sql b/database/schema/archive/patch-2210-48-0.sql
similarity index 100%
rename from database/schema/patch-2210-48-0.sql
rename to database/schema/archive/patch-2210-48-0.sql
diff --git a/database/schema/comments.sql b/database/schema/comments.sql
index 463936b..fb8dfcc 100644
--- a/database/schema/comments.sql
+++ b/database/schema/comments.sql
@@ -1934,7 +1934,7 @@ COMMENT ON COLUMN ArchiveAuthToken.date_deactivated IS 'The date and time this t
 COMMENT ON COLUMN ArchiveAuthToken.token IS 'The token text for this authorisation.';
 
 -- ArchiveDependency
-COMMENT ON TABLE ArchiveDependency IS 'This table maps a given archive to all other archives it should depend on.';
+COMMENT ON TABLE ArchiveDependency IS 'This table maps a given parent (archive or snap base) to all other archives it should depend on.';
 COMMENT ON COLUMN ArchiveDependency.date_created IS 'Instant when the dependency was created.';
 COMMENT ON COLUMN ArchiveDependency.archive IS 'The archive where the dependency should be applied.';
 COMMENT ON COLUMN ArchiveDependency.dependency IS 'The archive to depend on.';
diff --git a/database/schema/launchpad-2210-00-0.sql b/database/schema/launchpad-2211-00-0.sql
similarity index 80%
rename from database/schema/launchpad-2210-00-0.sql
rename to database/schema/launchpad-2211-00-0.sql
index e67c136..7b367be 100644
--- a/database/schema/launchpad-2210-00-0.sql
+++ b/database/schema/launchpad-2211-00-0.sql
@@ -1,14 +1,16 @@
--- Generated Mon Feb 25 21:35:23 2019 UTC
+-- Generated Thu Jul 14 23:32:59 2022 UTC
 
 SET client_min_messages TO ERROR;
 SET statement_timeout = 0;
 SET lock_timeout = 0;
+SET idle_in_transaction_session_timeout = 0;
 SET client_encoding = 'UTF8';
 SET standard_conforming_strings = off;
 SELECT pg_catalog.set_config('search_path', '', false);
 SET check_function_bodies = false;
 SET client_min_messages = warning;
 SET escape_string_warning = off;
+SET row_security = off;
 
 CREATE SCHEMA todrop;
 
@@ -22,10 +24,10 @@ CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
 COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
 
 
-CREATE EXTENSION IF NOT EXISTS plpythonu WITH SCHEMA pg_catalog;
+CREATE EXTENSION IF NOT EXISTS plpython3u WITH SCHEMA pg_catalog;
 
 
-COMMENT ON EXTENSION plpythonu IS 'PL/PythonU untrusted procedural language';
+COMMENT ON EXTENSION plpython3u IS 'PL/Python3U untrusted procedural language';
 
 
 CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA trgm;
@@ -40,6 +42,56 @@ CREATE EXTENSION IF NOT EXISTS pgstattuple WITH SCHEMA public;
 COMMENT ON EXTENSION pgstattuple IS 'show tuple-level statistics';
 
 
+CREATE DOMAIN public.ts2_tsvector AS tsvector;
+
+
+SET default_tablespace = '';
+
+SET default_with_oids = false;
+
+CREATE TABLE public.bugtaskflat (
+    bugtask integer NOT NULL,
+    bug integer NOT NULL,
+    datecreated timestamp without time zone,
+    duplicateof integer,
+    bug_owner integer NOT NULL,
+    fti public.ts2_tsvector,
+    information_type integer NOT NULL,
+    date_last_updated timestamp without time zone NOT NULL,
+    heat integer NOT NULL,
+    product integer,
+    productseries integer,
+    distribution integer,
+    distroseries integer,
+    sourcepackagename integer,
+    status integer NOT NULL,
+    importance integer NOT NULL,
+    assignee integer,
+    milestone integer,
+    owner integer NOT NULL,
+    active boolean NOT NULL,
+    access_policies integer[],
+    access_grants integer[],
+    latest_patch_uploaded timestamp without time zone,
+    date_closed timestamp without time zone,
+    ociproject integer,
+    ociprojectseries integer
+);
+
+
+CREATE TYPE public.bugsummary_temp_btf_internal AS (
+	btf public.bugtaskflat,
+	count integer
+);
+
+
+CREATE TYPE public.bugsummary_temp_bug_internal AS (
+	bug integer,
+	tags text[],
+	count integer
+);
+
+
 CREATE TYPE public.debversion;
 
 
@@ -91,21 +143,17 @@ CREATE TYPE public.pgstattuple_type AS (
 );
 
 
-CREATE DOMAIN public.ts2_tsvector AS tsvector;
-
-
 CREATE FUNCTION public._ftq(text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
         import re
 
         # I think this method would be more robust if we used a real
         # tokenizer and parser to generate the query string, but we need
         # something suitable for use as a stored procedure which currently
-        # means no external dependancies.
+        # means no external dependencies.
 
-        # Convert to Unicode
-        query = args[0].decode('utf8')
+        query = args[0]
         ## plpy.debug('1 query is %s' % repr(query))
 
         # Replace tsquery operators with ' '. '<' begins all the phrase
@@ -113,19 +161,19 @@ CREATE FUNCTION public._ftq(text) RETURNS text
         query = re.sub('[|&!<]', ' ', query)
 
         # Normalize whitespace
-        query = re.sub("(?u)\s+"," ", query)
+        query = re.sub("\s+"," ", query)
 
         # Convert AND, OR, NOT to tsearch2 punctuation
-        query = re.sub(r"(?u)\bAND\b", "&", query)
-        query = re.sub(r"(?u)\bOR\b", "|", query)
-        query = re.sub(r"(?u)\bNOT\b", " !", query)
+        query = re.sub(r"\bAND\b", "&", query)
+        query = re.sub(r"\bOR\b", "|", query)
+        query = re.sub(r"\bNOT\b", " !", query)
         ## plpy.debug('2 query is %s' % repr(query))
 
         # Deal with unwanted punctuation.
         # ':' is used in queries to specify a weight of a word.
         # '\' is treated differently in to_tsvector() and to_tsquery().
         punctuation = r'[:\\]'
-        query = re.sub(r"(?u)%s+" % (punctuation,), " ", query)
+        query = re.sub(r"%s+" % (punctuation,), " ", query)
         ## plpy.debug('3 query is %s' % repr(query))
 
         # Now that we have handle case sensitive booleans, convert to lowercase
@@ -136,18 +184,18 @@ CREATE FUNCTION public._ftq(text) RETURNS text
         query = re.sub(r"(?ux) \( ( [^)]* ) $", r"(\1)", query)
 
         # Remove spurious brackets
-        query = re.sub(r"(?u)\(([^\&\|]*?)\)", r" \1 ", query)
+        query = re.sub(r"\(([^\&\|]*?)\)", r" \1 ", query)
         ## plpy.debug('5 query is %s' % repr(query))
 
         # Insert & between tokens without an existing boolean operator
         # ( not proceeded by (|&!
-        query = re.sub(r"(?u)(?<![\(\|\&\!])\s*\(", "&(", query)
+        query = re.sub(r"(?<![\(\|\&\!])\s*\(", "&(", query)
         ## plpy.debug('6 query is %s' % repr(query))
         # ) not followed by )|&
-        query = re.sub(r"(?u)\)(?!\s*(\)|\||\&|\s*$))", ")&", query)
+        query = re.sub(r"\)(?!\s*(\)|\||\&|\s*$))", ")&", query)
         ## plpy.debug('6.1 query is %s' % repr(query))
         # Whitespace not proceded by (|&! not followed by &|
-        query = re.sub(r"(?u)(?<![\(\|\&\!\s])\s+(?![\&\|\s])", "&", query)
+        query = re.sub(r"(?<![\(\|\&\!\s])\s+(?![\&\|\s])", "&", query)
         ## plpy.debug('7 query is %s' % repr(query))
 
         # Detect and repair syntax errors - we are lenient because
@@ -163,21 +211,21 @@ CREATE FUNCTION public._ftq(text) RETURNS text
         ## plpy.debug('8 query is %s' % repr(query))
 
         # Strip ' character that do not have letters on both sides
-        query = re.sub(r"(?u)((?<!\w)'|'(?!\w))", "", query)
+        query = re.sub(r"((?<!\w)'|'(?!\w))", "", query)
 
         # Brackets containing nothing but whitespace and booleans, recursive
         last = ""
         while last != query:
             last = query
-            query = re.sub(r"(?u)\([\s\&\|\!]*\)", "", query)
+            query = re.sub(r"\([\s\&\|\!]*\)", "", query)
         ## plpy.debug('9 query is %s' % repr(query))
 
         # An & or | following a (
-        query = re.sub(r"(?u)(?<=\()[\&\|\s]+", "", query)
+        query = re.sub(r"(?<=\()[\&\|\s]+", "", query)
         ## plpy.debug('10 query is %s' % repr(query))
 
         # An &, | or ! immediatly before a )
-        query = re.sub(r"(?u)[\&\|\!\s]*[\&\|\!]+\s*(?=\))", "", query)
+        query = re.sub(r"[\&\|\!\s]*[\&\|\!]+\s*(?=\))", "", query)
         ## plpy.debug('11 query is %s' % repr(query))
 
         # An &,| or ! followed by another boolean.
@@ -185,20 +233,18 @@ CREATE FUNCTION public._ftq(text) RETURNS text
         ## plpy.debug('12 query is %s' % repr(query))
 
         # Leading & or |
-        query = re.sub(r"(?u)^[\s\&\|]+", "", query)
+        query = re.sub(r"^[\s\&\|]+", "", query)
         ## plpy.debug('13 query is %s' % repr(query))
 
         # Trailing &, | or !
-        query = re.sub(r"(?u)[\&\|\!\s]+$", "", query)
+        query = re.sub(r"[\&\|\!\s]+$", "", query)
         ## plpy.debug('14 query is %s' % repr(query))
 
         # If we have nothing but whitespace and tsearch2 operators,
         # return NULL.
-        if re.search(r"(?u)^[\&\|\!\s\(\)]*$", query) is not None:
+        if re.search(r"^[\&\|\!\s\(\)]*$", query) is not None:
             return None
 
-        # Convert back to UTF-8
-        query = query.encode('utf8')
         ## plpy.debug('15 query is %s' % repr(query))
 
         return query or None
@@ -221,15 +267,21 @@ BEGIN
     IF artifact_row.gitrepository IS NOT NULL THEN
         PERFORM gitrepository_denorm_access(artifact_row.gitrepository);
     END IF;
+    IF artifact_row.snap IS NOT NULL THEN
+        PERFORM snap_denorm_access(artifact_row.snap);
+    END IF;
     IF artifact_row.specification IS NOT NULL THEN
         PERFORM specification_denorm_access(artifact_row.specification);
     END IF;
+    IF artifact_row.ocirecipe IS NOT NULL THEN
+        PERFORM ocirecipe_denorm_access(artifact_row.ocirecipe);
+    END IF;
     RETURN;
 END;
 $$;
 
 
-COMMENT ON FUNCTION public.accessartifact_denorm_to_artifacts(artifact_id integer) IS 'Denormalize the policy access and artifact grants to bugs, branches, Git repositories, and specifications.';
+COMMENT ON FUNCTION public.accessartifact_denorm_to_artifacts(artifact_id integer) IS 'Denormalize the policy access and artifact grants to bugs, branches, git repositories, snaps, specifications and ocirecipe.';
 
 
 CREATE FUNCTION public.accessartifact_maintain_denorm_to_artifacts_trig() RETURNS trigger
@@ -443,7 +495,7 @@ COMMENT ON FUNCTION public.add_test_openid_identifier(account_ integer) IS 'Add 
 
 
 CREATE FUNCTION public.assert_patch_applied(major integer, minor integer, patch integer) RETURNS boolean
-    LANGUAGE plpythonu STABLE
+    LANGUAGE plpython3u STABLE
     AS $$
     rv = plpy.execute("""
         SELECT * FROM LaunchpadDatabaseRevision
@@ -548,98 +600,6 @@ END;
 $$;
 
 
-CREATE FUNCTION public.valid_bug_name(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
-    AS $_$
-    import re
-    name = args[0]
-    pat = r"^[a-z][a-z0-9+\.\-]+$"
-    if re.match(pat, name):
-        return 1
-    return 0
-$_$;
-
-
-COMMENT ON FUNCTION public.valid_bug_name(text) IS 'validate a bug name
-
-    As per valid_name, except numeric-only names are not allowed (including
-    names that look like floats).';
-
-
-SET default_tablespace = '';
-
-SET default_with_oids = false;
-
-CREATE TABLE public.bug (
-    id integer NOT NULL,
-    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    name text,
-    title text NOT NULL,
-    description text NOT NULL,
-    owner integer NOT NULL,
-    duplicateof integer,
-    fti public.ts2_tsvector,
-    date_last_updated timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_made_private timestamp without time zone,
-    who_made_private integer,
-    date_last_message timestamp without time zone,
-    number_of_duplicates integer DEFAULT 0 NOT NULL,
-    message_count integer DEFAULT 0 NOT NULL,
-    users_affected_count integer DEFAULT 0,
-    users_unaffected_count integer DEFAULT 0,
-    heat integer DEFAULT 0 NOT NULL,
-    heat_last_updated timestamp without time zone,
-    latest_patch_uploaded timestamp without time zone,
-    information_type integer NOT NULL,
-    CONSTRAINT notduplicateofself CHECK ((NOT (id = duplicateof))),
-    CONSTRAINT sane_description CHECK (((ltrim(description) <> ''::text) AND (char_length(description) <= 50000))),
-    CONSTRAINT valid_bug_name CHECK (public.valid_bug_name(name))
-);
-
-
-COMMENT ON TABLE public.bug IS 'A software bug that requires fixing. This particular bug may be linked to one or more products or source packages to identify the location(s) that this bug is found.';
-
-
-COMMENT ON COLUMN public.bug.name IS 'A lowercase name uniquely identifying the bug';
-
-
-COMMENT ON COLUMN public.bug.description IS 'A detailed description of the bug. Initially this will be set to the contents of the initial email or bug filing comment, but later it can be edited to give a more accurate description of the bug itself rather than the symptoms observed by the reporter.';
-
-
-COMMENT ON COLUMN public.bug.date_last_message IS 'When the last BugMessage was attached to this Bug. Maintained by a trigger on the BugMessage table.';
-
-
-COMMENT ON COLUMN public.bug.number_of_duplicates IS 'The number of bugs marked as duplicates of this bug, populated by a trigger after setting the duplicateof of bugs.';
-
-
-COMMENT ON COLUMN public.bug.message_count IS 'The number of messages (currently just comments) on this bugbug, maintained by the set_bug_message_count_t trigger.';
-
-
-COMMENT ON COLUMN public.bug.users_affected_count IS 'The number of users affected by this bug, maintained by the set_bug_users_affected_count_t trigger.';
-
-
-COMMENT ON COLUMN public.bug.heat IS 'The relevance of this bug. This value is computed periodically using bug_affects_person and other bug values.';
-
-
-COMMENT ON COLUMN public.bug.heat_last_updated IS 'The time this bug''s heat was last updated, or NULL if the heat has never yet been updated.';
-
-
-COMMENT ON COLUMN public.bug.latest_patch_uploaded IS 'The time when the most recent patch has been attached to this bug or NULL if no patches are attached';
-
-
-COMMENT ON COLUMN public.bug.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
-
-
-CREATE FUNCTION public.bug_row(bug_id integer) RETURNS public.bug
-    LANGUAGE sql STABLE
-    AS $_$
-    SELECT * FROM Bug WHERE id=$1;
-$_$;
-
-
-COMMENT ON FUNCTION public.bug_row(bug_id integer) IS 'Helper for manually testing functions requiring a bug row as input. eg. SELECT * FROM bugsummary_tags(bug_row(1))';
-
-
 CREATE TABLE public.bugsummary (
     id integer NOT NULL,
     count integer DEFAULT 0 NOT NULL,
@@ -655,12 +615,16 @@ CREATE TABLE public.bugsummary (
     importance integer NOT NULL,
     has_patch boolean NOT NULL,
     access_policy integer,
+    ociproject integer,
+    ociprojectseries integer,
     CONSTRAINT bugtask_assignment_checks CHECK (
 CASE
-    WHEN (product IS NOT NULL) THEN ((((productseries IS NULL) AND (distribution IS NULL)) AND (distroseries IS NULL)) AND (sourcepackagename IS NULL))
-    WHEN (productseries IS NOT NULL) THEN (((distribution IS NULL) AND (distroseries IS NULL)) AND (sourcepackagename IS NULL))
+    WHEN (product IS NOT NULL) THEN ((productseries IS NULL) AND (distribution IS NULL) AND (distroseries IS NULL) AND (sourcepackagename IS NULL))
+    WHEN (productseries IS NOT NULL) THEN ((distribution IS NULL) AND (distroseries IS NULL) AND (sourcepackagename IS NULL) AND (ociproject IS NULL) AND (ociprojectseries IS NULL))
     WHEN (distribution IS NOT NULL) THEN (distroseries IS NULL)
-    WHEN (distroseries IS NOT NULL) THEN true
+    WHEN (distroseries IS NOT NULL) THEN ((ociproject IS NULL) AND (ociprojectseries IS NULL))
+    WHEN (ociproject IS NOT NULL) THEN ((ociprojectseries IS NULL) AND ((distribution IS NOT NULL) OR (product IS NOT NULL)) AND (sourcepackagename IS NULL))
+    WHEN (ociprojectseries IS NOT NULL) THEN ((ociproject IS NULL) AND ((distribution IS NOT NULL) OR (product IS NOT NULL)) AND (sourcepackagename IS NULL))
     ELSE false
 END)
 );
@@ -708,39 +672,6 @@ $_$;
 COMMENT ON FUNCTION public.bug_summary_dec(public.bugsummary) IS 'UPSERT into bugsummary incrementing one row';
 
 
-CREATE FUNCTION public.bug_summary_flush_temp_journal() RETURNS void
-    LANGUAGE plpgsql
-    AS $$
-DECLARE
-    d bugsummary%ROWTYPE;
-BEGIN
-    -- May get called even though no summaries were made (for simplicity in the
-    -- callers). We sum the rows here to minimise the number of inserts
-    -- into the persistent journal, as it's reasonably likely that we'll
-    -- have -1s and +1s cancelling each other out.
-    PERFORM ensure_bugsummary_temp_journal();
-    INSERT INTO BugSummaryJournal(
-        count, product, productseries, distribution,
-        distroseries, sourcepackagename, viewed_by, tag,
-        status, milestone, importance, has_patch, access_policy)
-    SELECT
-        SUM(count), product, productseries, distribution,
-        distroseries, sourcepackagename, viewed_by, tag,
-        status, milestone, importance, has_patch, access_policy
-    FROM bugsummary_temp_journal
-    GROUP BY
-        product, productseries, distribution,
-        distroseries, sourcepackagename, viewed_by, tag,
-        status, milestone, importance, has_patch, access_policy
-    HAVING SUM(count) != 0;
-    TRUNCATE bugsummary_temp_journal;
-END;
-$$;
-
-
-COMMENT ON FUNCTION public.bug_summary_flush_temp_journal() IS 'flush the temporary bugsummary journal into the bugsummary table';
-
-
 CREATE FUNCTION public.bug_summary_inc(d public.bugsummary) RETURNS void
     LANGUAGE plpgsql
     AS $_$
@@ -750,20 +681,15 @@ BEGIN
         -- first try to update the row
         UPDATE BugSummary SET count = count + d.count
         WHERE
-            ((product IS NULL AND $1.product IS NULL)
-                OR product = $1.product)
-            AND ((productseries IS NULL AND $1.productseries IS NULL)
-                OR productseries = $1.productseries)
-            AND ((distribution IS NULL AND $1.distribution IS NULL)
-                OR distribution = $1.distribution)
-            AND ((distroseries IS NULL AND $1.distroseries IS NULL)
-                OR distroseries = $1.distroseries)
-            AND ((sourcepackagename IS NULL AND $1.sourcepackagename IS NULL)
-                OR sourcepackagename = $1.sourcepackagename)
-            AND ((viewed_by IS NULL AND $1.viewed_by IS NULL)
-                OR viewed_by = $1.viewed_by)
-            AND ((tag IS NULL AND $1.tag IS NULL)
-                OR tag = $1.tag)
+            product IS NOT DISTINCT FROM $1.product
+            AND productseries IS NOT DISTINCT FROM $1.productseries
+            AND distribution IS NOT DISTINCT FROM $1.distribution
+            AND distroseries IS NOT DISTINCT FROM $1.distroseries
+            AND sourcepackagename IS NOT DISTINCT FROM $1.sourcepackagename
+            AND ociproject IS NOT DISTINCT FROM $1.ociproject
+            AND ociprojectseries IS NOT DISTINCT FROM $1.ociprojectseries
+            AND viewed_by IS NOT DISTINCT FROM $1.viewed_by
+            AND tag IS NOT DISTINCT FROM $1.tag
             AND status = $1.status
             AND ((milestone IS NULL AND $1.milestone IS NULL)
                 OR milestone = $1.milestone)
@@ -779,11 +705,15 @@ BEGIN
         BEGIN
             INSERT INTO BugSummary(
                 count, product, productseries, distribution,
-                distroseries, sourcepackagename, viewed_by, tag,
+                distroseries, sourcepackagename,
+                ociproject, ociprojectseries,
+                viewed_by, tag,
                 status, milestone, importance, has_patch, access_policy)
             VALUES (
                 d.count, d.product, d.productseries, d.distribution,
-                d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
+                d.distroseries, d.sourcepackagename,
+                d.ociproject, d.ociprojectseries,
+                d.viewed_by, d.tag,
                 d.status, d.milestone, d.importance, d.has_patch,
                 d.access_policy);
             RETURN;
@@ -864,67 +794,53 @@ $$;
 COMMENT ON FUNCTION public.bugmessage_copy_owner_from_message() IS 'Copies the message owner into bugmessage when bugmessage changes.';
 
 
-CREATE FUNCTION public.bugsummary_journal_bug(bug_row public.bug, _count integer) RETURNS void
-    LANGUAGE plpgsql
-    AS $$
-DECLARE
-    btf_row bugtaskflat%ROWTYPE;
-BEGIN
-    FOR btf_row IN SELECT * FROM bugtaskflat WHERE bug = bug_row.id
-    LOOP
-        PERFORM bugsummary_journal_bugtaskflat(btf_row, _count);
-    END LOOP;
-END;
-$$;
-
-
-CREATE TABLE public.bugtaskflat (
-    bugtask integer NOT NULL,
-    bug integer NOT NULL,
-    datecreated timestamp without time zone,
-    duplicateof integer,
-    bug_owner integer NOT NULL,
-    fti public.ts2_tsvector,
-    information_type integer NOT NULL,
-    date_last_updated timestamp without time zone NOT NULL,
-    heat integer NOT NULL,
+CREATE TABLE public.bugsummaryjournal (
+    id integer NOT NULL,
+    count integer DEFAULT 0 NOT NULL,
     product integer,
     productseries integer,
     distribution integer,
     distroseries integer,
     sourcepackagename integer,
+    viewed_by integer,
+    tag text,
     status integer NOT NULL,
-    importance integer NOT NULL,
-    assignee integer,
     milestone integer,
-    owner integer NOT NULL,
-    active boolean NOT NULL,
-    access_policies integer[],
-    access_grants integer[],
-    latest_patch_uploaded timestamp without time zone,
-    date_closed timestamp without time zone
+    importance integer NOT NULL,
+    has_patch boolean NOT NULL,
+    access_policy integer,
+    ociproject integer,
+    ociprojectseries integer
 );
 
 
-CREATE FUNCTION public.bugsummary_journal_bugtaskflat(btf_row public.bugtaskflat, _count integer) RETURNS void
-    LANGUAGE plpgsql
+CREATE FUNCTION public.bugsummary_insert_journals(journals public.bugsummaryjournal[]) RETURNS void
+    LANGUAGE sql
     AS $$
-BEGIN
-    PERFORM ensure_bugsummary_temp_journal();
-    INSERT INTO BugSummary_Temp_Journal(
-        count, product, productseries, distribution,
-        distroseries, sourcepackagename, viewed_by, tag,
-        status, milestone, importance, has_patch, access_policy)
-    SELECT
-        _count, product, productseries, distribution,
-        distroseries, sourcepackagename, viewed_by, tag,
-        status, milestone, importance, has_patch, access_policy
-        FROM bugsummary_locations(btf_row);
-END;
+    -- We sum the rows here to minimise the number of inserts into the
+    -- journal, as in the case of UPDATE statement we may have -1s and +1s
+    -- cancelling each other out.
+    INSERT INTO BugSummaryJournal(
+            count, product, productseries, distribution,
+            distroseries, sourcepackagename, ociproject, ociprojectseries,
+            viewed_by, tag, status, milestone, importance, has_patch,
+            access_policy)
+        SELECT
+            SUM(count), product, productseries, distribution,
+            distroseries, sourcepackagename, ociproject, ociprojectseries,
+            viewed_by, tag, status, milestone, importance, has_patch,
+            access_policy
+        FROM unnest(journals)
+        GROUP BY
+            product, productseries, distribution,
+            distroseries, sourcepackagename, ociproject, ociprojectseries,
+            viewed_by, tag, status, milestone, importance, has_patch,
+            access_policy
+        HAVING SUM(count) != 0;
 $$;
 
 
-CREATE FUNCTION public.bugsummary_locations(btf_row public.bugtaskflat) RETURNS SETOF public.bugsummary
+CREATE FUNCTION public.bugsummary_locations(btf_row public.bugtaskflat, tags text[]) RETURNS SETOF public.bugsummaryjournal
     LANGUAGE plpgsql
     AS $$
 BEGIN
@@ -941,10 +857,11 @@ BEGIN
             bug_viewers.viewed_by, bug_tags.tag, btf_row.status,
             btf_row.milestone, btf_row.importance,
             btf_row.latest_patch_uploaded IS NOT NULL AS has_patch,
-            bug_viewers.access_policy
+            bug_viewers.access_policy,
+            bug_targets.ociproject, bug_targets.ociprojectseries
         FROM
-            bugsummary_targets(btf_row) as bug_targets,
-            bugsummary_tags(btf_row) AS bug_tags,
+            bugsummary_targets(btf_row) AS bug_targets,
+            unnest(tags) AS bug_tags (tag),
             bugsummary_viewers(btf_row) AS bug_viewers;
 END;
 $$;
@@ -987,12 +904,15 @@ BEGIN
             milestone,
             importance,
             has_patch,
-            access_policy
+            access_policy,
+            ociproject,
+            ociprojectseries
         FROM BugSummaryJournal
         WHERE id <= max_id
         GROUP BY
             product, productseries, distribution, distroseries,
-            sourcepackagename, viewed_by, tag, status, milestone,
+            sourcepackagename, ociproject, ociprojectseries,
+            viewed_by, tag, status, milestone,
             importance, has_patch, access_policy
         HAVING sum(count) <> 0
     LOOP
@@ -1014,68 +934,20 @@ $$;
 COMMENT ON FUNCTION public.bugsummary_rollup_journal(batchsize integer) IS 'Collate and migrate rows from BugSummaryJournal to BugSummary';
 
 
-CREATE FUNCTION public.valid_name(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
-    AS $$
-    import re
-    name = args[0]
-    pat = r"^[a-z0-9][a-z0-9\+\.\-]*\Z"
-    if re.match(pat, name):
-        return 1
-    return 0
-$$;
-
-
-COMMENT ON FUNCTION public.valid_name(text) IS 'validate a name.
-
-    Names must contain only lowercase letters, numbers, ., & -. They
-    must start with an alphanumeric. They are ASCII only. Names are useful
-    for mneumonic identifiers such as nicknames and as URL components.
-    This specification is the same as the Debian product naming policy.
-
-    Note that a valid name might be all integers, so there is a possible
-    namespace conflict if URL traversal is possible by name as well as id.';
-
-
-CREATE TABLE public.bugtag (
-    id integer NOT NULL,
-    bug integer NOT NULL,
-    tag text NOT NULL,
-    CONSTRAINT valid_tag CHECK (public.valid_name(tag))
-);
-
-
-COMMENT ON TABLE public.bugtag IS 'Attaches simple text tags to a bug.';
-
-
-COMMENT ON COLUMN public.bugtag.bug IS 'The bug the tags is attached to.';
-
-
-COMMENT ON COLUMN public.bugtag.tag IS 'The text representation of the tag.';
-
-
-CREATE FUNCTION public.bugsummary_tags(btf_row public.bugtaskflat) RETURNS SETOF public.bugtag
-    LANGUAGE sql STABLE
-    AS $_$
-    SELECT * FROM BugTag WHERE BugTag.bug = $1.bug
-    UNION ALL
-    SELECT NULL::integer, $1.bug, NULL::text;
-$_$;
-
-
-CREATE FUNCTION public.bugsummary_targets(btf_row public.bugtaskflat) RETURNS TABLE(product integer, productseries integer, distribution integer, distroseries integer, sourcepackagename integer)
+CREATE FUNCTION public.bugsummary_targets(btf_row public.bugtaskflat) RETURNS TABLE(product integer, productseries integer, distribution integer, distroseries integer, sourcepackagename integer, ociproject integer, ociprojectseries integer)
     LANGUAGE sql IMMUTABLE
     AS $_$
-    -- Include a sourcepackagename-free task if this one has a
-    -- sourcepackagename, so package tasks are also counted in their
-    -- distro/series.
+    -- Include a sourcepackagename-free/ociproject(series)-free task if this
+    -- one has a sourcepackagename/ociproject(series), so package tasks are
+    -- also counted in their distro/series.
     SELECT
         $1.product, $1.productseries, $1.distribution,
-        $1.distroseries, $1.sourcepackagename
+        $1.distroseries, $1.sourcepackagename,
+        $1.ociproject, $1.ociprojectseries
     UNION -- Implicit DISTINCT
     SELECT
         $1.product, $1.productseries, $1.distribution,
-        $1.distroseries, NULL;
+        $1.distroseries, NULL, NULL, NULL;
 $_$;
 
 
@@ -1096,38 +968,50 @@ CREATE FUNCTION public.bugtag_maintain_bug_summary() RETURNS trigger
     LANGUAGE plpgsql SECURITY DEFINER
     SET search_path TO 'public'
     AS $$
+DECLARE
+    all_rows bugsummary_temp_bug_internal[];
+    temp_rows bugsummary_temp_bug_internal[];
+    journals bugsummaryjournal[];
+    temp_rec record;
+    temp_journal bugsummaryjournal;
 BEGIN
-    IF TG_OP = 'INSERT' THEN
-        IF TG_WHEN = 'BEFORE' THEN
-            PERFORM unsummarise_bug(NEW.bug);
-        ELSE
-            PERFORM summarise_bug(NEW.bug);
-        END IF;
-        PERFORM bug_summary_flush_temp_journal();
-        RETURN NEW;
-    ELSIF TG_OP = 'DELETE' THEN
-        IF TG_WHEN = 'BEFORE' THEN
-            PERFORM unsummarise_bug(OLD.bug);
-        ELSE
-            PERFORM summarise_bug(OLD.bug);
-        END IF;
-        PERFORM bug_summary_flush_temp_journal();
-        RETURN OLD;
-    ELSE
-        IF TG_WHEN = 'BEFORE' THEN
-            PERFORM unsummarise_bug(OLD.bug);
-            IF OLD.bug <> NEW.bug THEN
-                PERFORM unsummarise_bug(NEW.bug);
-            END IF;
-        ELSE
-            PERFORM summarise_bug(OLD.bug);
-            IF OLD.bug <> NEW.bug THEN
-                PERFORM summarise_bug(NEW.bug);
-            END IF;
-        END IF;
-        PERFORM bug_summary_flush_temp_journal();
-        RETURN NEW;
+    -- Work out the subqueries we need to compute the set of
+    -- BugSummaryJournal rows that should be inserted.
+    IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
+        SELECT array_agg(
+            (SELECT row(bug, array_agg(tag), -1) FROM old_bugtag GROUP BY bug))
+            INTO STRICT temp_rows;
+        all_rows := array_cat(all_rows, temp_rows);
     END IF;
+    IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
+        SELECT array_agg(
+            (SELECT row(bug, array_agg(tag), 1) FROM new_bugtag GROUP BY bug))
+            INTO STRICT temp_rows;
+        all_rows := array_cat(all_rows, temp_rows);
+    END IF;
+
+    -- XXX wgrant 2020-02-07: "The target is a record variable, row
+    -- variable, or comma-separated list of scalar variables." but a list
+    -- doesn't seem to work.
+    FOR temp_rec IN
+        SELECT journal, row.count
+        FROM
+            unnest(all_rows) as row,
+            LATERAL (
+                SELECT journal.*
+                FROM
+                    bugtaskflat btf,
+                    bugsummary_locations(btf, row.tags) AS journal
+                WHERE btf.bug = row.bug
+            ) AS journal
+    LOOP
+        temp_journal := temp_rec.journal;
+        temp_journal.count := temp_rec.count;
+        journals := array_append(journals, temp_journal);
+    END LOOP;
+
+    PERFORM bugsummary_insert_journals(journals);
+    RETURN NULL;
 END;
 $$;
 
@@ -1199,7 +1083,8 @@ BEGIN
            COALESCE(_product_active, TRUE),
            _access_policies,
            _access_grants,
-           bug_row.latest_patch_uploaded, task_row.date_closed
+           bug_row.latest_patch_uploaded, task_row.date_closed,
+           task_row.ociproject, task_row.ociprojectseries
            INTO new_flat_row;
 
     -- Calculate the necessary updates.
@@ -1233,7 +1118,9 @@ BEGIN
                 access_policies = new_flat_row.access_policies,
                 access_grants = new_flat_row.access_grants,
                 date_closed = new_flat_row.date_closed,
-                latest_patch_uploaded = new_flat_row.latest_patch_uploaded
+                latest_patch_uploaded = new_flat_row.latest_patch_uploaded,
+                ociproject = new_flat_row.ociproject,
+                ociprojectseries = new_flat_row.ociprojectseries
                 WHERE bugtask = new_flat_row.bugtask;
         END IF;
         RETURN FALSE;
@@ -1268,6 +1155,8 @@ BEGIN
             OR NEW.distribution IS DISTINCT FROM OLD.distribution
             OR NEW.distroseries IS DISTINCT FROM OLD.distroseries
             OR NEW.sourcepackagename IS DISTINCT FROM OLD.sourcepackagename
+            OR NEW.ociproject IS DISTINCT FROM OLD.ociproject
+            OR NEW.ociprojectseries IS DISTINCT FROM OLD.ociprojectseries
             OR NEW.status IS DISTINCT FROM OLD.status
             OR NEW.importance IS DISTINCT FROM OLD.importance
             OR NEW.assignee IS DISTINCT FROM OLD.assignee
@@ -1285,6 +1174,8 @@ BEGIN
                 distribution = NEW.distribution,
                 distroseries = NEW.distroseries,
                 sourcepackagename = NEW.sourcepackagename,
+                ociproject = NEW.ociproject,
+                ociprojectseries = NEW.ociprojectseries,
                 status = NEW.status,
                 importance = NEW.importance,
                 assignee = NEW.assignee,
@@ -1305,32 +1196,44 @@ CREATE FUNCTION public.bugtaskflat_maintain_bug_summary() RETURNS trigger
     LANGUAGE plpgsql SECURITY DEFINER
     SET search_path TO 'public'
     AS $$
+DECLARE
+    all_rows bugsummary_temp_btf_internal[];
+    temp_rows bugsummary_temp_btf_internal[];
+    journals bugsummaryjournal[];
+    temp_rec record;
+    temp_journal bugsummaryjournal;
 BEGIN
-    IF TG_OP = 'INSERT' THEN
-        PERFORM bugsummary_journal_bugtaskflat(NEW, 1);
-        PERFORM bug_summary_flush_temp_journal();
-    ELSIF TG_OP = 'DELETE' THEN
-        PERFORM bugsummary_journal_bugtaskflat(OLD, -1);
-        PERFORM bug_summary_flush_temp_journal();
-    ELSIF
-        NEW.product IS DISTINCT FROM OLD.product
-        OR NEW.productseries IS DISTINCT FROM OLD.productseries
-        OR NEW.distribution IS DISTINCT FROM OLD.distribution
-        OR NEW.distroseries IS DISTINCT FROM OLD.distroseries
-        OR NEW.sourcepackagename IS DISTINCT FROM OLD.sourcepackagename
-        OR NEW.status IS DISTINCT FROM OLD.status
-        OR NEW.milestone IS DISTINCT FROM OLD.milestone
-        OR NEW.importance IS DISTINCT FROM OLD.importance
-        OR NEW.latest_patch_uploaded IS DISTINCT FROM OLD.latest_patch_uploaded
-        OR NEW.information_type IS DISTINCT FROM OLD.information_type
-        OR NEW.access_grants IS DISTINCT FROM OLD.access_grants
-        OR NEW.access_policies IS DISTINCT FROM OLD.access_policies
-        OR NEW.duplicateof IS DISTINCT FROM OLD.duplicateof
-    THEN
-        PERFORM bugsummary_journal_bugtaskflat(OLD, -1);
-        PERFORM bugsummary_journal_bugtaskflat(NEW, 1);
-        PERFORM bug_summary_flush_temp_journal();
+    -- Work out the subqueries we need to compute the set of
+    -- BugSummaryJournal rows that should be inserted.
+    IF TG_OP = 'DELETE' OR TG_OP = 'UPDATE' THEN
+        SELECT array_agg(row(old_bugtaskflat, -1))
+            INTO STRICT temp_rows FROM old_bugtaskflat;
+        all_rows := array_cat(all_rows, temp_rows);
+    END IF;
+    IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
+        SELECT array_agg(row(new_bugtaskflat, 1))
+            INTO STRICT temp_rows FROM new_bugtaskflat;
+        all_rows := array_cat(all_rows, temp_rows);
     END IF;
+
+    -- XXX wgrant 2020-02-07: "The target is a record variable, row
+    -- variable, or comma-separated list of scalar variables." but a list
+    -- doesn't seem to work.
+    FOR temp_rec IN
+        SELECT journal, row.count
+        FROM
+            unnest(all_rows) AS row,
+            LATERAL bugsummary_locations(
+                row((row.btf).*),
+                (SELECT array_append(array_agg(tag), NULL::text)
+                 FROM bugtag WHERE bug = (row.btf).bug)) AS journal
+    LOOP
+        temp_journal := temp_rec.journal;
+        temp_journal.count := temp_rec.count;
+        journals := array_append(journals, temp_journal);
+    END LOOP;
+
+    PERFORM bugsummary_insert_journals(journals);
     RETURN NULL;
 END;
 $$;
@@ -1475,7 +1378,7 @@ CREATE FUNCTION public.debversion_smaller(version1 public.debversion, version2 p
 
 
 CREATE FUNCTION public.debversion_sort_key(version text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
     # If this method is altered, then any functional indexes using it
     # need to be rebuilt.
@@ -1546,25 +1449,8 @@ $_$;
 COMMENT ON FUNCTION public.debversion_sort_key(version text) IS 'Return a string suitable for sorting debian version strings on';
 
 
-CREATE FUNCTION public.ensure_bugsummary_temp_journal() RETURNS void
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-    CREATE TEMPORARY TABLE bugsummary_temp_journal (
-        LIKE bugsummary ) ON COMMIT DROP;
-    ALTER TABLE bugsummary_temp_journal ALTER COLUMN id DROP NOT NULL;
-EXCEPTION
-    WHEN duplicate_table THEN
-        NULL;
-END;
-$$;
-
-
-COMMENT ON FUNCTION public.ensure_bugsummary_temp_journal() IS 'Create a temporary table bugsummary_temp_journal if it does not exist.';
-
-
 CREATE FUNCTION public.ftiupdate() RETURNS trigger
-    LANGUAGE plpythonu
+    LANGUAGE plpython3u
     AS $_$
     new = TD["new"]
     args = TD["args"][:]
@@ -1596,7 +1482,7 @@ CREATE FUNCTION public.ftiupdate() RETURNS trigger
     sql = "SELECT %s AS fti" % "||".join(sql)
 
     # Execute and store in the fti column
-    plan = plpy.prepare(sql, ["text", "char"] * (len(args)/2))
+    plan = plpy.prepare(sql, ["text", "char"] * (len(args) // 2))
     new["fti"] = plpy.execute(plan, args, 1)[0]["fti"]
 
     # Tell PostgreSQL we have modified the data
@@ -1608,7 +1494,7 @@ COMMENT ON FUNCTION public.ftiupdate() IS 'Trigger function that keeps the fti t
 
 
 CREATE FUNCTION public.ftq(text) RETURNS tsquery
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
         p = plpy.prepare(
             "SELECT to_tsquery('default', _ftq($1)) AS x", ["text"])
@@ -1947,7 +1833,7 @@ COMMENT ON FUNCTION public.message_copy_owner_to_questionmessage() IS 'Copies th
 
 
 CREATE FUNCTION public.milestone_sort_key(dateexpected timestamp without time zone, name text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE
+    LANGUAGE plpython3u IMMUTABLE
     AS $$
     # If this method is altered, then any functional indexes using it
     # need to be rebuilt.
@@ -1959,7 +1845,7 @@ CREATE FUNCTION public.milestone_sort_key(dateexpected timestamp without time zo
     def substitute_filled_numbers(match):
         return match.group(0).zfill(5)
 
-    name = re.sub(u'\d+', substitute_filled_numbers, name)
+    name = re.sub('\d+', substitute_filled_numbers, name)
     if date_expected is None:
         # NULL dates are considered to be in the future.
         date_expected = datetime.datetime(datetime.MAXYEAR, 1, 1)
@@ -2147,7 +2033,7 @@ COMMENT ON FUNCTION public.mv_pofiletranslator_translationmessage() IS 'Trigger 
 
 
 CREATE FUNCTION public.mv_validpersonorteamcache_emailaddress() RETURNS trigger
-    LANGUAGE plpythonu SECURITY DEFINER
+    LANGUAGE plpython3u SECURITY DEFINER
     AS $_$
     # This trigger function keeps the ValidPersonOrTeamCache materialized
     # view in sync when updates are made to the EmailAddress table.
@@ -2155,7 +2041,7 @@ CREATE FUNCTION public.mv_validpersonorteamcache_emailaddress() RETURNS trigger
     # have no effect.
     PREF = 4 # Constant indicating preferred email address
 
-    if not SD.has_key("delete_plan"):
+    if "delete_plan" not in SD:
         param_types = ["int4"]
 
         SD["is_team"] = plpy.prepare("""
@@ -2242,14 +2128,14 @@ COMMENT ON FUNCTION public.mv_validpersonorteamcache_emailaddress() IS 'A trigge
 
 
 CREATE FUNCTION public.mv_validpersonorteamcache_person() RETURNS trigger
-    LANGUAGE plpythonu SECURITY DEFINER
+    LANGUAGE plpython3u SECURITY DEFINER
     AS $_$
     # This trigger function could be simplified by simply issuing
     # one DELETE followed by one INSERT statement. However, we want to minimize
     # expensive writes so we use this more complex logic.
     PREF = 4 # Constant indicating preferred email address
 
-    if not SD.has_key("delete_plan"):
+    if "delete_plan" not in SD:
         param_types = ["int4"]
 
         SD["delete_plan"] = plpy.prepare("""
@@ -2306,15 +2192,15 @@ COMMENT ON FUNCTION public.mv_validpersonorteamcache_person() IS 'A trigger for 
 
 
 CREATE FUNCTION public.name_blacklist_match(text, integer) RETURNS integer
-    LANGUAGE plpythonu STABLE STRICT SECURITY DEFINER
+    LANGUAGE plpython3u STABLE STRICT SECURITY DEFINER
     SET search_path TO 'public'
     AS $_$
     import re
-    name = args[0].decode("UTF-8")
+    name = args[0]
     user_id = args[1]
 
     # Initialize shared storage, shared between invocations.
-    if not SD.has_key("regexp_select_plan"):
+    if "regexp_select_plan" not in SD:
 
         # All the blacklist regexps except the ones we are an admin
         # for. These we do not check since they are not blacklisted to us.
@@ -2364,9 +2250,7 @@ CREATE FUNCTION public.name_blacklist_match(text, integer) RETURNS integer
         regexp_txt = row["regexp"]
         if (compiled.get(regexp_id) is None
             or compiled[regexp_id][0] != regexp_txt):
-            regexp = re.compile(
-                regexp_txt, re.IGNORECASE | re.UNICODE | re.VERBOSE
-                )
+            regexp = re.compile(regexp_txt, re.IGNORECASE | re.VERBOSE)
             compiled[regexp_id] = (regexp_txt, regexp)
         else:
             regexp = compiled[regexp_id][1]
@@ -2399,6 +2283,40 @@ $$;
 COMMENT ON FUNCTION public.null_count(p_values anyarray) IS 'Return the number of NULLs in the first row of the given array.';
 
 
+CREATE FUNCTION public.ocirecipe_denorm_access(ocirecipe_id integer) RETURNS void
+    LANGUAGE plpgsql
+    AS $$
+DECLARE
+    info_type integer;
+BEGIN
+    SELECT
+        -- information type: 1 = public
+        COALESCE(ocirecipe.information_type, 1)
+    INTO info_type
+    FROM ocirecipe WHERE id = ocirecipe_id;
+
+    UPDATE OCIRecipe
+        SET access_policy = policies[1], access_grants = grants
+        FROM
+            build_access_cache(
+                (SELECT id FROM accessartifact WHERE ocirecipe = ocirecipe_id),
+                info_type)
+            AS (policies integer[], grants integer[])
+        WHERE id = ocirecipe_id;
+END;
+$$;
+
+
+CREATE FUNCTION public.ocirecipe_maintain_access_cache_trig() RETURNS trigger
+    LANGUAGE plpgsql
+    AS $$
+BEGIN
+    PERFORM ocirecipe_denorm_access(NEW.id);
+    RETURN NULL;
+END;
+$$;
+
+
 CREATE FUNCTION public.packageset_deleted_trig() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
@@ -2582,7 +2500,7 @@ COMMENT ON FUNCTION public.packagesetinclusion_inserted_trig() IS 'Maintain the 
 
 
 CREATE FUNCTION public.person_sort_key(displayname text, name text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     # NB: If this implementation is changed, the person_sort_idx needs to be
     # rebuilt along with any other indexes using it.
@@ -2591,15 +2509,15 @@ CREATE FUNCTION public.person_sort_key(displayname text, name text) RETURNS text
     try:
         strip_re = SD["strip_re"]
     except KeyError:
-        strip_re = re.compile("(?:[^\w\s]|[\d_])", re.U)
+        strip_re = re.compile("(?:[^\w\s]|[\d_])")
         SD["strip_re"] = strip_re
 
     displayname, name = args
 
     # Strip noise out of displayname. We do not have to bother with
     # name, as we know it is just plain ascii.
-    displayname = strip_re.sub('', displayname.decode('UTF-8').lower())
-    return ("%s, %s" % (displayname.strip(), name)).encode('UTF-8')
+    displayname = strip_re.sub('', displayname.lower())
+    return "%s, %s" % (displayname.strip(), name)
 $$;
 
 
@@ -2686,7 +2604,7 @@ COMMENT ON FUNCTION public.replication_lag(node_id integer) IS 'Returns the lag 
 
 
 CREATE FUNCTION public.sane_version(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
     import re
     if re.search("""^(?ix)
@@ -2908,16 +2826,56 @@ COMMENT ON FUNCTION public.set_date_status_set() IS 'BEFORE UPDATE trigger on Ac
 
 
 CREATE FUNCTION public.sha1(text) RETURNS character
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import hashlib
-    return hashlib.sha1(args[0]).hexdigest()
+    return hashlib.sha1(args[0].encode()).hexdigest()
 $$;
 
 
 COMMENT ON FUNCTION public.sha1(text) IS 'Return the SHA1 one way cryptographic hash as a string of 40 hex digits';
 
 
+CREATE FUNCTION public.snap_denorm_access(snap_id integer) RETURNS void
+    LANGUAGE plpgsql
+    AS $$
+DECLARE
+    info_type integer;
+BEGIN
+    -- XXX pappacena 2021-02-12: Once we finish filling "information_type" and
+    -- deprecate the usage of "public" column at code level, we will be able to
+    -- drop the "private" column usage here.
+    SELECT
+        COALESCE(
+            snap.information_type,
+            -- information type: 1 = public; 5 = proprietary
+            CASE WHEN snap.private THEN 5 ELSE 1 END
+        )
+    INTO info_type
+    FROM snap WHERE id = snap_id;
+
+    UPDATE Snap
+        SET access_policy = policies[1], access_grants = grants
+        FROM
+            build_access_cache(
+                (SELECT id FROM accessartifact WHERE snap = snap_id),
+                info_type)
+            AS (policies integer[], grants integer[])
+        WHERE id = snap_id;
+END;
+$$;
+
+
+CREATE FUNCTION public.snap_maintain_access_cache_trig() RETURNS trigger
+    LANGUAGE plpgsql
+    AS $$
+BEGIN
+    PERFORM snap_denorm_access(NEW.id);
+    RETURN NULL;
+END;
+$$;
+
+
 CREATE FUNCTION public.specification_denorm_access(spec_id integer) RETURNS void
     LANGUAGE sql SECURITY DEFINER
     SET search_path TO 'public'
@@ -2943,34 +2901,16 @@ END;
 $$;
 
 
-CREATE FUNCTION public.summarise_bug(bug integer) RETURNS void
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-    PERFORM bugsummary_journal_bug(bug_row(bug), 1);
-END;
-$$;
-
-
 CREATE FUNCTION public.ulower(text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
-    return args[0].decode('utf8').lower().encode('utf8')
+    return args[0].lower()
 $$;
 
 
 COMMENT ON FUNCTION public.ulower(text) IS 'Return the lower case version of a UTF-8 encoded string.';
 
 
-CREATE FUNCTION public.unsummarise_bug(bug integer) RETURNS void
-    LANGUAGE plpgsql
-    AS $$
-BEGIN
-    PERFORM bugsummary_journal_bug(bug_row(bug), -1);
-END;
-$$;
-
-
 CREATE FUNCTION public.update_branch_name_cache() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
@@ -3135,7 +3075,7 @@ $$;
 
 
 CREATE FUNCTION public.update_database_stats() RETURNS void
-    LANGUAGE plpythonu SECURITY DEFINER
+    LANGUAGE plpython3u SECURITY DEFINER
     SET search_path TO 'public'
     AS $_$
     import re
@@ -3248,17 +3188,14 @@ COMMENT ON FUNCTION public.update_replication_lag_cache() IS 'Updates the Databa
 
 
 CREATE FUNCTION public.valid_absolute_url(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
-    from urlparse import urlparse, uses_netloc
-    # Extend list of schemes that specify netloc. We can drop sftp
-    # with Python 2.5 in the DB.
-    if 'git' not in uses_netloc:
-        uses_netloc.insert(0, 'sftp')
+    from urllib.parse import urlparse, uses_netloc
+    # Extend list of schemes that specify netloc.
+    if 'bzr' not in uses_netloc:
         uses_netloc.insert(0, 'bzr')
         uses_netloc.insert(0, 'bzr+ssh')
         uses_netloc.insert(0, 'ssh') # Mercurial
-        uses_netloc.insert(0, 'git')
     (scheme, netloc, path, params, query, fragment) = urlparse(args[0])
     return bool(scheme and netloc)
 $$;
@@ -3268,7 +3205,7 @@ COMMENT ON FUNCTION public.valid_absolute_url(text) IS 'Ensure the given test is
 
 
 CREATE FUNCTION public.valid_branch_name(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import re
     name = args[0]
@@ -3284,8 +3221,26 @@ COMMENT ON FUNCTION public.valid_branch_name(text) IS 'validate a branch name.
     As per valid_name, except we allow uppercase and @';
 
 
+CREATE FUNCTION public.valid_bug_name(text) RETURNS boolean
+    LANGUAGE plpython3u IMMUTABLE STRICT
+    AS $_$
+    import re
+    name = args[0]
+    pat = r"^[a-z][a-z0-9+\.\-]+$"
+    if re.match(pat, name):
+        return 1
+    return 0
+$_$;
+
+
+COMMENT ON FUNCTION public.valid_bug_name(text) IS 'validate a bug name
+
+    As per valid_name, except numeric-only names are not allowed (including
+    names that look like floats).';
+
+
 CREATE FUNCTION public.valid_cve(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
     import re
     name = args[0]
@@ -3300,7 +3255,7 @@ COMMENT ON FUNCTION public.valid_cve(text) IS 'validate a common vulnerability n
 
 
 CREATE FUNCTION public.valid_debian_version(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $_$
     import re
     m = re.search("""^(?ix)
@@ -3327,7 +3282,7 @@ COMMENT ON FUNCTION public.valid_debian_version(text) IS 'validate a version num
 
 
 CREATE FUNCTION public.valid_fingerprint(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import re
     if re.match(r"[\dA-F]{40}", args[0]) is not None:
@@ -3341,7 +3296,7 @@ COMMENT ON FUNCTION public.valid_fingerprint(text) IS 'Returns true if passed a 
 
 
 CREATE FUNCTION public.valid_git_repository_name(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import re
     name = args[0]
@@ -3358,7 +3313,7 @@ COMMENT ON FUNCTION public.valid_git_repository_name(text) IS 'validate a Git re
 
 
 CREATE FUNCTION public.valid_keyid(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import re
     if re.match(r"[\dA-F]{8}", args[0]) is not None:
@@ -3371,13 +3326,36 @@ $$;
 COMMENT ON FUNCTION public.valid_keyid(text) IS 'Returns true if passed a valid GPG keyid. Valid GPG keyids are an 8 character long hexadecimal number in uppercase (in reality, they are 16 characters long but we are using the ''common'' definition.';
 
 
+CREATE FUNCTION public.valid_name(text) RETURNS boolean
+    LANGUAGE plpython3u IMMUTABLE STRICT
+    AS $$
+    import re
+    name = args[0]
+    pat = r"^[a-z0-9][a-z0-9\+\.\-]*\Z"
+    if re.match(pat, name):
+        return 1
+    return 0
+$$;
+
+
+COMMENT ON FUNCTION public.valid_name(text) IS 'validate a name.
+
+    Names must contain only lowercase letters, numbers, ., & -. They
+    must start with an alphanumeric. They are ASCII only. Names are useful
+    for mneumonic identifiers such as nicknames and as URL components.
+    This specification is the same as the Debian product naming policy.
+
+    Note that a valid name might be all integers, so there is a possible
+    namespace conflict if URL traversal is possible by name as well as id.';
+
+
 CREATE FUNCTION public.valid_regexp(text) RETURNS boolean
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     import re
     try:
         re.compile(args[0])
-    except:
+    except Exception:
         return False
     else:
         return True
@@ -3388,7 +3366,7 @@ COMMENT ON FUNCTION public.valid_regexp(text) IS 'Returns true if the input can 
 
 
 CREATE FUNCTION public.version_sort_key(version text) RETURNS text
-    LANGUAGE plpythonu IMMUTABLE STRICT
+    LANGUAGE plpython3u IMMUTABLE STRICT
     AS $$
     # If this method is altered, then any functional indexes using it
     # need to be rebuilt.
@@ -3403,7 +3381,7 @@ CREATE FUNCTION public.version_sort_key(version text) RETURNS text
         # of visible ASCII characters.
         return '~' + match.group(0).zfill(5)
 
-    return re.sub(u'\d+', substitute_filled_numbers, version)
+    return re.sub('\d+', substitute_filled_numbers, version)
 $$;
 
 
@@ -3617,7 +3595,9 @@ CREATE TABLE public.accessartifact (
     branch integer,
     specification integer,
     gitrepository integer,
-    CONSTRAINT has_artifact CHECK ((public.null_count(ARRAY[bug, branch, gitrepository, specification]) = 3))
+    snap integer,
+    ocirecipe integer,
+    CONSTRAINT has_artifact CHECK ((public.null_count(ARRAY[bug, branch, gitrepository, snap, specification, ocirecipe]) = 5))
 );
 
 
@@ -3670,7 +3650,7 @@ CREATE TABLE public.accesspolicy (
     distribution integer,
     type integer,
     person integer,
-    CONSTRAINT has_target CHECK (((((type IS NOT NULL) AND ((product IS NULL) <> (distribution IS NULL))) AND (person IS NULL)) OR ((((type IS NULL) AND (person IS NOT NULL)) AND (product IS NULL)) AND (distribution IS NULL))))
+    CONSTRAINT has_target CHECK ((((type IS NOT NULL) AND ((product IS NULL) <> (distribution IS NULL)) AND (person IS NULL)) OR ((type IS NULL) AND (person IS NOT NULL) AND (product IS NULL) AND (distribution IS NULL))))
 );
 
 
@@ -3769,6 +3749,62 @@ CREATE SEQUENCE public.accesspolicygrantflat_id_seq
 ALTER SEQUENCE public.accesspolicygrantflat_id_seq OWNED BY public.accesspolicygrantflat.id;
 
 
+CREATE TABLE public.accesstoken (
+    id integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    token_sha256 text NOT NULL,
+    owner integer NOT NULL,
+    description text NOT NULL,
+    git_repository integer NOT NULL,
+    scopes jsonb NOT NULL,
+    date_last_used timestamp without time zone,
+    date_expires timestamp without time zone,
+    revoked_by integer
+);
+
+
+COMMENT ON TABLE public.accesstoken IS 'A personal access token for the webservice API.';
+
+
+COMMENT ON COLUMN public.accesstoken.date_created IS 'When the token was created.';
+
+
+COMMENT ON COLUMN public.accesstoken.token_sha256 IS 'SHA-256 hash of the secret token.';
+
+
+COMMENT ON COLUMN public.accesstoken.owner IS 'The person who created the token.';
+
+
+COMMENT ON COLUMN public.accesstoken.description IS 'A short description of the token''s purpose.';
+
+
+COMMENT ON COLUMN public.accesstoken.git_repository IS 'The Git repository for which the token was issued.';
+
+
+COMMENT ON COLUMN public.accesstoken.scopes IS 'A list of scopes granted by the token.';
+
+
+COMMENT ON COLUMN public.accesstoken.date_last_used IS 'When the token was last used.';
+
+
+COMMENT ON COLUMN public.accesstoken.date_expires IS 'When the token should expire or was revoked.';
+
+
+COMMENT ON COLUMN public.accesstoken.revoked_by IS 'The person who revoked the token, if any.';
+
+
+CREATE SEQUENCE public.accesstoken_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.accesstoken_id_seq OWNED BY public.accesstoken.id;
+
+
 CREATE TABLE public.account (
     id integer NOT NULL,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
@@ -3819,7 +3855,7 @@ CREATE TABLE public.announcement (
     url text,
     active boolean DEFAULT true NOT NULL,
     date_updated timestamp without time zone,
-    CONSTRAINT has_target CHECK ((((product IS NOT NULL) OR (project IS NOT NULL)) OR (distribution IS NOT NULL))),
+    CONSTRAINT has_target CHECK (((product IS NOT NULL) OR (project IS NOT NULL) OR (distribution IS NOT NULL))),
     CONSTRAINT valid_url CHECK (public.valid_absolute_url(url))
 );
 
@@ -3943,7 +3979,6 @@ CREATE TABLE public.archive (
     failed_count integer DEFAULT 0 NOT NULL,
     building_count integer DEFAULT 0 NOT NULL,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    signing_key integer,
     removed_binary_retention_days integer,
     num_old_versions_published integer,
     displayname text NOT NULL,
@@ -3957,7 +3992,8 @@ CREATE TABLE public.archive (
     signing_key_owner integer,
     signing_key_fingerprint text,
     dirty_suites text,
-    CONSTRAINT valid_buildd_secret CHECK ((((private = true) AND (buildd_secret IS NOT NULL)) OR (private = false))),
+    publishing_method integer,
+    repository_format integer,
     CONSTRAINT valid_name CHECK (public.valid_name(name)),
     CONSTRAINT valid_signing_key_fingerprint CHECK (((signing_key_fingerprint IS NULL) OR public.valid_fingerprint(signing_key_fingerprint)))
 );
@@ -4023,9 +4059,6 @@ COMMENT ON COLUMN public.archive.failed_count IS 'How many packages failed to bu
 COMMENT ON COLUMN public.archive.building_count IS 'How many packages are building at present?';
 
 
-COMMENT ON COLUMN public.archive.signing_key IS 'The GpgKey used for signing this archive.';
-
-
 COMMENT ON COLUMN public.archive.removed_binary_retention_days IS 'The number of days before superseded or deleted binary files are expired in the librarian, or zero for never.';
 
 
@@ -4137,15 +4170,17 @@ ALTER SEQUENCE public.archiveauthtoken_id_seq OWNED BY public.archiveauthtoken.i
 CREATE TABLE public.archivedependency (
     id integer NOT NULL,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    archive integer NOT NULL,
+    archive integer,
     dependency integer NOT NULL,
     pocket integer NOT NULL,
     component integer,
-    CONSTRAINT distinct_archives CHECK ((archive <> dependency))
+    snap_base integer,
+    CONSTRAINT distinct_archives CHECK ((archive <> dependency)),
+    CONSTRAINT one_parent CHECK ((public.null_count(ARRAY[archive, snap_base]) = 1))
 );
 
 
-COMMENT ON TABLE public.archivedependency IS 'This table maps a given archive to all other archives it should depend on.';
+COMMENT ON TABLE public.archivedependency IS 'This table maps a given parent (archive or snap base) to all other archives it should depend on.';
 
 
 COMMENT ON COLUMN public.archivedependency.date_created IS 'Instant when the dependency was created.';
@@ -4157,6 +4192,9 @@ COMMENT ON COLUMN public.archivedependency.archive IS 'The archive where the dep
 COMMENT ON COLUMN public.archivedependency.dependency IS 'The archive to depend on.';
 
 
+COMMENT ON COLUMN public.archivedependency.snap_base IS 'The snap base that has this dependency.';
+
+
 CREATE SEQUENCE public.archivedependency_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -4174,7 +4212,9 @@ CREATE TABLE public.archivefile (
     container text NOT NULL,
     path text NOT NULL,
     library_file integer NOT NULL,
-    scheduled_deletion_date timestamp without time zone
+    scheduled_deletion_date timestamp without time zone,
+    date_created timestamp without time zone,
+    date_superseded timestamp without time zone
 );
 
 
@@ -4196,6 +4236,12 @@ COMMENT ON COLUMN public.archivefile.library_file IS 'The file in the librarian.
 COMMENT ON COLUMN public.archivefile.scheduled_deletion_date IS 'The date when this file should stop being published.';
 
 
+COMMENT ON COLUMN public.archivefile.date_created IS 'The date when this file was created.';
+
+
+COMMENT ON COLUMN public.archivefile.date_superseded IS 'The date when this file ceased to hold its path in the archive, due to being removed or superseded by a newer version.';
+
+
 CREATE SEQUENCE public.archivefile_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -4299,6 +4345,28 @@ CREATE SEQUENCE public.archivepermission_id_seq
 ALTER SEQUENCE public.archivepermission_id_seq OWNED BY public.archivepermission.id;
 
 
+CREATE TABLE public.archivesigningkey (
+    id integer NOT NULL,
+    archive integer NOT NULL,
+    earliest_distro_series integer,
+    key_type integer NOT NULL,
+    signing_key integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL
+);
+
+
+CREATE SEQUENCE public.archivesigningkey_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.archivesigningkey_id_seq OWNED BY public.archivesigningkey.id;
+
+
 CREATE TABLE public.archivesubscriber (
     id integer NOT NULL,
     archive integer NOT NULL,
@@ -4356,8 +4424,7 @@ ALTER SEQUENCE public.archivesubscriber_id_seq OWNED BY public.archivesubscriber
 
 CREATE TABLE public.binarypackagename (
     id integer NOT NULL,
-    name text NOT NULL,
-    CONSTRAINT valid_name CHECK (public.valid_name(name))
+    name text NOT NULL
 );
 
 
@@ -4487,9 +4554,9 @@ CREATE TABLE public.binarypackagepublishinghistory (
     binarypackagerelease integer NOT NULL,
     distroarchseries integer NOT NULL,
     status integer NOT NULL,
-    component integer NOT NULL,
-    section integer NOT NULL,
-    priority integer NOT NULL,
+    component integer,
+    section integer,
+    priority integer,
     datecreated timestamp without time zone NOT NULL,
     datepublished timestamp without time zone,
     datesuperseded timestamp without time zone,
@@ -4502,7 +4569,13 @@ CREATE TABLE public.binarypackagepublishinghistory (
     removed_by integer,
     removal_comment text,
     binarypackagename integer NOT NULL,
-    phased_update_percentage smallint
+    phased_update_percentage smallint,
+    creator integer,
+    copied_from_archive integer,
+    binarypackageformat integer,
+    channel jsonb,
+    CONSTRAINT debian_columns CHECK ((((binarypackageformat IS NOT NULL) AND (binarypackageformat <> ALL (ARRAY[1, 2, 5]))) OR ((component IS NOT NULL) AND (section IS NOT NULL) AND (priority IS NOT NULL)))),
+    CONSTRAINT no_debian_channel CHECK ((((binarypackageformat IS NOT NULL) AND (binarypackageformat <> ALL (ARRAY[1, 2, 5]))) OR (channel IS NULL)))
 );
 
 
@@ -4583,11 +4656,11 @@ CREATE TABLE public.binarypackagerelease (
     version public.debversion NOT NULL,
     summary text NOT NULL,
     description text NOT NULL,
-    build integer NOT NULL,
+    build integer,
     binpackageformat integer NOT NULL,
-    component integer NOT NULL,
-    section integer NOT NULL,
-    priority integer NOT NULL,
+    component integer,
+    section integer,
+    priority integer,
     shlibdeps text,
     depends text,
     recommends text,
@@ -4606,6 +4679,9 @@ CREATE TABLE public.binarypackagerelease (
     debug_package integer,
     user_defined_fields text,
     homepage text,
+    ci_build integer,
+    CONSTRAINT debian_columns CHECK (((binpackageformat <> ALL (ARRAY[1, 2, 5])) OR ((component IS NOT NULL) AND (section IS NOT NULL) AND (priority IS NOT NULL)))),
+    CONSTRAINT one_build CHECK ((public.null_count(ARRAY[build, ci_build]) = 1)),
     CONSTRAINT valid_version CHECK (public.valid_debian_version((version)::text))
 );
 
@@ -4720,6 +4796,38 @@ CREATE SEQUENCE public.binarypackagereleasedownloadcount_id_seq
 ALTER SEQUENCE public.binarypackagereleasedownloadcount_id_seq OWNED BY public.binarypackagereleasedownloadcount.id;
 
 
+CREATE TABLE public.binarysourcereference (
+    id integer NOT NULL,
+    binary_package_release integer NOT NULL,
+    source_package_release integer NOT NULL,
+    reference_type integer NOT NULL
+);
+
+
+COMMENT ON TABLE public.binarysourcereference IS 'A reference from a binary package release to a source package release.';
+
+
+COMMENT ON COLUMN public.binarysourcereference.binary_package_release IS 'The referencing binary package release.';
+
+
+COMMENT ON COLUMN public.binarysourcereference.source_package_release IS 'The referenced source package release.';
+
+
+COMMENT ON COLUMN public.binarysourcereference.reference_type IS 'The type of the reference.';
+
+
+CREATE SEQUENCE public.binarysourcereference_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.binarysourcereference_id_seq OWNED BY public.binarysourcereference.id;
+
+
 CREATE TABLE public.branch (
     id integer NOT NULL,
     title text,
@@ -4758,7 +4866,8 @@ CREATE TABLE public.branch (
     information_type integer NOT NULL,
     access_policy integer,
     access_grants integer[],
-    CONSTRAINT branch_type_url_consistent CHECK (((((branch_type = 2) AND (url IS NOT NULL)) OR ((branch_type = ANY (ARRAY[1, 3])) AND (url IS NULL))) OR (branch_type = 4))),
+    deletion_status integer,
+    CONSTRAINT branch_type_url_consistent CHECK ((((branch_type = 2) AND (url IS NOT NULL)) OR ((branch_type = ANY (ARRAY[1, 3])) AND (url IS NULL)) OR (branch_type = 4))),
     CONSTRAINT branch_url_no_trailing_slash CHECK ((url !~~ '%/'::text)),
     CONSTRAINT branch_url_not_supermirror CHECK ((url !~~ 'http://bazaar.launchpad.net/%'::text)),
     CONSTRAINT one_container CHECK ((((distroseries IS NULL) = (sourcepackagename IS NULL)) AND ((distroseries IS NULL) OR (product IS NULL)))),
@@ -4840,6 +4949,9 @@ COMMENT ON COLUMN public.branch.size_on_disk IS 'The size in bytes of this branc
 COMMENT ON COLUMN public.branch.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
 
 
+COMMENT ON COLUMN public.branch.deletion_status IS 'The deletion status of this branch.';
+
+
 CREATE SEQUENCE public.branch_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -4927,9 +5039,9 @@ CREATE TABLE public.branchmergeproposal (
     CONSTRAINT consistent_dependent_git_ref CHECK ((((dependent_git_repository IS NULL) = (dependent_git_path IS NULL)) AND ((dependent_git_repository IS NULL) = (dependent_git_commit_sha1 IS NULL)))),
     CONSTRAINT consistent_source_git_ref CHECK ((((source_git_repository IS NULL) = (source_git_path IS NULL)) AND ((source_git_repository IS NULL) = (source_git_commit_sha1 IS NULL)))),
     CONSTRAINT consistent_target_git_ref CHECK ((((target_git_repository IS NULL) = (target_git_path IS NULL)) AND ((target_git_repository IS NULL) = (target_git_commit_sha1 IS NULL)))),
-    CONSTRAINT different_branches CHECK ((((source_branch <> target_branch) AND (dependent_branch <> source_branch)) AND (dependent_branch <> target_branch))),
-    CONSTRAINT different_git_refs CHECK (((source_git_repository IS NULL) OR ((((source_git_repository <> target_git_repository) OR (source_git_path <> target_git_path)) AND ((dependent_git_repository <> source_git_repository) OR (dependent_git_path <> source_git_path))) AND ((dependent_git_repository <> target_git_repository) OR (dependent_git_path <> target_git_path))))),
-    CONSTRAINT one_vcs CHECK ((((((source_branch IS NOT NULL) AND (target_branch IS NOT NULL)) <> ((source_git_repository IS NOT NULL) AND (target_git_repository IS NOT NULL))) AND ((dependent_branch IS NULL) OR (source_branch IS NOT NULL))) AND ((dependent_git_repository IS NULL) OR (source_git_repository IS NOT NULL)))),
+    CONSTRAINT different_branches CHECK (((source_branch <> target_branch) AND (dependent_branch <> source_branch) AND (dependent_branch <> target_branch))),
+    CONSTRAINT different_git_refs CHECK (((source_git_repository IS NULL) OR (((source_git_repository <> target_git_repository) OR (source_git_path <> target_git_path)) AND ((dependent_git_repository <> source_git_repository) OR (dependent_git_path <> source_git_path)) AND ((dependent_git_repository <> target_git_repository) OR (dependent_git_path <> target_git_path))))),
+    CONSTRAINT one_vcs CHECK (((((source_branch IS NOT NULL) AND (target_branch IS NOT NULL)) <> ((source_git_repository IS NOT NULL) AND (target_git_repository IS NOT NULL))) AND ((dependent_branch IS NULL) OR (source_branch IS NOT NULL)) AND ((dependent_git_repository IS NULL) OR (source_git_repository IS NOT NULL)))),
     CONSTRAINT positive_revno CHECK (((merged_revno IS NULL) OR (merged_revno > 0)))
 );
 
@@ -5110,24 +5222,92 @@ CREATE SEQUENCE public.branchsubscription_id_seq
 ALTER SEQUENCE public.branchsubscription_id_seq OWNED BY public.branchsubscription.id;
 
 
-CREATE SEQUENCE public.bug_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+CREATE TABLE public.bug (
+    id integer NOT NULL,
+    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    name text,
+    title text NOT NULL,
+    description text NOT NULL,
+    owner integer NOT NULL,
+    duplicateof integer,
+    fti public.ts2_tsvector,
+    date_last_updated timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_made_private timestamp without time zone,
+    who_made_private integer,
+    date_last_message timestamp without time zone,
+    number_of_duplicates integer DEFAULT 0 NOT NULL,
+    message_count integer DEFAULT 0 NOT NULL,
+    users_affected_count integer DEFAULT 0,
+    users_unaffected_count integer DEFAULT 0,
+    heat integer DEFAULT 0 NOT NULL,
+    heat_last_updated timestamp without time zone,
+    latest_patch_uploaded timestamp without time zone,
+    information_type integer NOT NULL,
+    lock_status integer DEFAULT 0 NOT NULL,
+    lock_reason text,
+    CONSTRAINT notduplicateofself CHECK ((NOT (id = duplicateof))),
+    CONSTRAINT sane_description CHECK (((ltrim(description) <> ''::text) AND (char_length(description) <= 50000))),
+    CONSTRAINT valid_bug_name CHECK (public.valid_bug_name(name))
+);
 
 
-ALTER SEQUENCE public.bug_id_seq OWNED BY public.bug.id;
+COMMENT ON TABLE public.bug IS 'A software bug that requires fixing. This particular bug may be linked to one or more products or source packages to identify the location(s) that this bug is found.';
 
 
-CREATE TABLE public.bugactivity (
-    id integer NOT NULL,
-    bug integer NOT NULL,
-    datechanged timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    person integer NOT NULL,
-    whatchanged text NOT NULL,
-    oldvalue text,
+COMMENT ON COLUMN public.bug.name IS 'A lowercase name uniquely identifying the bug';
+
+
+COMMENT ON COLUMN public.bug.description IS 'A detailed description of the bug. Initially this will be set to the contents of the initial email or bug filing comment, but later it can be edited to give a more accurate description of the bug itself rather than the symptoms observed by the reporter.';
+
+
+COMMENT ON COLUMN public.bug.date_last_message IS 'When the last BugMessage was attached to this Bug. Maintained by a trigger on the BugMessage table.';
+
+
+COMMENT ON COLUMN public.bug.number_of_duplicates IS 'The number of bugs marked as duplicates of this bug, populated by a trigger after setting the duplicateof of bugs.';
+
+
+COMMENT ON COLUMN public.bug.message_count IS 'The number of messages (currently just comments) on this bugbug, maintained by the set_bug_message_count_t trigger.';
+
+
+COMMENT ON COLUMN public.bug.users_affected_count IS 'The number of users affected by this bug, maintained by the set_bug_users_affected_count_t trigger.';
+
+
+COMMENT ON COLUMN public.bug.heat IS 'The relevance of this bug. This value is computed periodically using bug_affects_person and other bug values.';
+
+
+COMMENT ON COLUMN public.bug.heat_last_updated IS 'The time this bug''s heat was last updated, or NULL if the heat has never yet been updated.';
+
+
+COMMENT ON COLUMN public.bug.latest_patch_uploaded IS 'The time when the most recent patch has been attached to this bug or NULL if no patches are attached';
+
+
+COMMENT ON COLUMN public.bug.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
+
+
+COMMENT ON COLUMN public.bug.lock_status IS 'The current lock status of this bug.';
+
+
+COMMENT ON COLUMN public.bug.lock_reason IS 'The reason for locking this bug.';
+
+
+CREATE SEQUENCE public.bug_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.bug_id_seq OWNED BY public.bug.id;
+
+
+CREATE TABLE public.bugactivity (
+    id integer NOT NULL,
+    bug integer NOT NULL,
+    datechanged timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    person integer NOT NULL,
+    whatchanged text NOT NULL,
+    oldvalue text,
     newvalue text,
     message text
 )
@@ -5503,7 +5683,7 @@ ALTER SEQUENCE public.bugsubscription_id_seq OWNED BY public.bugsubscription.id;
 
 CREATE TABLE public.bugsubscriptionfilter (
     id integer NOT NULL,
-    structuralsubscription integer,
+    structuralsubscription integer NOT NULL,
     find_all_tags boolean NOT NULL,
     include_any_tags boolean NOT NULL,
     exclude_any_tags boolean NOT NULL,
@@ -5645,24 +5825,6 @@ CREATE SEQUENCE public.bugsummary_id_seq
 ALTER SEQUENCE public.bugsummary_id_seq OWNED BY public.bugsummary.id;
 
 
-CREATE TABLE public.bugsummaryjournal (
-    id integer NOT NULL,
-    count integer DEFAULT 0 NOT NULL,
-    product integer,
-    productseries integer,
-    distribution integer,
-    distroseries integer,
-    sourcepackagename integer,
-    viewed_by integer,
-    tag text,
-    status integer NOT NULL,
-    milestone integer,
-    importance integer NOT NULL,
-    has_patch boolean NOT NULL,
-    access_policy integer
-);
-
-
 CREATE SEQUENCE public.bugsummaryjournal_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -5674,6 +5836,23 @@ CREATE SEQUENCE public.bugsummaryjournal_id_seq
 ALTER SEQUENCE public.bugsummaryjournal_id_seq OWNED BY public.bugsummaryjournal.id;
 
 
+CREATE TABLE public.bugtag (
+    id integer NOT NULL,
+    bug integer NOT NULL,
+    tag text NOT NULL,
+    CONSTRAINT valid_tag CHECK (public.valid_name(tag))
+);
+
+
+COMMENT ON TABLE public.bugtag IS 'Attaches simple text tags to a bug.';
+
+
+COMMENT ON COLUMN public.bugtag.bug IS 'The bug the tags is attached to.';
+
+
+COMMENT ON COLUMN public.bugtag.tag IS 'The text representation of the tag.';
+
+
 CREATE SEQUENCE public.bugtag_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -5712,12 +5891,18 @@ CREATE TABLE public.bugtask (
     date_fix_released timestamp without time zone,
     date_left_closed timestamp without time zone,
     date_milestone_set timestamp without time zone,
+    ociproject integer,
+    ociprojectseries integer,
+    status_explanation text,
+    importance_explanation text,
     CONSTRAINT bugtask_assignment_checks CHECK (
 CASE
-    WHEN (product IS NOT NULL) THEN ((((productseries IS NULL) AND (distribution IS NULL)) AND (distroseries IS NULL)) AND (sourcepackagename IS NULL))
-    WHEN (productseries IS NOT NULL) THEN (((distribution IS NULL) AND (distroseries IS NULL)) AND (sourcepackagename IS NULL))
+    WHEN (product IS NOT NULL) THEN ((productseries IS NULL) AND (distribution IS NULL) AND (distroseries IS NULL) AND (sourcepackagename IS NULL))
+    WHEN (productseries IS NOT NULL) THEN ((distribution IS NULL) AND (distroseries IS NULL) AND (sourcepackagename IS NULL) AND (ociproject IS NULL) AND (ociprojectseries IS NULL))
     WHEN (distribution IS NOT NULL) THEN (distroseries IS NULL)
-    WHEN (distroseries IS NOT NULL) THEN true
+    WHEN (distroseries IS NOT NULL) THEN ((ociproject IS NULL) AND (ociprojectseries IS NULL))
+    WHEN (ociproject IS NOT NULL) THEN ((ociprojectseries IS NULL) AND ((distribution IS NOT NULL) OR (product IS NOT NULL)) AND (sourcepackagename IS NULL))
+    WHEN (ociprojectseries IS NOT NULL) THEN ((ociproject IS NULL) AND ((distribution IS NOT NULL) OR (product IS NOT NULL)) AND (sourcepackagename IS NULL))
     ELSE false
 END)
 );
@@ -5796,6 +5981,12 @@ COMMENT ON COLUMN public.bugtask.date_left_closed IS 'The date when this bug las
 COMMENT ON COLUMN public.bugtask.date_milestone_set IS 'The date when this bug was targed to the milestone that is currently set.';
 
 
+COMMENT ON COLUMN public.bugtask.status_explanation IS 'An optional explanation for the current status of this bugtask.';
+
+
+COMMENT ON COLUMN public.bugtask.importance_explanation IS 'An optional explanation for the current importance of this bugtask.';
+
+
 CREATE SEQUENCE public.bugtask_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -6246,73 +6437,75 @@ CREATE SEQUENCE public.buildqueue_id_seq
 ALTER SEQUENCE public.buildqueue_id_seq OWNED BY public.buildqueue.id;
 
 
-CREATE TABLE public.codeimport (
+CREATE TABLE public.charmbase (
     id integer NOT NULL,
-    branch integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
     registrant integer NOT NULL,
-    rcs_type integer NOT NULL,
-    cvs_root text,
-    cvs_module text,
-    review_status integer DEFAULT 1 NOT NULL,
-    date_last_successful timestamp without time zone,
-    owner integer NOT NULL,
-    assignee integer,
-    update_interval interval,
-    url text,
-    git_repository integer,
-    CONSTRAINT one_target_vcs CHECK (((branch IS NOT NULL) <> (git_repository IS NOT NULL))),
-    CONSTRAINT valid_source_target_vcs_pairing CHECK (((branch IS NOT NULL) OR (rcs_type = 4))),
-    CONSTRAINT valid_vcs_details CHECK (
-CASE
-    WHEN (rcs_type = 1) THEN (((((cvs_root IS NOT NULL) AND (cvs_root <> ''::text)) AND (cvs_module IS NOT NULL)) AND (cvs_module <> ''::text)) AND (url IS NULL))
-    WHEN (rcs_type = ANY (ARRAY[2, 3])) THEN ((((cvs_root IS NULL) AND (cvs_module IS NULL)) AND (url IS NOT NULL)) AND public.valid_absolute_url(url))
-    WHEN (rcs_type = ANY (ARRAY[4, 5, 6])) THEN (((cvs_root IS NULL) AND (cvs_module IS NULL)) AND (url IS NOT NULL))
-    ELSE false
-END)
+    distro_series integer NOT NULL,
+    build_snap_channels jsonb NOT NULL
 );
 
 
-COMMENT ON TABLE public.codeimport IS 'The persistent record of an import from a foreign version control system to Bazaar, from the initial request to the regularly updated import branch.';
+COMMENT ON TABLE public.charmbase IS 'A base for charms.';
 
 
-COMMENT ON COLUMN public.codeimport.branch IS 'The Bazaar branch produced by the import system.  Always non-NULL: a placeholder branch is created when the import is created.  The import is associated to a Product and Series though the branch.';
+COMMENT ON COLUMN public.charmbase.date_created IS 'The date on which this base was created in Launchpad.';
 
 
-COMMENT ON COLUMN public.codeimport.registrant IS 'The person who originally requested this import.';
+COMMENT ON COLUMN public.charmbase.registrant IS 'The user who registered this base.';
 
 
-COMMENT ON COLUMN public.codeimport.rcs_type IS 'The revision control system used by the import source. The value is defined in dbschema.RevisionControlSystems.';
+COMMENT ON COLUMN public.charmbase.distro_series IS 'The distro series for this base.';
 
 
-COMMENT ON COLUMN public.codeimport.cvs_root IS 'The $CVSROOT details, probably of the form :pserver:user@host:/path.';
+COMMENT ON COLUMN public.charmbase.build_snap_channels IS 'A dictionary mapping snap names to channels to use when building charm recipes that specify this base.';
 
 
-COMMENT ON COLUMN public.codeimport.cvs_module IS 'The module in cvs_root to import, often the name of the project.';
+CREATE SEQUENCE public.charmbase_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.codeimport.review_status IS 'Whether this code import request has been reviewed, and whether it was accepted.';
+ALTER SEQUENCE public.charmbase_id_seq OWNED BY public.charmbase.id;
 
 
-COMMENT ON COLUMN public.codeimport.date_last_successful IS 'When this code import last succeeded. NULL if this import has never succeeded.';
+CREATE TABLE public.charmbasearch (
+    charm_base integer NOT NULL,
+    processor integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.codeimport.owner IS 'The person who is currently responsible for keeping the import details up to date, initially set to the registrant. This person can edit some of the details of the code import branch.';
+COMMENT ON TABLE public.charmbasearch IS 'The architectures that a charm base supports.';
 
 
-COMMENT ON COLUMN public.codeimport.assignee IS 'The person in charge of delivering this code import and interacting with the owner.';
+COMMENT ON COLUMN public.charmbasearch.charm_base IS 'The charm base for which a supported architecture is specified.';
 
 
-COMMENT ON COLUMN public.codeimport.update_interval IS 'How often should this import be updated. If NULL, defaults to a system-wide value set by the Launchpad administrators.';
+COMMENT ON COLUMN public.charmbasearch.processor IS 'A supported architecture for this charm base.';
 
 
-COMMENT ON COLUMN public.codeimport.url IS 'The URL of the foreign VCS branch for this import.';
+CREATE TABLE public.charmfile (
+    id integer NOT NULL,
+    build integer NOT NULL,
+    library_file integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.codeimport.git_repository IS 'The Git repository produced by the import system, if applicable.  A placeholder repository is created when the import is created.  The import is associated with a target through the repository.';
+COMMENT ON TABLE public.charmfile IS 'A link between a charm recipe build and a file in the librarian that it produces.';
 
 
-CREATE SEQUENCE public.codeimport_id_seq
+COMMENT ON COLUMN public.charmfile.build IS 'The charm recipe build producing this file.';
+
+
+COMMENT ON COLUMN public.charmfile.library_file IS 'A file in the librarian.';
+
+
+CREATE SEQUENCE public.charmfile_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6320,66 +6513,94 @@ CREATE SEQUENCE public.codeimport_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.codeimport_id_seq OWNED BY public.codeimport.id;
+ALTER SEQUENCE public.charmfile_id_seq OWNED BY public.charmfile.id;
 
 
-CREATE TABLE public.codeimportevent (
+CREATE TABLE public.charmrecipe (
     id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    entry_type integer NOT NULL,
-    code_import integer,
-    person integer,
-    machine integer
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    registrant integer NOT NULL,
+    owner integer NOT NULL,
+    project integer NOT NULL,
+    name text NOT NULL,
+    description text,
+    git_repository integer,
+    git_path text,
+    build_path text,
+    require_virtualized boolean DEFAULT true NOT NULL,
+    information_type integer NOT NULL,
+    access_policy integer,
+    access_grants integer[],
+    auto_build boolean DEFAULT false NOT NULL,
+    auto_build_channels jsonb,
+    is_stale boolean DEFAULT true NOT NULL,
+    store_upload boolean DEFAULT false NOT NULL,
+    store_name text,
+    store_secrets text,
+    store_channels jsonb,
+    CONSTRAINT consistent_git_ref CHECK (((git_repository IS NULL) = (git_path IS NULL))),
+    CONSTRAINT consistent_store_upload CHECK (((NOT store_upload) OR (store_name IS NOT NULL))),
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
 );
 
 
-COMMENT ON TABLE public.codeimportevent IS 'A record of events in the code import system.  Rows in this table are created by triggers on other code import tables.';
+COMMENT ON TABLE public.charmrecipe IS 'A charm recipe.';
 
 
-COMMENT ON COLUMN public.codeimportevent.entry_type IS 'The type of event that is recorded by this entry. Legal values are defined by the CodeImportEventType enumeration.';
+COMMENT ON COLUMN public.charmrecipe.registrant IS 'The person who registered this charm recipe.';
 
 
-COMMENT ON COLUMN public.codeimportevent.code_import IS 'The code import that was associated to this event, if any and if it has not been deleted.';
+COMMENT ON COLUMN public.charmrecipe.owner IS 'The owner of this charm recipe.';
 
 
-COMMENT ON COLUMN public.codeimportevent.person IS 'The user who caused the event, if the event is not automatically generated.';
+COMMENT ON COLUMN public.charmrecipe.project IS 'The project that this charm recipe belongs to.';
 
 
-COMMENT ON COLUMN public.codeimportevent.machine IS 'The code import machine that was concerned by this event, if any.';
+COMMENT ON COLUMN public.charmrecipe.name IS 'The name of the charm recipe, unique per owner and project.';
 
 
-CREATE SEQUENCE public.codeimportevent_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.charmrecipe.description IS 'A description of the charm recipe.';
 
 
-ALTER SEQUENCE public.codeimportevent_id_seq OWNED BY public.codeimportevent.id;
+COMMENT ON COLUMN public.charmrecipe.git_repository IS 'A Git repository with a branch containing a charmcraft.yaml recipe.';
 
 
-CREATE TABLE public.codeimporteventdata (
-    id integer NOT NULL,
-    event integer,
-    data_type integer NOT NULL,
-    data_value text
-);
+COMMENT ON COLUMN public.charmrecipe.git_path IS 'The path of the Git branch containing a charmcraft.yaml recipe.';
 
 
-COMMENT ON TABLE public.codeimporteventdata IS 'Additional data associated to a particular code import event.';
+COMMENT ON COLUMN public.charmrecipe.build_path IS 'Subdirectory within the branch containing charmcraft.yaml.';
 
 
-COMMENT ON COLUMN public.codeimporteventdata.event IS 'The event the data is associated to.';
+COMMENT ON COLUMN public.charmrecipe.require_virtualized IS 'If True, this snap package must be built only on a virtual machine.';
 
 
-COMMENT ON COLUMN public.codeimporteventdata.data_type IS 'The type of additional data, from the CodeImportEventDataType enumeration.';
+COMMENT ON COLUMN public.charmrecipe.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
 
 
-COMMENT ON COLUMN public.codeimporteventdata.data_value IS 'The value of the additional data.  A string.';
+COMMENT ON COLUMN public.charmrecipe.auto_build IS 'Whether this charm recipe is built automatically when its branch changes.';
 
 
-CREATE SEQUENCE public.codeimporteventdata_id_seq
+COMMENT ON COLUMN public.charmrecipe.auto_build_channels IS 'A dictionary mapping snap names to channels to use when building this charm recipe.';
+
+
+COMMENT ON COLUMN public.charmrecipe.is_stale IS 'True if this charm recipe has not been built since a branch was updated.';
+
+
+COMMENT ON COLUMN public.charmrecipe.store_upload IS 'Whether builds of this charm recipe are automatically uploaded to the store.';
+
+
+COMMENT ON COLUMN public.charmrecipe.store_name IS 'The registered name of this charm in the store.';
+
+
+COMMENT ON COLUMN public.charmrecipe.store_secrets IS 'Serialized secrets issued by the store and the login service to authorize uploads of this charm.';
+
+
+COMMENT ON COLUMN public.charmrecipe.store_channels IS 'Channels to release this charm to after uploading it to the store.';
+
+
+CREATE SEQUENCE public.charmrecipe_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6387,232 +6608,230 @@ CREATE SEQUENCE public.codeimporteventdata_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.codeimporteventdata_id_seq OWNED BY public.codeimporteventdata.id;
+ALTER SEQUENCE public.charmrecipe_id_seq OWNED BY public.charmrecipe.id;
 
 
-CREATE TABLE public.codeimportjob (
+CREATE TABLE public.charmrecipebuild (
     id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    code_import integer NOT NULL,
-    machine integer,
-    date_due timestamp without time zone NOT NULL,
-    state integer NOT NULL,
-    requesting_user integer,
-    ordering integer,
-    heartbeat timestamp without time zone,
-    logtail text,
+    build_request integer NOT NULL,
+    requester integer NOT NULL,
+    recipe integer NOT NULL,
+    distro_arch_series integer NOT NULL,
+    channels jsonb,
+    processor integer NOT NULL,
+    virtualized boolean NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
     date_started timestamp without time zone,
-    CONSTRAINT valid_state CHECK (
-CASE
-    WHEN (state = 10) THEN (((((machine IS NULL) AND (ordering IS NULL)) AND (heartbeat IS NULL)) AND (date_started IS NULL)) AND (logtail IS NULL))
-    WHEN (state = 20) THEN (((((machine IS NOT NULL) AND (ordering IS NOT NULL)) AND (heartbeat IS NULL)) AND (date_started IS NULL)) AND (logtail IS NULL))
-    WHEN (state = 30) THEN (((((machine IS NOT NULL) AND (ordering IS NULL)) AND (heartbeat IS NOT NULL)) AND (date_started IS NOT NULL)) AND (logtail IS NOT NULL))
-    ELSE false
-END)
+    date_finished timestamp without time zone,
+    date_first_dispatched timestamp without time zone,
+    builder integer,
+    status integer NOT NULL,
+    log integer,
+    upload_log integer,
+    dependencies text,
+    failure_count integer DEFAULT 0 NOT NULL,
+    build_farm_job integer NOT NULL,
+    revision_id text,
+    store_upload_json_data jsonb
 );
 
 
-COMMENT ON TABLE public.codeimportjob IS 'A pending or active code import job.  There is always such a row for any active import, but it will not run until date_due is in the past.';
+COMMENT ON TABLE public.charmrecipebuild IS 'A build record for a charm recipe.';
 
 
-COMMENT ON COLUMN public.codeimportjob.code_import IS 'The code import that is being worked upon.';
+COMMENT ON COLUMN public.charmrecipebuild.build_request IS 'The build request that caused this build to be created.';
 
 
-COMMENT ON COLUMN public.codeimportjob.machine IS 'The machine job is currently scheduled to run on, or where the job is currently running.';
+COMMENT ON COLUMN public.charmrecipebuild.requester IS 'The person who requested this charm recipe build.';
 
 
-COMMENT ON COLUMN public.codeimportjob.date_due IS 'When the import should happen.';
+COMMENT ON COLUMN public.charmrecipebuild.recipe IS 'The charm recipe to build.';
 
 
-COMMENT ON COLUMN public.codeimportjob.state IS 'One of PENDING (waiting until its due or a machine is online), SCHEDULED (assigned to a machine, but not yet running) or RUNNING (actually in the process of being imported now).';
+COMMENT ON COLUMN public.charmrecipebuild.distro_arch_series IS 'The distroarchseries that the charm recipe should build from.';
 
 
-COMMENT ON COLUMN public.codeimportjob.requesting_user IS 'The user who requested the import, if any. Set if and only if reason = REQUEST.';
+COMMENT ON COLUMN public.charmrecipebuild.channels IS 'A dictionary mapping snap names to channels to use for this build.';
 
 
-COMMENT ON COLUMN public.codeimportjob.ordering IS 'A measure of how urgent the job is -- queue entries with lower "ordering" should be processed first, or in other works "ORDER BY ordering" returns the most import jobs first.';
+COMMENT ON COLUMN public.charmrecipebuild.processor IS 'The processor that the charm recipe should be built for.';
 
 
-COMMENT ON COLUMN public.codeimportjob.heartbeat IS 'While the job is running, this field should be updated frequently to indicate that the import job hasn''t crashed.';
+COMMENT ON COLUMN public.charmrecipebuild.virtualized IS 'The virtualization setting required by this build farm job.';
 
 
-COMMENT ON COLUMN public.codeimportjob.logtail IS 'The last few lines of output produced by the running job. It should be updated at the same time as the heartbeat.';
+COMMENT ON COLUMN public.charmrecipebuild.date_created IS 'When the build farm job record was created.';
 
 
-COMMENT ON COLUMN public.codeimportjob.date_started IS 'When the import began to be processed.';
+COMMENT ON COLUMN public.charmrecipebuild.date_started IS 'When the build farm job started being processed.';
 
 
-CREATE SEQUENCE public.codeimportjob_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.charmrecipebuild.date_finished IS 'When the build farm job finished being processed.';
 
 
-ALTER SEQUENCE public.codeimportjob_id_seq OWNED BY public.codeimportjob.id;
+COMMENT ON COLUMN public.charmrecipebuild.date_first_dispatched IS 'The instant the build was dispatched the first time.  This value will not get overridden if the build is retried.';
 
 
-CREATE TABLE public.codeimportmachine (
-    id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    hostname text NOT NULL,
-    state integer DEFAULT 10 NOT NULL,
-    heartbeat timestamp without time zone
-);
+COMMENT ON COLUMN public.charmrecipebuild.builder IS 'The builder which processed this build farm job.';
 
 
-COMMENT ON TABLE public.codeimportmachine IS 'The record of a machine capable of performing jobs for the code import system.';
+COMMENT ON COLUMN public.charmrecipebuild.status IS 'The current build status.';
 
 
-COMMENT ON COLUMN public.codeimportmachine.hostname IS 'The (unique) hostname of the machine.';
+COMMENT ON COLUMN public.charmrecipebuild.log IS 'The log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.codeimportmachine.state IS 'Whether the controller daemon on this machine is offline, online, or quiescing (running but not accepting new jobs).';
+COMMENT ON COLUMN public.charmrecipebuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.codeimportmachine.heartbeat IS 'When the code-import-controller daemon was last known to be running on this machine. If it is not updated for a long time the machine state will change to offline.';
+COMMENT ON COLUMN public.charmrecipebuild.dependencies IS 'A Debian-like dependency line specifying the current missing dependencies for this build.';
 
 
-CREATE SEQUENCE public.codeimportmachine_id_seq
-    START WITH 1
-    INCREMENT BY 1
+COMMENT ON COLUMN public.charmrecipebuild.failure_count IS 'The number of consecutive failures on this job.  If excessive, the job may be terminated.';
+
+
+COMMENT ON COLUMN public.charmrecipebuild.build_farm_job IS 'The build farm job with the base information.';
+
+
+COMMENT ON COLUMN public.charmrecipebuild.revision_id IS 'The revision ID of the branch used for this build, if available.';
+
+
+COMMENT ON COLUMN public.charmrecipebuild.store_upload_json_data IS 'Data that is related to the process of uploading a build to the store.';
+
+
+CREATE SEQUENCE public.charmrecipebuild_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
 
 
-ALTER SEQUENCE public.codeimportmachine_id_seq OWNED BY public.codeimportmachine.id;
+ALTER SEQUENCE public.charmrecipebuild_id_seq OWNED BY public.charmrecipebuild.id;
 
 
-CREATE TABLE public.codeimportresult (
-    id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    code_import integer,
-    machine integer,
-    requesting_user integer,
-    log_excerpt text,
-    log_file integer,
-    status integer NOT NULL,
-    date_job_started timestamp without time zone
+CREATE TABLE public.charmrecipebuildjob (
+    job integer NOT NULL,
+    build integer NOT NULL,
+    job_type integer NOT NULL,
+    json_data jsonb NOT NULL
 );
 
 
-COMMENT ON TABLE public.codeimportresult IS 'A completed code import job.';
+COMMENT ON TABLE public.charmrecipebuildjob IS 'Contains references to jobs that are executed for a build of a charm recipe.';
 
 
-COMMENT ON COLUMN public.codeimportresult.code_import IS 'The code import for which the job was run.';
+COMMENT ON COLUMN public.charmrecipebuildjob.job IS 'A reference to a Job row that has all the common job details.';
 
 
-COMMENT ON COLUMN public.codeimportresult.machine IS 'The machine the job ran on.';
+COMMENT ON COLUMN public.charmrecipebuildjob.build IS 'The charm recipe build that this job is for.';
 
 
-COMMENT ON COLUMN public.codeimportresult.log_excerpt IS 'The last few lines of the partial log, in case it is set.';
+COMMENT ON COLUMN public.charmrecipebuildjob.job_type IS 'The type of a job, such as a store upload.';
 
 
-COMMENT ON COLUMN public.codeimportresult.log_file IS 'A partial log of the job for users to see. It is normally only recorded if the job failed in a step that interacts with the remote repository. If a job was successful, or failed in a houskeeping step, the log file would not contain information useful to the user.';
+COMMENT ON COLUMN public.charmrecipebuildjob.json_data IS 'Data that is specific to a particular job type.';
 
 
-COMMENT ON COLUMN public.codeimportresult.status IS 'How the job ended. Success, some kind of failure, or some kind of interruption before completion.';
+CREATE TABLE public.charmrecipejob (
+    job integer NOT NULL,
+    recipe integer NOT NULL,
+    job_type integer NOT NULL,
+    json_data jsonb NOT NULL
+);
 
 
-COMMENT ON COLUMN public.codeimportresult.date_job_started IS 'When the job started to run (date_created is when it finished).';
+COMMENT ON TABLE public.charmrecipejob IS 'Contains references to jobs that are executed for a charm recipe.';
 
 
-CREATE SEQUENCE public.codeimportresult_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.charmrecipejob.job IS 'A reference to a Job row that has all the common job details.';
 
 
-ALTER SEQUENCE public.codeimportresult_id_seq OWNED BY public.codeimportresult.id;
+COMMENT ON COLUMN public.charmrecipejob.recipe IS 'The charm recipe that this job is for.';
 
 
-CREATE TABLE public.codereviewinlinecomment (
-    previewdiff integer NOT NULL,
-    person integer NOT NULL,
-    comment integer NOT NULL,
-    comments text NOT NULL
-);
+COMMENT ON COLUMN public.charmrecipejob.job_type IS 'The type of a job, such as a build request.';
 
 
-CREATE TABLE public.codereviewinlinecommentdraft (
-    previewdiff integer NOT NULL,
-    person integer NOT NULL,
-    comments text NOT NULL
-);
+COMMENT ON COLUMN public.charmrecipejob.json_data IS 'Data that is specific to a particular job type.';
 
 
-CREATE TABLE public.codereviewmessage (
+CREATE TABLE public.cibuild (
     id integer NOT NULL,
-    branch_merge_proposal integer NOT NULL,
-    message integer NOT NULL,
-    vote integer,
-    vote_tag text
+    git_repository integer NOT NULL,
+    commit_sha1 character(40) NOT NULL,
+    distro_arch_series integer NOT NULL,
+    processor integer NOT NULL,
+    virtualized boolean NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_started timestamp without time zone,
+    date_finished timestamp without time zone,
+    date_first_dispatched timestamp without time zone,
+    builder integer,
+    status integer NOT NULL,
+    log integer,
+    upload_log integer,
+    dependencies text,
+    failure_count integer DEFAULT 0 NOT NULL,
+    build_farm_job integer NOT NULL,
+    jobs jsonb
 );
 
 
-COMMENT ON TABLE public.codereviewmessage IS 'A message that is part of a code review discussion.';
+COMMENT ON TABLE public.cibuild IS 'A build record for a CI job.';
 
 
-COMMENT ON COLUMN public.codereviewmessage.branch_merge_proposal IS 'The merge proposal that is being discussed.';
+COMMENT ON COLUMN public.cibuild.git_repository IS 'The Git repository for this CI job.';
 
 
-COMMENT ON COLUMN public.codereviewmessage.message IS 'The actual message.';
+COMMENT ON COLUMN public.cibuild.commit_sha1 IS 'The Git commit ID for this CI job.';
 
 
-COMMENT ON COLUMN public.codereviewmessage.vote IS 'The reviewer''s vote for this message.';
+COMMENT ON COLUMN public.cibuild.distro_arch_series IS 'The distroarchseries that this CI job should run on.';
 
 
-COMMENT ON COLUMN public.codereviewmessage.vote_tag IS 'A short description of the vote';
+COMMENT ON COLUMN public.cibuild.processor IS 'The processor that this CI job should run on.';
 
 
-CREATE SEQUENCE public.codereviewmessage_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.cibuild.virtualized IS 'The virtualization setting required by this build farm job.';
 
 
-ALTER SEQUENCE public.codereviewmessage_id_seq OWNED BY public.codereviewmessage.id;
+COMMENT ON COLUMN public.cibuild.date_created IS 'When the build farm job record was created.';
 
 
-CREATE TABLE public.codereviewvote (
-    id integer NOT NULL,
-    branch_merge_proposal integer NOT NULL,
-    reviewer integer NOT NULL,
-    review_type text,
-    registrant integer NOT NULL,
-    vote_message integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
-);
+COMMENT ON COLUMN public.cibuild.date_started IS 'When the build farm job started being processed.';
 
 
-COMMENT ON TABLE public.codereviewvote IS 'Reference to a person''s last vote in a code review discussion.';
+COMMENT ON COLUMN public.cibuild.date_finished IS 'When the build farm job finished being processed.';
 
 
-COMMENT ON COLUMN public.codereviewvote.branch_merge_proposal IS 'The BranchMergeProposal for the code review.';
+COMMENT ON COLUMN public.cibuild.date_first_dispatched IS 'The instant the build was dispatched the first time.  This value will not get overridden if the build is retried.';
 
 
-COMMENT ON COLUMN public.codereviewvote.reviewer IS 'The person performing the review.';
+COMMENT ON COLUMN public.cibuild.builder IS 'The builder which processed this build farm job.';
 
 
-COMMENT ON COLUMN public.codereviewvote.review_type IS 'The aspect of the code being reviewed.';
+COMMENT ON COLUMN public.cibuild.status IS 'The current build status.';
 
 
-COMMENT ON COLUMN public.codereviewvote.registrant IS 'The person who registered this vote';
+COMMENT ON COLUMN public.cibuild.log IS 'The log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.codereviewvote.vote_message IS 'The message associated with the vote';
+COMMENT ON COLUMN public.cibuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.codereviewvote.date_created IS 'The date this vote reference was created';
+COMMENT ON COLUMN public.cibuild.failure_count IS 'The number of consecutive failures on this job.  If excessive, the job may be terminated.';
 
 
-CREATE SEQUENCE public.codereviewvote_id_seq
+COMMENT ON COLUMN public.cibuild.build_farm_job IS 'The build farm job with the base information.';
+
+
+COMMENT ON COLUMN public.cibuild.jobs IS 'The status of the individual jobs in this CI build.';
+
+
+CREATE SEQUENCE public.cibuild_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6620,92 +6839,76 @@ CREATE SEQUENCE public.codereviewvote_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.codereviewvote_id_seq OWNED BY public.codereviewvote.id;
-
-
-CREATE VIEW public.combinedbugsummary AS
- SELECT bugsummary.id,
-    bugsummary.count,
-    bugsummary.product,
-    bugsummary.productseries,
-    bugsummary.distribution,
-    bugsummary.distroseries,
-    bugsummary.sourcepackagename,
-    bugsummary.viewed_by,
-    bugsummary.tag,
-    bugsummary.status,
-    bugsummary.milestone,
-    bugsummary.importance,
-    bugsummary.has_patch,
-    bugsummary.access_policy
-   FROM public.bugsummary
-UNION ALL
- SELECT (- bugsummaryjournal.id) AS id,
-    bugsummaryjournal.count,
-    bugsummaryjournal.product,
-    bugsummaryjournal.productseries,
-    bugsummaryjournal.distribution,
-    bugsummaryjournal.distroseries,
-    bugsummaryjournal.sourcepackagename,
-    bugsummaryjournal.viewed_by,
-    bugsummaryjournal.tag,
-    bugsummaryjournal.status,
-    bugsummaryjournal.milestone,
-    bugsummaryjournal.importance,
-    bugsummaryjournal.has_patch,
-    bugsummaryjournal.access_policy
-   FROM public.bugsummaryjournal;
+ALTER SEQUENCE public.cibuild_id_seq OWNED BY public.cibuild.id;
 
 
-CREATE TABLE public.commercialsubscription (
+CREATE TABLE public.codeimport (
     id integer NOT NULL,
+    branch integer,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_starts timestamp without time zone NOT NULL,
-    date_expires timestamp without time zone NOT NULL,
-    status integer DEFAULT 10 NOT NULL,
-    product integer NOT NULL,
     registrant integer NOT NULL,
-    purchaser integer NOT NULL,
-    whiteboard text,
-    sales_system_id text
+    rcs_type integer NOT NULL,
+    cvs_root text,
+    cvs_module text,
+    review_status integer DEFAULT 1 NOT NULL,
+    date_last_successful timestamp without time zone,
+    owner integer NOT NULL,
+    assignee integer,
+    update_interval interval,
+    url text,
+    git_repository integer,
+    CONSTRAINT one_target_vcs CHECK (((branch IS NOT NULL) <> (git_repository IS NOT NULL))),
+    CONSTRAINT valid_source_target_vcs_pairing CHECK (((branch IS NOT NULL) OR (rcs_type = 4))),
+    CONSTRAINT valid_vcs_details CHECK (
+CASE
+    WHEN (rcs_type = 1) THEN ((cvs_root IS NOT NULL) AND (cvs_root <> ''::text) AND (cvs_module IS NOT NULL) AND (cvs_module <> ''::text) AND (url IS NULL))
+    WHEN (rcs_type = ANY (ARRAY[2, 3])) THEN ((cvs_root IS NULL) AND (cvs_module IS NULL) AND (url IS NOT NULL) AND public.valid_absolute_url(url))
+    WHEN (rcs_type = ANY (ARRAY[4, 5, 6])) THEN ((cvs_root IS NULL) AND (cvs_module IS NULL) AND (url IS NOT NULL))
+    ELSE false
+END)
 );
 
 
-COMMENT ON TABLE public.commercialsubscription IS 'A Commercial Subscription entry for a project.  Projects with licenses of Other/Proprietary must purchase a subscription in order to use Launchpad.';
+COMMENT ON TABLE public.codeimport IS 'The persistent record of an import from a foreign version control system to Bazaar, from the initial request to the regularly updated import branch.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.date_created IS 'The date this subscription was created in Launchpad.';
+COMMENT ON COLUMN public.codeimport.branch IS 'The Bazaar branch produced by the import system.  Always non-NULL: a placeholder branch is created when the import is created.  The import is associated to a Product and Series though the branch.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.date_last_modified IS 'The date this subscription was last modified.';
+COMMENT ON COLUMN public.codeimport.registrant IS 'The person who originally requested this import.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.date_starts IS 'The beginning date for this subscription.  It is invalid until that date.';
+COMMENT ON COLUMN public.codeimport.rcs_type IS 'The revision control system used by the import source. The value is defined in dbschema.RevisionControlSystems.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.date_expires IS 'The expiration date for this subscription.  It is invalid after that date.';
+COMMENT ON COLUMN public.codeimport.cvs_root IS 'The $CVSROOT details, probably of the form :pserver:user@host:/path.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.status IS 'The current status.  One of: SUBSCRIBED, LAPSED, SUSPENDED.';
+COMMENT ON COLUMN public.codeimport.cvs_module IS 'The module in cvs_root to import, often the name of the project.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.product IS 'The product this subscription enables.';
+COMMENT ON COLUMN public.codeimport.review_status IS 'Whether this code import request has been reviewed, and whether it was accepted.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.registrant IS 'The person who created this subscription.';
+COMMENT ON COLUMN public.codeimport.date_last_successful IS 'When this code import last succeeded. NULL if this import has never succeeded.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.purchaser IS 'The person who purchased this subscription.';
+COMMENT ON COLUMN public.codeimport.owner IS 'The person who is currently responsible for keeping the import details up to date, initially set to the registrant. This person can edit some of the details of the code import branch.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.whiteboard IS 'A place for administrators to store comments related to this subscription.';
+COMMENT ON COLUMN public.codeimport.assignee IS 'The person in charge of delivering this code import and interacting with the owner.';
 
 
-COMMENT ON COLUMN public.commercialsubscription.sales_system_id IS 'A reference in the external sales system (e.g. Salesforce) that can be used to identify this subscription.';
+COMMENT ON COLUMN public.codeimport.update_interval IS 'How often should this import be updated. If NULL, defaults to a system-wide value set by the Launchpad administrators.';
 
 
-CREATE SEQUENCE public.commercialsubscription_id_seq
+COMMENT ON COLUMN public.codeimport.url IS 'The URL of the foreign VCS branch for this import.';
+
+
+COMMENT ON COLUMN public.codeimport.git_repository IS 'The Git repository produced by the import system, if applicable.  A placeholder repository is created when the import is created.  The import is associated with a target through the repository.';
+
+
+CREATE SEQUENCE public.codeimport_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6713,27 +6916,35 @@ CREATE SEQUENCE public.commercialsubscription_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.commercialsubscription_id_seq OWNED BY public.commercialsubscription.id;
+ALTER SEQUENCE public.codeimport_id_seq OWNED BY public.codeimport.id;
 
 
-CREATE TABLE public.component (
+CREATE TABLE public.codeimportevent (
     id integer NOT NULL,
-    name text NOT NULL,
-    description text,
-    CONSTRAINT valid_name CHECK (public.valid_name(name))
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    entry_type integer NOT NULL,
+    code_import integer,
+    person integer,
+    machine integer
 );
 
 
-COMMENT ON TABLE public.component IS 'Known components in Launchpad';
+COMMENT ON TABLE public.codeimportevent IS 'A record of events in the code import system.  Rows in this table are created by triggers on other code import tables.';
 
 
-COMMENT ON COLUMN public.component.name IS 'Component name text';
+COMMENT ON COLUMN public.codeimportevent.entry_type IS 'The type of event that is recorded by this entry. Legal values are defined by the CodeImportEventType enumeration.';
 
 
-COMMENT ON COLUMN public.component.description IS 'Description of this component.';
+COMMENT ON COLUMN public.codeimportevent.code_import IS 'The code import that was associated to this event, if any and if it has not been deleted.';
 
 
-CREATE SEQUENCE public.component_id_seq
+COMMENT ON COLUMN public.codeimportevent.person IS 'The user who caused the event, if the event is not automatically generated.';
+
+
+COMMENT ON COLUMN public.codeimportevent.machine IS 'The code import machine that was concerned by this event, if any.';
+
+
+CREATE SEQUENCE public.codeimportevent_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6741,27 +6952,30 @@ CREATE SEQUENCE public.component_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.component_id_seq OWNED BY public.component.id;
+ALTER SEQUENCE public.codeimportevent_id_seq OWNED BY public.codeimportevent.id;
 
 
-CREATE TABLE public.componentselection (
+CREATE TABLE public.codeimporteventdata (
     id integer NOT NULL,
-    distroseries integer NOT NULL,
-    component integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+    event integer,
+    data_type integer NOT NULL,
+    data_value text
 );
 
 
-COMMENT ON TABLE public.componentselection IS 'Allowed components in a given distroseries.';
+COMMENT ON TABLE public.codeimporteventdata IS 'Additional data associated to a particular code import event.';
 
 
-COMMENT ON COLUMN public.componentselection.distroseries IS 'Refers to the distroseries in question.';
+COMMENT ON COLUMN public.codeimporteventdata.event IS 'The event the data is associated to.';
 
 
-COMMENT ON COLUMN public.componentselection.component IS 'Refers to the component in qestion.';
+COMMENT ON COLUMN public.codeimporteventdata.data_type IS 'The type of additional data, from the CodeImportEventDataType enumeration.';
 
 
-CREATE SEQUENCE public.componentselection_id_seq
+COMMENT ON COLUMN public.codeimporteventdata.data_value IS 'The value of the additional data.  A string.';
+
+
+CREATE SEQUENCE public.codeimporteventdata_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6769,91 +6983,62 @@ CREATE SEQUENCE public.componentselection_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.componentselection_id_seq OWNED BY public.componentselection.id;
+ALTER SEQUENCE public.codeimporteventdata_id_seq OWNED BY public.codeimporteventdata.id;
 
 
-CREATE TABLE public.continent (
+CREATE TABLE public.codeimportjob (
     id integer NOT NULL,
-    code text NOT NULL,
-    name text NOT NULL
-)
-WITH (fillfactor='100');
-
-
-COMMENT ON TABLE public.continent IS 'A continent in this huge world.';
-
-
-COMMENT ON COLUMN public.continent.code IS 'A two-letter code for a continent.';
-
-
-COMMENT ON COLUMN public.continent.name IS 'The name of the continent.';
-
-
-CREATE SEQUENCE public.continent_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
-
-
-ALTER SEQUENCE public.continent_id_seq OWNED BY public.continent.id;
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    code_import integer NOT NULL,
+    machine integer,
+    date_due timestamp without time zone NOT NULL,
+    state integer NOT NULL,
+    requesting_user integer,
+    ordering integer,
+    heartbeat timestamp without time zone,
+    logtail text,
+    date_started timestamp without time zone,
+    CONSTRAINT valid_state CHECK (
+CASE
+    WHEN (state = 10) THEN ((machine IS NULL) AND (ordering IS NULL) AND (heartbeat IS NULL) AND (date_started IS NULL) AND (logtail IS NULL))
+    WHEN (state = 20) THEN ((machine IS NOT NULL) AND (ordering IS NOT NULL) AND (heartbeat IS NULL) AND (date_started IS NULL) AND (logtail IS NULL))
+    WHEN (state = 30) THEN ((machine IS NOT NULL) AND (ordering IS NULL) AND (heartbeat IS NOT NULL) AND (date_started IS NOT NULL) AND (logtail IS NOT NULL))
+    ELSE false
+END)
+);
 
 
-CREATE TABLE public.country (
-    id integer NOT NULL,
-    iso3166code2 character(2) NOT NULL,
-    iso3166code3 character(3) NOT NULL,
-    name text NOT NULL,
-    title text,
-    description text,
-    continent integer NOT NULL
-)
-WITH (fillfactor='100');
+COMMENT ON TABLE public.codeimportjob IS 'A pending or active code import job.  There is always such a row for any active import, but it will not run until date_due is in the past.';
 
 
-CREATE SEQUENCE public.country_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.codeimportjob.code_import IS 'The code import that is being worked upon.';
 
 
-ALTER SEQUENCE public.country_id_seq OWNED BY public.country.id;
+COMMENT ON COLUMN public.codeimportjob.machine IS 'The machine job is currently scheduled to run on, or where the job is currently running.';
 
 
-CREATE TABLE public.customlanguagecode (
-    id integer NOT NULL,
-    product integer,
-    distribution integer,
-    sourcepackagename integer,
-    language_code text NOT NULL,
-    language integer,
-    CONSTRAINT distro_and_sourcepackage CHECK (((sourcepackagename IS NULL) = (distribution IS NULL))),
-    CONSTRAINT product_or_distro CHECK (((product IS NULL) <> (distribution IS NULL)))
-);
+COMMENT ON COLUMN public.codeimportjob.date_due IS 'When the import should happen.';
 
 
-COMMENT ON TABLE public.customlanguagecode IS 'Overrides translation importer''s interpretation of language codes where needed.';
+COMMENT ON COLUMN public.codeimportjob.state IS 'One of PENDING (waiting until its due or a machine is online), SCHEDULED (assigned to a machine, but not yet running) or RUNNING (actually in the process of being imported now).';
 
 
-COMMENT ON COLUMN public.customlanguagecode.product IS 'Product for which this custom language code applies (alternative to distribution + source package name).';
+COMMENT ON COLUMN public.codeimportjob.requesting_user IS 'The user who requested the import, if any. Set if and only if reason = REQUEST.';
 
 
-COMMENT ON COLUMN public.customlanguagecode.distribution IS 'Distribution in which this custom language code applies (if not a product).';
+COMMENT ON COLUMN public.codeimportjob.ordering IS 'A measure of how urgent the job is -- queue entries with lower "ordering" should be processed first, or in other works "ORDER BY ordering" returns the most import jobs first.';
 
 
-COMMENT ON COLUMN public.customlanguagecode.sourcepackagename IS 'Source package name to which this custom language code applies; goes with distribution.';
+COMMENT ON COLUMN public.codeimportjob.heartbeat IS 'While the job is running, this field should be updated frequently to indicate that the import job hasn''t crashed.';
 
 
-COMMENT ON COLUMN public.customlanguagecode.language_code IS 'Custom language code; need not be for a real language, and typically not for a "useful" language.';
+COMMENT ON COLUMN public.codeimportjob.logtail IS 'The last few lines of output produced by the running job. It should be updated at the same time as the heartbeat.';
 
 
-COMMENT ON COLUMN public.customlanguagecode.language IS 'Language to which code really refers in this context, or NULL if files with this code are to be rejected.';
+COMMENT ON COLUMN public.codeimportjob.date_started IS 'When the import began to be processed.';
 
 
-CREATE SEQUENCE public.customlanguagecode_id_seq
+CREATE SEQUENCE public.codeimportjob_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6861,34 +7046,31 @@ CREATE SEQUENCE public.customlanguagecode_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.customlanguagecode_id_seq OWNED BY public.customlanguagecode.id;
+ALTER SEQUENCE public.codeimportjob_id_seq OWNED BY public.codeimportjob.id;
 
 
-CREATE TABLE public.cve (
+CREATE TABLE public.codeimportmachine (
     id integer NOT NULL,
-    sequence text NOT NULL,
-    status integer NOT NULL,
-    description text NOT NULL,
-    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    datemodified timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    fti public.ts2_tsvector,
-    CONSTRAINT valid_cve_ref CHECK (public.valid_cve(sequence))
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    hostname text NOT NULL,
+    state integer DEFAULT 10 NOT NULL,
+    heartbeat timestamp without time zone
 );
 
 
-COMMENT ON TABLE public.cve IS 'A CVE Entry. The formal database of CVE entries is available at http://cve.mitre.org/ and we sync that database into Launchpad on a regular basis.';
+COMMENT ON TABLE public.codeimportmachine IS 'The record of a machine capable of performing jobs for the code import system.';
 
 
-COMMENT ON COLUMN public.cve.sequence IS 'The official CVE entry number. It takes the form XXXX-XXXX where the first four digits are a year indicator, like 2004, and the latter four are the sequence number of the vulnerability in that year.';
+COMMENT ON COLUMN public.codeimportmachine.hostname IS 'The (unique) hostname of the machine.';
 
 
-COMMENT ON COLUMN public.cve.status IS 'The current status of the CVE. The values are documented in dbschema.CVEState, and are Entry, Candidate, and Deprecated.';
+COMMENT ON COLUMN public.codeimportmachine.state IS 'Whether the controller daemon on this machine is offline, online, or quiescing (running but not accepting new jobs).';
 
 
-COMMENT ON COLUMN public.cve.datemodified IS 'The last time this CVE entry changed in some way - including addition or modification of references.';
+COMMENT ON COLUMN public.codeimportmachine.heartbeat IS 'When the code-import-controller daemon was last known to be running on this machine. If it is not updated for a long time the machine state will change to offline.';
 
 
-CREATE SEQUENCE public.cve_id_seq
+CREATE SEQUENCE public.codeimportmachine_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6896,32 +7078,44 @@ CREATE SEQUENCE public.cve_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.cve_id_seq OWNED BY public.cve.id;
+ALTER SEQUENCE public.codeimportmachine_id_seq OWNED BY public.codeimportmachine.id;
 
 
-CREATE TABLE public.cvereference (
+CREATE TABLE public.codeimportresult (
     id integer NOT NULL,
-    cve integer NOT NULL,
-    source text NOT NULL,
-    content text NOT NULL,
-    url text,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    code_import integer,
+    machine integer,
+    requesting_user integer,
+    log_excerpt text,
+    log_file integer,
+    status integer NOT NULL,
+    date_job_started timestamp without time zone
 );
 
 
-COMMENT ON TABLE public.cvereference IS 'A reference in the CVE system that shows what outside tracking numbers are associated with the CVE. These are tracked in the CVE database and extracted from the daily XML dump that we fetch.';
+COMMENT ON TABLE public.codeimportresult IS 'A completed code import job.';
 
 
-COMMENT ON COLUMN public.cvereference.source IS 'The SOURCE of the CVE reference. This is a text string, like XF or BUGTRAQ or MSKB. Each string indicates a different kind of reference. The list of known types is documented on the CVE web site. At some future date we might turn this into an enum rather than a text, but for the moment we prefer to keep it fluid and just suck in what CVE gives us. This means that CVE can add new source types without us having to update our code.';
+COMMENT ON COLUMN public.codeimportresult.code_import IS 'The code import for which the job was run.';
 
 
-COMMENT ON COLUMN public.cvereference.content IS 'The content of the ref in the CVE database. This is sometimes a comment, sometimes a description, sometimes a bug number... it is not predictable.';
+COMMENT ON COLUMN public.codeimportresult.machine IS 'The machine the job ran on.';
 
 
-COMMENT ON COLUMN public.cvereference.url IS 'The URL to this reference out there on the web, if it was present in the CVE database.';
+COMMENT ON COLUMN public.codeimportresult.log_excerpt IS 'The last few lines of the partial log, in case it is set.';
 
 
-CREATE SEQUENCE public.cvereference_id_seq
+COMMENT ON COLUMN public.codeimportresult.log_file IS 'A partial log of the job for users to see. It is normally only recorded if the job failed in a step that interacts with the remote repository. If a job was successful, or failed in a houskeeping step, the log file would not contain information useful to the user.';
+
+
+COMMENT ON COLUMN public.codeimportresult.status IS 'How the job ended. Success, some kind of failure, or some kind of interruption before completion.';
+
+
+COMMENT ON COLUMN public.codeimportresult.date_job_started IS 'When the job started to run (date_created is when it finished).';
+
+
+CREATE SEQUENCE public.codeimportresult_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -6929,117 +7123,92 @@ CREATE SEQUENCE public.cvereference_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.cvereference_id_seq OWNED BY public.cvereference.id;
-
-
-CREATE TABLE public.databasecpustats (
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    username text NOT NULL,
-    cpu integer NOT NULL
-)
-WITH (fillfactor='100');
+ALTER SEQUENCE public.codeimportresult_id_seq OWNED BY public.codeimportresult.id;
 
 
-COMMENT ON TABLE public.databasecpustats IS 'Snapshots of CPU utilization per database username.';
+CREATE TABLE public.codereviewinlinecomment (
+    previewdiff integer NOT NULL,
+    person integer NOT NULL,
+    comment integer NOT NULL,
+    comments text NOT NULL
+);
 
 
-COMMENT ON COLUMN public.databasecpustats.cpu IS '% CPU utilization * 100, as reported by ps -o cp';
+CREATE TABLE public.codereviewinlinecommentdraft (
+    previewdiff integer NOT NULL,
+    person integer NOT NULL,
+    comments text NOT NULL
+);
 
 
-CREATE TABLE public.databasediskutilization (
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    namespace text NOT NULL,
-    name text NOT NULL,
-    sub_namespace text,
-    sub_name text,
-    kind character(1) NOT NULL,
-    sort text NOT NULL,
-    table_len bigint NOT NULL,
-    tuple_count bigint NOT NULL,
-    tuple_len bigint NOT NULL,
-    tuple_percent double precision NOT NULL,
-    dead_tuple_count bigint NOT NULL,
-    dead_tuple_len bigint NOT NULL,
-    dead_tuple_percent double precision NOT NULL,
-    free_space bigint NOT NULL,
-    free_percent double precision NOT NULL
-)
-WITH (fillfactor='100');
+CREATE TABLE public.codereviewmessage (
+    id integer NOT NULL,
+    branch_merge_proposal integer NOT NULL,
+    message integer NOT NULL,
+    vote integer,
+    vote_tag text
+);
 
 
-CREATE TABLE public.databasereplicationlag (
-    node integer NOT NULL,
-    lag interval NOT NULL,
-    updated timestamp without time zone DEFAULT timezone('UTC'::text, now())
-);
+COMMENT ON TABLE public.codereviewmessage IS 'A message that is part of a code review discussion.';
 
 
-COMMENT ON TABLE public.databasereplicationlag IS 'A cached snapshot of database replication lag between our master Slony node and its slaves.';
+COMMENT ON COLUMN public.codereviewmessage.branch_merge_proposal IS 'The merge proposal that is being discussed.';
 
 
-COMMENT ON COLUMN public.databasereplicationlag.node IS 'The Slony node number identifying the slave database.';
+COMMENT ON COLUMN public.codereviewmessage.message IS 'The actual message.';
 
 
-COMMENT ON COLUMN public.databasereplicationlag.lag IS 'lag time.';
+COMMENT ON COLUMN public.codereviewmessage.vote IS 'The reviewer''s vote for this message.';
 
 
-COMMENT ON COLUMN public.databasereplicationlag.updated IS 'When this value was updated.';
+COMMENT ON COLUMN public.codereviewmessage.vote_tag IS 'A short description of the vote';
 
 
-CREATE TABLE public.databasetablestats (
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    schemaname name NOT NULL,
-    relname name NOT NULL,
-    seq_scan bigint NOT NULL,
-    seq_tup_read bigint NOT NULL,
-    idx_scan bigint NOT NULL,
-    idx_tup_fetch bigint NOT NULL,
-    n_tup_ins bigint NOT NULL,
-    n_tup_upd bigint NOT NULL,
-    n_tup_del bigint NOT NULL,
-    n_tup_hot_upd bigint NOT NULL,
-    n_live_tup bigint NOT NULL,
-    n_dead_tup bigint NOT NULL,
-    last_vacuum timestamp with time zone,
-    last_autovacuum timestamp with time zone,
-    last_analyze timestamp with time zone,
-    last_autoanalyze timestamp with time zone
-)
-WITH (fillfactor='100');
+CREATE SEQUENCE public.codereviewmessage_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON TABLE public.databasetablestats IS 'Snapshots of pg_stat_user_tables to let us calculate arbitrary deltas';
+ALTER SEQUENCE public.codereviewmessage_id_seq OWNED BY public.codereviewmessage.id;
 
 
-CREATE TABLE public.diff (
+CREATE TABLE public.codereviewvote (
     id integer NOT NULL,
-    diff_text integer,
-    diff_lines_count integer,
-    diffstat text,
-    added_lines_count integer,
-    removed_lines_count integer
+    branch_merge_proposal integer NOT NULL,
+    reviewer integer NOT NULL,
+    review_type text,
+    registrant integer NOT NULL,
+    vote_message integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
 );
 
 
-COMMENT ON TABLE public.diff IS 'Information common to static or preview diffs';
+COMMENT ON TABLE public.codereviewvote IS 'Reference to a person''s last vote in a code review discussion.';
 
 
-COMMENT ON COLUMN public.diff.diff_text IS 'The library copy of the fulltext of the diff';
+COMMENT ON COLUMN public.codereviewvote.branch_merge_proposal IS 'The BranchMergeProposal for the code review.';
 
 
-COMMENT ON COLUMN public.diff.diff_lines_count IS 'The number of lines in the diff';
+COMMENT ON COLUMN public.codereviewvote.reviewer IS 'The person performing the review.';
 
 
-COMMENT ON COLUMN public.diff.diffstat IS 'Statistics about the diff';
+COMMENT ON COLUMN public.codereviewvote.review_type IS 'The aspect of the code being reviewed.';
 
 
-COMMENT ON COLUMN public.diff.added_lines_count IS 'The number of lines added in the diff.';
+COMMENT ON COLUMN public.codereviewvote.registrant IS 'The person who registered this vote';
 
 
-COMMENT ON COLUMN public.diff.removed_lines_count IS 'The number of lines removed in the diff';
+COMMENT ON COLUMN public.codereviewvote.vote_message IS 'The message associated with the vote';
 
 
-CREATE SEQUENCE public.diff_id_seq
+COMMENT ON COLUMN public.codereviewvote.date_created IS 'The date this vote reference was created';
+
+
+CREATE SEQUENCE public.codereviewvote_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7047,165 +7216,208 @@ CREATE SEQUENCE public.diff_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.diff_id_seq OWNED BY public.diff.id;
+ALTER SEQUENCE public.codereviewvote_id_seq OWNED BY public.codereviewvote.id;
 
 
-CREATE TABLE public.distribution (
+CREATE VIEW public.combinedbugsummary AS
+ SELECT bugsummary.id,
+    bugsummary.count,
+    bugsummary.product,
+    bugsummary.productseries,
+    bugsummary.distribution,
+    bugsummary.distroseries,
+    bugsummary.sourcepackagename,
+    bugsummary.viewed_by,
+    bugsummary.tag,
+    bugsummary.status,
+    bugsummary.milestone,
+    bugsummary.importance,
+    bugsummary.has_patch,
+    bugsummary.access_policy,
+    bugsummary.ociproject,
+    bugsummary.ociprojectseries
+   FROM public.bugsummary
+UNION ALL
+ SELECT (- bugsummaryjournal.id) AS id,
+    bugsummaryjournal.count,
+    bugsummaryjournal.product,
+    bugsummaryjournal.productseries,
+    bugsummaryjournal.distribution,
+    bugsummaryjournal.distroseries,
+    bugsummaryjournal.sourcepackagename,
+    bugsummaryjournal.viewed_by,
+    bugsummaryjournal.tag,
+    bugsummaryjournal.status,
+    bugsummaryjournal.milestone,
+    bugsummaryjournal.importance,
+    bugsummaryjournal.has_patch,
+    bugsummaryjournal.access_policy,
+    bugsummaryjournal.ociproject,
+    bugsummaryjournal.ociprojectseries
+   FROM public.bugsummaryjournal;
+
+
+CREATE TABLE public.commercialsubscription (
     id integer NOT NULL,
-    name text NOT NULL,
-    title text NOT NULL,
-    description text NOT NULL,
-    domainname text NOT NULL,
-    owner integer NOT NULL,
-    displayname text NOT NULL,
-    summary text NOT NULL,
-    members integer NOT NULL,
-    translationgroup integer,
-    translationpermission integer DEFAULT 1 NOT NULL,
-    bug_supervisor integer,
-    official_malone boolean DEFAULT false NOT NULL,
-    official_rosetta boolean DEFAULT false NOT NULL,
-    driver integer,
-    translation_focus integer,
-    mirror_admin integer NOT NULL,
-    upload_sender text,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    homepage_content text,
-    icon integer,
-    mugshot integer,
-    logo integer,
-    fti public.ts2_tsvector,
-    official_answers boolean DEFAULT false NOT NULL,
-    language_pack_admin integer,
-    official_blueprints boolean DEFAULT false NOT NULL,
-    enable_bug_expiration boolean DEFAULT false NOT NULL,
-    bug_reporting_guidelines text,
-    reviewer_whiteboard text,
-    max_bug_heat integer,
-    bug_reported_acknowledgement text,
-    answers_usage integer DEFAULT 10 NOT NULL,
-    blueprints_usage integer DEFAULT 10 NOT NULL,
-    translations_usage integer DEFAULT 10 NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_starts timestamp without time zone NOT NULL,
+    date_expires timestamp without time zone NOT NULL,
+    status integer DEFAULT 10 NOT NULL,
+    product integer,
     registrant integer NOT NULL,
-    package_derivatives_email text,
-    redirect_release_uploads boolean DEFAULT false NOT NULL,
-    development_series_alias text,
-    official_packages boolean DEFAULT false NOT NULL,
-    supports_ppas boolean DEFAULT false NOT NULL,
-    supports_mirrors boolean DEFAULT false NOT NULL,
-    vcs integer,
-    CONSTRAINT only_launchpad_has_expiration CHECK (((enable_bug_expiration IS FALSE) OR (official_malone IS TRUE))),
-    CONSTRAINT valid_name CHECK (public.valid_name(name))
+    purchaser integer NOT NULL,
+    whiteboard text,
+    sales_system_id text,
+    distribution integer,
+    CONSTRAINT one_pillar CHECK ((public.null_count(ARRAY[product, distribution]) = 1))
 );
 
 
-COMMENT ON TABLE public.distribution IS 'Distribution: A soyuz distribution. A distribution is a collection of DistroSeries. Distributions often group together policy and may be referred to by a name such as "Ubuntu" or "Debian"';
-
-
-COMMENT ON COLUMN public.distribution.name IS 'The unique name of the distribution as a short lowercase name suitable for use in a URL.';
+COMMENT ON TABLE public.commercialsubscription IS 'A Commercial Subscription entry for a project.  Projects with licenses of Other/Proprietary must purchase a subscription in order to use Launchpad.';
 
 
-COMMENT ON COLUMN public.distribution.title IS 'The title of the distribution. More a "display name" as it were. E.g. "Ubuntu" or "Debian GNU/Linux"';
+COMMENT ON COLUMN public.commercialsubscription.date_created IS 'The date this subscription was created in Launchpad.';
 
 
-COMMENT ON COLUMN public.distribution.description IS 'A description of the distribution. More detailed than the title, this column may also contain information about the project this distribution is run by.';
+COMMENT ON COLUMN public.commercialsubscription.date_last_modified IS 'The date this subscription was last modified.';
 
 
-COMMENT ON COLUMN public.distribution.domainname IS 'The domain name of the distribution. This may be used both for linking to the distribution and for context-related stuff.';
+COMMENT ON COLUMN public.commercialsubscription.date_starts IS 'The beginning date for this subscription.  It is invalid until that date.';
 
 
-COMMENT ON COLUMN public.distribution.owner IS 'The person in launchpad who is in ultimate-charge of this distribution within launchpad.';
+COMMENT ON COLUMN public.commercialsubscription.date_expires IS 'The expiration date for this subscription.  It is invalid after that date.';
 
 
-COMMENT ON COLUMN public.distribution.displayname IS 'A short, well-capitalised
-name for this distribution that is not required to be unique but in almost
-all cases would be so.';
+COMMENT ON COLUMN public.commercialsubscription.status IS 'The current status.  One of: SUBSCRIBED, LAPSED, SUSPENDED.';
 
 
-COMMENT ON COLUMN public.distribution.summary IS 'A single paragraph that
-summarises the highlights of this distribution. It should be no longer than
-240 characters, although this is not enforced in the database.';
+COMMENT ON COLUMN public.commercialsubscription.product IS 'The product this subscription enables.';
 
 
-COMMENT ON COLUMN public.distribution.members IS 'Person or team with upload and commit priviledges relating to this distribution. Other rights may be assigned to this role in the future.';
+COMMENT ON COLUMN public.commercialsubscription.registrant IS 'The person who created this subscription.';
 
 
-COMMENT ON COLUMN public.distribution.translationgroup IS 'The translation group that is responsible for all translation work in this distribution.';
+COMMENT ON COLUMN public.commercialsubscription.purchaser IS 'The person who purchased this subscription.';
 
 
-COMMENT ON COLUMN public.distribution.translationpermission IS 'The level of openness of this distribution''s translation process. The enum lists different approaches to translation, from the very open (anybody can edit any translation in any language) to the completely closed (only designated translators can make any changes at all).';
+COMMENT ON COLUMN public.commercialsubscription.whiteboard IS 'A place for administrators to store comments related to this subscription.';
 
 
-COMMENT ON COLUMN public.distribution.bug_supervisor IS 'Person who is responsible for managing bugs on this distribution.';
+COMMENT ON COLUMN public.commercialsubscription.sales_system_id IS 'A reference in the external sales system (e.g. Salesforce) that can be used to identify this subscription.';
 
 
-COMMENT ON COLUMN public.distribution.official_malone IS 'Whether or not this distribution uses Malone for an official bug tracker.';
+COMMENT ON COLUMN public.commercialsubscription.distribution IS 'The distribution this subscription enables.';
 
 
-COMMENT ON COLUMN public.distribution.official_rosetta IS 'Whether or not this distribution uses Rosetta for its official translation team and coordination.';
+CREATE SEQUENCE public.commercialsubscription_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distribution.driver IS 'The team or person responsible for approving goals for each release in the distribution. This should usually be a very small team because the Distribution driver can approve items for backporting to past releases as well as the current release under development. Each distroseries has its own driver too, so you can have the small superset in the Distribution driver, and then specific teams per distroseries for backporting, for example, or for the current release management team on the current development focus release.';
+ALTER SEQUENCE public.commercialsubscription_id_seq OWNED BY public.commercialsubscription.id;
 
 
-COMMENT ON COLUMN public.distribution.translation_focus IS 'The DistroSeries that should get the translation effort focus.';
+CREATE TABLE public.component (
+    id integer NOT NULL,
+    name text NOT NULL,
+    description text,
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
+);
 
 
-COMMENT ON COLUMN public.distribution.mirror_admin IS 'Person or team with privileges to mark a mirror as official.';
+COMMENT ON TABLE public.component IS 'Known components in Launchpad';
 
 
-COMMENT ON COLUMN public.distribution.upload_sender IS 'The email address (and name) of the default sender used by the upload processor. If NULL, we fall back to the default sender in the launchpad config.';
+COMMENT ON COLUMN public.component.name IS 'Component name text';
 
 
-COMMENT ON COLUMN public.distribution.homepage_content IS 'A home page for this distribution in the Launchpad.';
+COMMENT ON COLUMN public.component.description IS 'Description of this component.';
 
 
-COMMENT ON COLUMN public.distribution.icon IS 'The library file alias to a small image to be used as an icon whenever we are referring to a distribution.';
+CREATE SEQUENCE public.component_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distribution.mugshot IS 'The library file alias of a mugshot image to display as the branding of a distribution, on its home page.';
+ALTER SEQUENCE public.component_id_seq OWNED BY public.component.id;
 
 
-COMMENT ON COLUMN public.distribution.logo IS 'The library file alias of a smaller version of this distributions''s mugshot.';
+CREATE TABLE public.componentselection (
+    id integer NOT NULL,
+    distroseries integer NOT NULL,
+    component integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+);
 
 
-COMMENT ON COLUMN public.distribution.official_answers IS 'Whether or not this product upstream uses Answers officialy.';
+COMMENT ON TABLE public.componentselection IS 'Allowed components in a given distroseries.';
 
 
-COMMENT ON COLUMN public.distribution.language_pack_admin IS 'The Person or Team that handle language packs for the distro release.';
+COMMENT ON COLUMN public.componentselection.distroseries IS 'Refers to the distroseries in question.';
 
 
-COMMENT ON COLUMN public.distribution.enable_bug_expiration IS 'Indicates whether automatic bug expiration is enabled.';
+COMMENT ON COLUMN public.componentselection.component IS 'Refers to the component in qestion.';
 
 
-COMMENT ON COLUMN public.distribution.bug_reporting_guidelines IS 'Guidelines to the end user for reporting bugs on this distribution.';
+CREATE SEQUENCE public.componentselection_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distribution.reviewer_whiteboard IS 'A whiteboard for Launchpad admins, registry experts and the project owners to capture the state of current issues with the project.';
+ALTER SEQUENCE public.componentselection_id_seq OWNED BY public.componentselection.id;
 
 
-COMMENT ON COLUMN public.distribution.max_bug_heat IS 'The highest heat value across bugs for this distribution.';
+CREATE TABLE public.continent (
+    id integer NOT NULL,
+    code text NOT NULL,
+    name text NOT NULL
+)
+WITH (fillfactor='100');
 
 
-COMMENT ON COLUMN public.distribution.bug_reported_acknowledgement IS 'A message of acknowledgement to display to a bug reporter after they''ve reported a new bug.';
+COMMENT ON TABLE public.continent IS 'A continent in this huge world.';
 
 
-COMMENT ON COLUMN public.distribution.registrant IS 'The person in launchpad who registered this distribution.';
+COMMENT ON COLUMN public.continent.code IS 'A two-letter code for a continent.';
 
 
-COMMENT ON COLUMN public.distribution.package_derivatives_email IS 'The optional email address template to use when sending emails about package updates in a distributrion. The string {package_name} in the template will be replaced with the actual package name being updated.';
+COMMENT ON COLUMN public.continent.name IS 'The name of the continent.';
 
 
-COMMENT ON COLUMN public.distribution.redirect_release_uploads IS 'Whether uploads to the release pocket of this distribution should be redirected to the proposed pocket instead.';
+CREATE SEQUENCE public.continent_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distribution.development_series_alias IS 'If set, an alias for the current development series in this distribution.';
+ALTER SEQUENCE public.continent_id_seq OWNED BY public.continent.id;
 
 
-COMMENT ON COLUMN public.distribution.vcs IS 'An enumeration specifying the default version control system for this distribution.';
+CREATE TABLE public.country (
+    id integer NOT NULL,
+    iso3166code2 character(2) NOT NULL,
+    iso3166code3 character(3) NOT NULL,
+    name text NOT NULL,
+    title text,
+    description text,
+    continent integer NOT NULL
+)
+WITH (fillfactor='100');
 
 
-CREATE SEQUENCE public.distribution_id_seq
+CREATE SEQUENCE public.country_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7213,35 +7425,40 @@ CREATE SEQUENCE public.distribution_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distribution_id_seq OWNED BY public.distribution.id;
+ALTER SEQUENCE public.country_id_seq OWNED BY public.country.id;
 
 
-CREATE TABLE public.distributionjob (
+CREATE TABLE public.customlanguagecode (
     id integer NOT NULL,
-    job integer NOT NULL,
-    distribution integer NOT NULL,
-    distroseries integer,
-    job_type integer NOT NULL,
-    json_data text
+    product integer,
+    distribution integer,
+    sourcepackagename integer,
+    language_code text NOT NULL,
+    language integer,
+    CONSTRAINT distro_and_sourcepackage CHECK (((sourcepackagename IS NULL) = (distribution IS NULL))),
+    CONSTRAINT product_or_distro CHECK (((product IS NULL) <> (distribution IS NULL)))
 );
 
 
-COMMENT ON TABLE public.distributionjob IS 'Contains references to jobs to be run on distributions.';
+COMMENT ON TABLE public.customlanguagecode IS 'Overrides translation importer''s interpretation of language codes where needed.';
 
 
-COMMENT ON COLUMN public.distributionjob.distribution IS 'The distribution to be acted on.';
+COMMENT ON COLUMN public.customlanguagecode.product IS 'Product for which this custom language code applies (alternative to distribution + source package name).';
 
 
-COMMENT ON COLUMN public.distributionjob.distroseries IS 'The distroseries to be acted on.';
+COMMENT ON COLUMN public.customlanguagecode.distribution IS 'Distribution in which this custom language code applies (if not a product).';
 
 
-COMMENT ON COLUMN public.distributionjob.job_type IS 'The type of job';
+COMMENT ON COLUMN public.customlanguagecode.sourcepackagename IS 'Source package name to which this custom language code applies; goes with distribution.';
 
 
-COMMENT ON COLUMN public.distributionjob.json_data IS 'A JSON struct containing data for the job.';
+COMMENT ON COLUMN public.customlanguagecode.language_code IS 'Custom language code; need not be for a real language, and typically not for a "useful" language.';
 
 
-CREATE SEQUENCE public.distributionjob_id_seq
+COMMENT ON COLUMN public.customlanguagecode.language IS 'Language to which code really refers in this context, or NULL if files with this code are to be rejected.';
+
+
+CREATE SEQUENCE public.customlanguagecode_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7249,99 +7466,1047 @@ CREATE SEQUENCE public.distributionjob_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distributionjob_id_seq OWNED BY public.distributionjob.id;
+ALTER SEQUENCE public.customlanguagecode_id_seq OWNED BY public.customlanguagecode.id;
 
 
-CREATE TABLE public.distributionmirror (
+CREATE TABLE public.cve (
     id integer NOT NULL,
-    distribution integer NOT NULL,
-    name text NOT NULL,
-    http_base_url text,
-    ftp_base_url text,
-    rsync_base_url text,
-    displayname text,
-    description text,
-    owner integer NOT NULL,
-    speed integer NOT NULL,
-    country integer NOT NULL,
-    content integer NOT NULL,
-    official_candidate boolean DEFAULT false NOT NULL,
-    enabled boolean DEFAULT false NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    whiteboard text,
-    status integer DEFAULT 10 NOT NULL,
-    date_reviewed timestamp without time zone,
-    reviewer integer,
-    country_dns_mirror boolean DEFAULT false NOT NULL,
-    CONSTRAINT one_or_more_urls CHECK ((((http_base_url IS NOT NULL) OR (ftp_base_url IS NOT NULL)) OR (rsync_base_url IS NOT NULL))),
+    sequence text NOT NULL,
+    status integer NOT NULL,
+    description text NOT NULL,
+    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    datemodified timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    fti public.ts2_tsvector,
+    date_made_public timestamp without time zone,
+    discoverer integer,
+    cvss jsonb,
+    CONSTRAINT valid_cve_ref CHECK (public.valid_cve(sequence))
+);
+
+
+COMMENT ON TABLE public.cve IS 'A CVE Entry. The formal database of CVE entries is available at http://cve.mitre.org/ and we sync that database into Launchpad on a regular basis.';
+
+
+COMMENT ON COLUMN public.cve.sequence IS 'The official CVE entry number. It takes the form XXXX-XXXX where the first four digits are a year indicator, like 2004, and the latter four are the sequence number of the vulnerability in that year.';
+
+
+COMMENT ON COLUMN public.cve.status IS 'The current status of the CVE. The values are documented in dbschema.CVEState, and are Entry, Candidate, and Deprecated.';
+
+
+COMMENT ON COLUMN public.cve.datemodified IS 'The last time this CVE entry changed in some way - including addition or modification of references.';
+
+
+COMMENT ON COLUMN public.cve.date_made_public IS 'The date on which the CVE was made public.';
+
+
+COMMENT ON COLUMN public.cve.discoverer IS 'The person who discovered this CVE.';
+
+
+COMMENT ON COLUMN public.cve.cvss IS 'The CVSS score for this CVE.';
+
+
+CREATE SEQUENCE public.cve_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.cve_id_seq OWNED BY public.cve.id;
+
+
+CREATE TABLE public.cvereference (
+    id integer NOT NULL,
+    cve integer NOT NULL,
+    source text NOT NULL,
+    content text NOT NULL,
+    url text,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+);
+
+
+COMMENT ON TABLE public.cvereference IS 'A reference in the CVE system that shows what outside tracking numbers are associated with the CVE. These are tracked in the CVE database and extracted from the daily XML dump that we fetch.';
+
+
+COMMENT ON COLUMN public.cvereference.source IS 'The SOURCE of the CVE reference. This is a text string, like XF or BUGTRAQ or MSKB. Each string indicates a different kind of reference. The list of known types is documented on the CVE web site. At some future date we might turn this into an enum rather than a text, but for the moment we prefer to keep it fluid and just suck in what CVE gives us. This means that CVE can add new source types without us having to update our code.';
+
+
+COMMENT ON COLUMN public.cvereference.content IS 'The content of the ref in the CVE database. This is sometimes a comment, sometimes a description, sometimes a bug number... it is not predictable.';
+
+
+COMMENT ON COLUMN public.cvereference.url IS 'The URL to this reference out there on the web, if it was present in the CVE database.';
+
+
+CREATE SEQUENCE public.cvereference_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.cvereference_id_seq OWNED BY public.cvereference.id;
+
+
+CREATE TABLE public.databasecpustats (
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    username text NOT NULL,
+    cpu integer NOT NULL
+)
+WITH (fillfactor='100');
+
+
+COMMENT ON TABLE public.databasecpustats IS 'Snapshots of CPU utilization per database username.';
+
+
+COMMENT ON COLUMN public.databasecpustats.cpu IS '% CPU utilization * 100, as reported by ps -o cp';
+
+
+CREATE TABLE public.databasediskutilization (
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    namespace text NOT NULL,
+    name text NOT NULL,
+    sub_namespace text,
+    sub_name text,
+    kind character(1) NOT NULL,
+    sort text NOT NULL,
+    table_len bigint NOT NULL,
+    tuple_count bigint NOT NULL,
+    tuple_len bigint NOT NULL,
+    tuple_percent double precision NOT NULL,
+    dead_tuple_count bigint NOT NULL,
+    dead_tuple_len bigint NOT NULL,
+    dead_tuple_percent double precision NOT NULL,
+    free_space bigint NOT NULL,
+    free_percent double precision NOT NULL
+)
+WITH (fillfactor='100');
+
+
+CREATE TABLE public.databasereplicationlag (
+    node integer NOT NULL,
+    lag interval NOT NULL,
+    updated timestamp without time zone DEFAULT timezone('UTC'::text, now())
+);
+
+
+COMMENT ON TABLE public.databasereplicationlag IS 'A cached snapshot of database replication lag between our master Slony node and its slaves.';
+
+
+COMMENT ON COLUMN public.databasereplicationlag.node IS 'The Slony node number identifying the slave database.';
+
+
+COMMENT ON COLUMN public.databasereplicationlag.lag IS 'lag time.';
+
+
+COMMENT ON COLUMN public.databasereplicationlag.updated IS 'When this value was updated.';
+
+
+CREATE TABLE public.databasetablestats (
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    schemaname name NOT NULL,
+    relname name NOT NULL,
+    seq_scan bigint NOT NULL,
+    seq_tup_read bigint NOT NULL,
+    idx_scan bigint NOT NULL,
+    idx_tup_fetch bigint NOT NULL,
+    n_tup_ins bigint NOT NULL,
+    n_tup_upd bigint NOT NULL,
+    n_tup_del bigint NOT NULL,
+    n_tup_hot_upd bigint NOT NULL,
+    n_live_tup bigint NOT NULL,
+    n_dead_tup bigint NOT NULL,
+    last_vacuum timestamp with time zone,
+    last_autovacuum timestamp with time zone,
+    last_analyze timestamp with time zone,
+    last_autoanalyze timestamp with time zone
+)
+WITH (fillfactor='100');
+
+
+COMMENT ON TABLE public.databasetablestats IS 'Snapshots of pg_stat_user_tables to let us calculate arbitrary deltas';
+
+
+CREATE TABLE public.diff (
+    id integer NOT NULL,
+    diff_text integer,
+    diff_lines_count integer,
+    diffstat text,
+    added_lines_count integer,
+    removed_lines_count integer
+);
+
+
+COMMENT ON TABLE public.diff IS 'Information common to static or preview diffs';
+
+
+COMMENT ON COLUMN public.diff.diff_text IS 'The library copy of the fulltext of the diff';
+
+
+COMMENT ON COLUMN public.diff.diff_lines_count IS 'The number of lines in the diff';
+
+
+COMMENT ON COLUMN public.diff.diffstat IS 'Statistics about the diff';
+
+
+COMMENT ON COLUMN public.diff.added_lines_count IS 'The number of lines added in the diff.';
+
+
+COMMENT ON COLUMN public.diff.removed_lines_count IS 'The number of lines removed in the diff';
+
+
+CREATE SEQUENCE public.diff_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.diff_id_seq OWNED BY public.diff.id;
+
+
+CREATE TABLE public.distribution (
+    id integer NOT NULL,
+    name text NOT NULL,
+    title text NOT NULL,
+    description text NOT NULL,
+    domainname text NOT NULL,
+    owner integer NOT NULL,
+    displayname text NOT NULL,
+    summary text NOT NULL,
+    members integer NOT NULL,
+    translationgroup integer,
+    translationpermission integer DEFAULT 1 NOT NULL,
+    bug_supervisor integer,
+    official_malone boolean DEFAULT false NOT NULL,
+    official_rosetta boolean DEFAULT false NOT NULL,
+    driver integer,
+    translation_focus integer,
+    mirror_admin integer NOT NULL,
+    upload_sender text,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    homepage_content text,
+    icon integer,
+    mugshot integer,
+    logo integer,
+    fti public.ts2_tsvector,
+    official_answers boolean DEFAULT false NOT NULL,
+    language_pack_admin integer,
+    official_blueprints boolean DEFAULT false NOT NULL,
+    enable_bug_expiration boolean DEFAULT false NOT NULL,
+    bug_reporting_guidelines text,
+    reviewer_whiteboard text,
+    max_bug_heat integer,
+    bug_reported_acknowledgement text,
+    answers_usage integer DEFAULT 10 NOT NULL,
+    blueprints_usage integer DEFAULT 10 NOT NULL,
+    translations_usage integer DEFAULT 10 NOT NULL,
+    registrant integer NOT NULL,
+    package_derivatives_email text,
+    redirect_release_uploads boolean DEFAULT false NOT NULL,
+    development_series_alias text,
+    official_packages boolean DEFAULT false NOT NULL,
+    supports_ppas boolean DEFAULT false NOT NULL,
+    supports_mirrors boolean DEFAULT false NOT NULL,
+    vcs integer,
+    oci_project_admin integer,
+    default_traversal_policy integer DEFAULT 0 NOT NULL,
+    redirect_default_traversal boolean DEFAULT false NOT NULL,
+    oci_credentials integer,
+    branch_sharing_policy integer DEFAULT 1 NOT NULL,
+    bug_sharing_policy integer DEFAULT 1 NOT NULL,
+    specification_sharing_policy integer DEFAULT 1 NOT NULL,
+    information_type integer DEFAULT 1 NOT NULL,
+    access_policies integer[],
+    security_admin integer,
+    CONSTRAINT distribution__valid_information_type CHECK ((information_type = ANY (ARRAY[1, 5, 6]))),
+    CONSTRAINT only_launchpad_has_expiration CHECK (((enable_bug_expiration IS FALSE) OR (official_malone IS TRUE))),
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
+);
+
+
+COMMENT ON TABLE public.distribution IS 'Distribution: A soyuz distribution. A distribution is a collection of DistroSeries. Distributions often group together policy and may be referred to by a name such as "Ubuntu" or "Debian"';
+
+
+COMMENT ON COLUMN public.distribution.name IS 'The unique name of the distribution as a short lowercase name suitable for use in a URL.';
+
+
+COMMENT ON COLUMN public.distribution.title IS 'The title of the distribution. More a "display name" as it were. E.g. "Ubuntu" or "Debian GNU/Linux"';
+
+
+COMMENT ON COLUMN public.distribution.description IS 'A description of the distribution. More detailed than the title, this column may also contain information about the project this distribution is run by.';
+
+
+COMMENT ON COLUMN public.distribution.domainname IS 'The domain name of the distribution. This may be used both for linking to the distribution and for context-related stuff.';
+
+
+COMMENT ON COLUMN public.distribution.owner IS 'The person in launchpad who is in ultimate-charge of this distribution within launchpad.';
+
+
+COMMENT ON COLUMN public.distribution.displayname IS 'A short, well-capitalised
+name for this distribution that is not required to be unique but in almost
+all cases would be so.';
+
+
+COMMENT ON COLUMN public.distribution.summary IS 'A single paragraph that
+summarises the highlights of this distribution. It should be no longer than
+240 characters, although this is not enforced in the database.';
+
+
+COMMENT ON COLUMN public.distribution.members IS 'Person or team with upload and commit priviledges relating to this distribution. Other rights may be assigned to this role in the future.';
+
+
+COMMENT ON COLUMN public.distribution.translationgroup IS 'The translation group that is responsible for all translation work in this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.translationpermission IS 'The level of openness of this distribution''s translation process. The enum lists different approaches to translation, from the very open (anybody can edit any translation in any language) to the completely closed (only designated translators can make any changes at all).';
+
+
+COMMENT ON COLUMN public.distribution.bug_supervisor IS 'Person who is responsible for managing bugs on this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.official_malone IS 'Whether or not this distribution uses Malone for an official bug tracker.';
+
+
+COMMENT ON COLUMN public.distribution.official_rosetta IS 'Whether or not this distribution uses Rosetta for its official translation team and coordination.';
+
+
+COMMENT ON COLUMN public.distribution.driver IS 'The team or person responsible for approving goals for each release in the distribution. This should usually be a very small team because the Distribution driver can approve items for backporting to past releases as well as the current release under development. Each distroseries has its own driver too, so you can have the small superset in the Distribution driver, and then specific teams per distroseries for backporting, for example, or for the current release management team on the current development focus release.';
+
+
+COMMENT ON COLUMN public.distribution.translation_focus IS 'The DistroSeries that should get the translation effort focus.';
+
+
+COMMENT ON COLUMN public.distribution.mirror_admin IS 'Person or team with privileges to mark a mirror as official.';
+
+
+COMMENT ON COLUMN public.distribution.upload_sender IS 'The email address (and name) of the default sender used by the upload processor. If NULL, we fall back to the default sender in the launchpad config.';
+
+
+COMMENT ON COLUMN public.distribution.homepage_content IS 'A home page for this distribution in the Launchpad.';
+
+
+COMMENT ON COLUMN public.distribution.icon IS 'The library file alias to a small image to be used as an icon whenever we are referring to a distribution.';
+
+
+COMMENT ON COLUMN public.distribution.mugshot IS 'The library file alias of a mugshot image to display as the branding of a distribution, on its home page.';
+
+
+COMMENT ON COLUMN public.distribution.logo IS 'The library file alias of a smaller version of this distributions''s mugshot.';
+
+
+COMMENT ON COLUMN public.distribution.official_answers IS 'Whether or not this product upstream uses Answers officialy.';
+
+
+COMMENT ON COLUMN public.distribution.language_pack_admin IS 'The Person or Team that handle language packs for the distro release.';
+
+
+COMMENT ON COLUMN public.distribution.enable_bug_expiration IS 'Indicates whether automatic bug expiration is enabled.';
+
+
+COMMENT ON COLUMN public.distribution.bug_reporting_guidelines IS 'Guidelines to the end user for reporting bugs on this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.reviewer_whiteboard IS 'A whiteboard for Launchpad admins, registry experts and the project owners to capture the state of current issues with the project.';
+
+
+COMMENT ON COLUMN public.distribution.max_bug_heat IS 'The highest heat value across bugs for this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.bug_reported_acknowledgement IS 'A message of acknowledgement to display to a bug reporter after they''ve reported a new bug.';
+
+
+COMMENT ON COLUMN public.distribution.registrant IS 'The person in launchpad who registered this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.package_derivatives_email IS 'The optional email address template to use when sending emails about package updates in a distributrion. The string {package_name} in the template will be replaced with the actual package name being updated.';
+
+
+COMMENT ON COLUMN public.distribution.redirect_release_uploads IS 'Whether uploads to the release pocket of this distribution should be redirected to the proposed pocket instead.';
+
+
+COMMENT ON COLUMN public.distribution.development_series_alias IS 'If set, an alias for the current development series in this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.vcs IS 'An enumeration specifying the default version control system for this distribution.';
+
+
+COMMENT ON COLUMN public.distribution.oci_project_admin IS 'Person or team with privileges to manage OCI Projects.';
+
+
+COMMENT ON COLUMN public.distribution.oci_credentials IS 'Credentials and URL to use for uploading all OCI Images in this distribution to a registry.';
+
+
+COMMENT ON COLUMN public.distribution.branch_sharing_policy IS 'Sharing policy for this distribution''s branches.';
+
+
+COMMENT ON COLUMN public.distribution.bug_sharing_policy IS 'Sharing policy for this distribution''s bugs.';
+
+
+COMMENT ON COLUMN public.distribution.specification_sharing_policy IS 'Sharing policy for this distribution''s specifications.';
+
+
+COMMENT ON COLUMN public.distribution.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
+
+
+COMMENT ON COLUMN public.distribution.access_policies IS 'Cache of AccessPolicy.ids that convey launchpad.LimitedView.';
+
+
+COMMENT ON COLUMN public.distribution.security_admin IS 'The person or team responsible for managing security vulnerabilities in this distribution.';
+
+
+CREATE SEQUENCE public.distribution_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distribution_id_seq OWNED BY public.distribution.id;
+
+
+CREATE TABLE public.distributionjob (
+    id integer NOT NULL,
+    job integer NOT NULL,
+    distribution integer NOT NULL,
+    distroseries integer,
+    job_type integer NOT NULL,
+    json_data text
+);
+
+
+COMMENT ON TABLE public.distributionjob IS 'Contains references to jobs to be run on distributions.';
+
+
+COMMENT ON COLUMN public.distributionjob.distribution IS 'The distribution to be acted on.';
+
+
+COMMENT ON COLUMN public.distributionjob.distroseries IS 'The distroseries to be acted on.';
+
+
+COMMENT ON COLUMN public.distributionjob.job_type IS 'The type of job';
+
+
+COMMENT ON COLUMN public.distributionjob.json_data IS 'A JSON struct containing data for the job.';
+
+
+CREATE SEQUENCE public.distributionjob_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distributionjob_id_seq OWNED BY public.distributionjob.id;
+
+
+CREATE TABLE public.distributionmirror (
+    id integer NOT NULL,
+    distribution integer NOT NULL,
+    name text NOT NULL,
+    http_base_url text,
+    ftp_base_url text,
+    rsync_base_url text,
+    displayname text,
+    description text,
+    owner integer NOT NULL,
+    speed integer NOT NULL,
+    country integer NOT NULL,
+    content integer NOT NULL,
+    official_candidate boolean DEFAULT false NOT NULL,
+    enabled boolean DEFAULT false NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    whiteboard text,
+    status integer DEFAULT 10 NOT NULL,
+    date_reviewed timestamp without time zone,
+    reviewer integer,
+    country_dns_mirror boolean DEFAULT false NOT NULL,
+    https_base_url text,
+    CONSTRAINT one_or_more_urls CHECK (((http_base_url IS NOT NULL) OR (https_base_url IS NOT NULL) OR (ftp_base_url IS NOT NULL) OR (rsync_base_url IS NOT NULL))),
     CONSTRAINT valid_ftp_base_url CHECK (public.valid_absolute_url(ftp_base_url)),
     CONSTRAINT valid_http_base_url CHECK (public.valid_absolute_url(http_base_url)),
+    CONSTRAINT valid_https_base_url CHECK (public.valid_absolute_url(https_base_url)),
+    CONSTRAINT valid_name CHECK (public.valid_name(name)),
+    CONSTRAINT valid_rsync_base_url CHECK (public.valid_absolute_url(rsync_base_url))
+);
+
+
+COMMENT ON TABLE public.distributionmirror IS 'A mirror of a given distribution.';
+
+
+COMMENT ON COLUMN public.distributionmirror.distribution IS 'The distribution to which the mirror refers to.';
+
+
+COMMENT ON COLUMN public.distributionmirror.name IS 'The unique name of the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.http_base_url IS 'The HTTP URL used to access the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.ftp_base_url IS 'The FTP URL used to access the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.rsync_base_url IS 'The Rsync URL used to access the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.displayname IS 'The displayname of the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.description IS 'A description of the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.owner IS 'The owner of the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.speed IS 'The speed of the mirror''s Internet link.';
+
+
+COMMENT ON COLUMN public.distributionmirror.country IS 'The country where the mirror is located.';
+
+
+COMMENT ON COLUMN public.distributionmirror.content IS 'The content that is mirrored.';
+
+
+COMMENT ON COLUMN public.distributionmirror.official_candidate IS 'Is the mirror a candidate for becoming an official mirror?';
+
+
+COMMENT ON COLUMN public.distributionmirror.enabled IS 'Is this mirror enabled?';
+
+
+COMMENT ON COLUMN public.distributionmirror.date_created IS 'The date and time the mirror was created.';
+
+
+COMMENT ON COLUMN public.distributionmirror.whiteboard IS 'Notes on the current status of the mirror';
+
+
+COMMENT ON COLUMN public.distributionmirror.status IS 'This mirror''s status.';
+
+
+COMMENT ON COLUMN public.distributionmirror.date_reviewed IS 'The date and time the mirror was reviewed.';
+
+
+COMMENT ON COLUMN public.distributionmirror.reviewer IS 'The person who reviewed the mirror.';
+
+
+COMMENT ON COLUMN public.distributionmirror.country_dns_mirror IS 'Is the mirror a country DNS mirror?';
+
+
+COMMENT ON COLUMN public.distributionmirror.https_base_url IS 'The HTTPS URL used to access the mirror.';
+
+
+CREATE SEQUENCE public.distributionmirror_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distributionmirror_id_seq OWNED BY public.distributionmirror.id;
+
+
+CREATE TABLE public.distributionsourcepackage (
+    id integer NOT NULL,
+    distribution integer NOT NULL,
+    sourcepackagename integer NOT NULL,
+    bug_reporting_guidelines text,
+    max_bug_heat integer,
+    bug_reported_acknowledgement text,
+    total_bug_heat integer,
+    bug_count integer,
+    po_message_count integer,
+    is_upstream_link_allowed boolean DEFAULT true NOT NULL,
+    enable_bugfiling_duplicate_search boolean DEFAULT true NOT NULL
+);
+
+
+COMMENT ON TABLE public.distributionsourcepackage IS 'Representing a sourcepackage in a distribution across all distribution series.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.bug_reporting_guidelines IS 'Guidelines to the end user for reporting bugs on a particular a source package in a distribution.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.max_bug_heat IS 'The highest heat value across bugs for this source package. NULL means it has not yet been calculated.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.bug_reported_acknowledgement IS 'A message of acknowledgement to display to a bug reporter after they''ve reported a new bug.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.total_bug_heat IS 'Sum of bug heat matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.bug_count IS 'Number of bugs matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.po_message_count IS 'Number of translations matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.is_upstream_link_allowed IS 'Whether an upstream link may be added if it does not already exist.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackage.enable_bugfiling_duplicate_search IS 'Enable/disable a search for posiible duplicates when a bug is filed.';
+
+
+CREATE SEQUENCE public.distributionsourcepackage_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distributionsourcepackage_id_seq OWNED BY public.distributionsourcepackage.id;
+
+
+CREATE TABLE public.distributionsourcepackagecache (
+    id integer NOT NULL,
+    distribution integer NOT NULL,
+    sourcepackagename integer NOT NULL,
+    name text,
+    binpkgnames text,
+    binpkgsummaries text,
+    binpkgdescriptions text,
+    fti public.ts2_tsvector,
+    changelog text,
+    archive integer
+);
+
+
+COMMENT ON TABLE public.distributionsourcepackagecache IS 'A cache of the text associated with binary and source packages in the distribution. This table allows for fast queries to find a source packagename that matches a given text.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.distribution IS 'The distribution in which we are checking.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.sourcepackagename IS 'The source package name for which we are caching details.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.name IS 'The source package name itself. This is just a copy of the value of sourcepackagename.name. We have it here so it can be part of the full text index.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgnames IS 'The binary package names of binary packages generated from these source packages across all architectures.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgsummaries IS 'The aggregated summaries of all the binary packages generated from these source packages in this distribution.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgdescriptions IS 'The aggregated description of all the binary packages generated from these source packages in this distribution.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.changelog IS 'A concatenation of the source package release changelogs for this source package, where the status is not REMOVED.';
+
+
+COMMENT ON COLUMN public.distributionsourcepackagecache.archive IS 'The archive where the source is published.';
+
+
+CREATE SEQUENCE public.distributionsourcepackagecache_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distributionsourcepackagecache_id_seq OWNED BY public.distributionsourcepackagecache.id;
+
+
+CREATE TABLE public.distroarchseries (
+    id integer NOT NULL,
+    distroseries integer NOT NULL,
+    architecturetag text NOT NULL,
+    owner integer NOT NULL,
+    official boolean NOT NULL,
+    package_count integer DEFAULT 0 NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    enabled boolean DEFAULT true NOT NULL,
+    processor integer NOT NULL,
+    CONSTRAINT valid_architecturetag CHECK (public.valid_name(architecturetag))
+);
+
+
+COMMENT ON TABLE public.distroarchseries IS 'DistroArchSeries: A soyuz distribution release for a given architecture. A distroseries runs on various architectures. The distroarchseries groups that architecture-specific stuff.';
+
+
+COMMENT ON COLUMN public.distroarchseries.distroseries IS 'The distribution which this distroarchseries is part of.';
+
+
+COMMENT ON COLUMN public.distroarchseries.architecturetag IS 'The name of this architecture in the context of this specific distro release. For example, some distributions might label amd64 as amd64, others might call is x86_64. This information is used, for example, in determining the names of the actual package files... such as the "amd64" part of "apache2_2.0.56-1_amd64.deb"';
+
+
+COMMENT ON COLUMN public.distroarchseries.official IS 'Whether or not this architecture or "port" is an official release. If it is not official then you may not be able to install it or get all the packages for it.';
+
+
+COMMENT ON COLUMN public.distroarchseries.package_count IS 'A cache of the number of binary packages published in this distro arch release. The count only includes packages published in the release pocket.';
+
+
+COMMENT ON COLUMN public.distroarchseries.enabled IS 'Whether to allow build creation and publishing for this DistroArchSeries.';
+
+
+COMMENT ON COLUMN public.distroarchseries.processor IS 'A link to the Processor table, giving the architecture of this DistroArchSeries.';
+
+
+CREATE SEQUENCE public.distroarchseries_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distroarchseries_id_seq OWNED BY public.distroarchseries.id;
+
+
+CREATE TABLE public.distroarchseriesfilter (
+    id integer NOT NULL,
+    distroarchseries integer NOT NULL,
+    packageset integer NOT NULL,
+    sense integer NOT NULL,
+    creator integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL
+);
+
+
+COMMENT ON TABLE public.distroarchseriesfilter IS 'A filter for packages to be included in or excluded from an architecture in a distro series.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.distroarchseries IS 'The distro arch series that this filter is for.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.packageset IS 'The package set to be included in or excluded from this distro arch series.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.sense IS 'Whether the filter represents packages to include or exclude from the distro arch series.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.creator IS 'The user who created this filter.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.date_created IS 'The time when this filter was created.';
+
+
+COMMENT ON COLUMN public.distroarchseriesfilter.date_last_modified IS 'The time when this filter was last modified.';
+
+
+CREATE SEQUENCE public.distroarchseriesfilter_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distroarchseriesfilter_id_seq OWNED BY public.distroarchseriesfilter.id;
+
+
+CREATE TABLE public.distroseries (
+    id integer NOT NULL,
+    distribution integer NOT NULL,
+    name text NOT NULL,
+    title text NOT NULL,
+    description text NOT NULL,
+    version text NOT NULL,
+    releasestatus integer NOT NULL,
+    datereleased timestamp without time zone,
+    parent_series integer,
+    registrant integer NOT NULL,
+    summary text NOT NULL,
+    displayname text NOT NULL,
+    datelastlangpack timestamp without time zone,
+    messagecount integer DEFAULT 0 NOT NULL,
+    nominatedarchindep integer,
+    changeslist text,
+    binarycount integer DEFAULT 0 NOT NULL,
+    sourcecount integer DEFAULT 0 NOT NULL,
+    driver integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    hide_all_translations boolean DEFAULT true NOT NULL,
+    defer_translation_imports boolean DEFAULT true NOT NULL,
+    language_pack_base integer,
+    language_pack_delta integer,
+    language_pack_proposed integer,
+    language_pack_full_export_requested boolean DEFAULT false NOT NULL,
+    backports_not_automatic boolean DEFAULT false NOT NULL,
+    include_long_descriptions boolean DEFAULT true NOT NULL,
+    proposed_not_automatic boolean DEFAULT false NOT NULL,
+    publishing_options text,
+    CONSTRAINT valid_language_pack_delta CHECK (((language_pack_base IS NOT NULL) OR (language_pack_delta IS NULL))),
     CONSTRAINT valid_name CHECK (public.valid_name(name)),
-    CONSTRAINT valid_rsync_base_url CHECK (public.valid_absolute_url(rsync_base_url))
+    CONSTRAINT valid_version CHECK (public.sane_version(version))
+);
+
+
+COMMENT ON TABLE public.distroseries IS 'DistroSeries: A soyuz distribution release. A DistroSeries is a given version of a distribution. E.g. "Warty" "Hoary" "Sarge" etc.';
+
+
+COMMENT ON COLUMN public.distroseries.distribution IS 'The distribution which contains this distroseries.';
+
+
+COMMENT ON COLUMN public.distroseries.name IS 'The unique name of the distroseries. This is a short name in lower case and would be used in sources.list configuration and in generated URLs. E.g. "warty" "sarge" "sid"';
+
+
+COMMENT ON COLUMN public.distroseries.title IS 'The display-name title of the distroseries E.g. "Warty Warthog"';
+
+
+COMMENT ON COLUMN public.distroseries.description IS 'The long detailed description of the release. This may describe the focus of the release or other related information.';
+
+
+COMMENT ON COLUMN public.distroseries.version IS 'The version of the release. E.g. warty would be "4.10" and hoary would be "5.4"';
+
+
+COMMENT ON COLUMN public.distroseries.releasestatus IS 'The current release status of this distroseries. E.g. "pre-release freeze" or "released"';
+
+
+COMMENT ON COLUMN public.distroseries.datereleased IS 'The date on which this distroseries was released. (obviously only valid for released distributions)';
+
+
+COMMENT ON COLUMN public.distroseries.parent_series IS 'The parent distroseries on which this distribution is based. This is related to the inheritance stuff.';
+
+
+COMMENT ON COLUMN public.distroseries.registrant IS 'The user who registered this distroseries.';
+
+
+COMMENT ON COLUMN public.distroseries.summary IS 'A brief summary of the distro release. This will be displayed in bold at the top of the distroseries page, above the distroseries description. It should include any high points that are particularly important to draw to the attention of users.';
+
+
+COMMENT ON COLUMN public.distroseries.datelastlangpack IS 'The date we last generated a base language pack for this release. Language update packs for this release will only include translations added after that date.';
+
+
+COMMENT ON COLUMN public.distroseries.messagecount IS 'This is a cached value and may be a few hours out of sync with reality. It should, however, be in sync with the values in DistroSeriesLanguage, and should never be updated separately. The total number of translation messages in this distro release, as per IRosettaStats.';
+
+
+COMMENT ON COLUMN public.distroseries.nominatedarchindep IS 'This is the DistroArchSeries nominated to build architecture independent packages within this DistroRelase, it is mandatory for buildable distroseries, i.e., Auto Build System will avoid to create build jobs for a DistroSeries with no nominatedarchindep, but the database model allow us to do it (for non-buildable DistroSeries). See further info in NominatedArchIndep specification.';
+
+
+COMMENT ON COLUMN public.distroseries.changeslist IS 'The email address (name name) of the changes announcement list for this distroseries. If NULL, no announcement mail will be sent.';
+
+
+COMMENT ON COLUMN public.distroseries.binarycount IS 'A cache of the number of distinct binary package names published in this distro release.';
+
+
+COMMENT ON COLUMN public.distroseries.sourcecount IS 'A cache of the number of distinct source package names published in this distro release.';
+
+
+COMMENT ON COLUMN public.distroseries.driver IS 'This is a person or team who can act as a driver for this specific release - note that the distribution drivers can also set goals for any release.';
+
+
+COMMENT ON COLUMN public.distroseries.hide_all_translations IS 'Whether we should hid
+e all available translations for this distro release to non admin users.';
+
+
+COMMENT ON COLUMN public.distroseries.defer_translation_imports IS 'Don''t accept PO imports for this release just now.';
+
+
+COMMENT ON COLUMN public.distroseries.language_pack_base IS 'Current full export language pack for this distribution release.';
+
+
+COMMENT ON COLUMN public.distroseries.language_pack_delta IS 'Current language pack update based on language_pack_base information.';
+
+
+COMMENT ON COLUMN public.distroseries.language_pack_proposed IS 'Either a full or update language pack being tested to be used in language_pack_base or language_pack_delta.';
+
+
+COMMENT ON COLUMN public.distroseries.language_pack_full_export_requested IS 'Whether next language pack export should be a full export or an update.';
+
+
+COMMENT ON COLUMN public.distroseries.include_long_descriptions IS 'Include long descriptions in Packages rather than in Translation-en.';
+
+
+COMMENT ON COLUMN public.distroseries.proposed_not_automatic IS 'Whether the -proposed pocket is set NotAutomatic and ButAutomaticUpgrades so that apt does not offer users upgrades into -proposed, but does offer upgrades within it.';
+
+
+COMMENT ON COLUMN public.distroseries.publishing_options IS 'A JSON object containing options modifying the publisher''s behaviour for this series.';
+
+
+CREATE SEQUENCE public.distroseries_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distroseries_id_seq OWNED BY public.distroseries.id;
+
+
+CREATE TABLE public.distroseriesdifference (
+    id integer NOT NULL,
+    derived_series integer NOT NULL,
+    source_package_name integer NOT NULL,
+    package_diff integer,
+    status integer NOT NULL,
+    difference_type integer NOT NULL,
+    parent_package_diff integer,
+    source_version public.debversion,
+    parent_source_version public.debversion,
+    base_version public.debversion,
+    parent_series integer NOT NULL,
+    CONSTRAINT valid_base_version CHECK (public.valid_debian_version((base_version)::text)),
+    CONSTRAINT valid_parent_source_version CHECK (public.valid_debian_version((parent_source_version)::text)),
+    CONSTRAINT valid_source_version CHECK (public.valid_debian_version((source_version)::text))
 );
 
 
-COMMENT ON TABLE public.distributionmirror IS 'A mirror of a given distribution.';
+COMMENT ON TABLE public.distroseriesdifference IS 'A difference of versions for a package in a derived distroseries and its parent distroseries.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.derived_series IS 'The derived distroseries with the difference from its parent.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.source_package_name IS 'The name of the source package which is different in the two series.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.package_diff IS 'The most recent package diff that was created for the base version to derived version.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.status IS 'A distroseries difference can be needing attention, ignored or resolved.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.difference_type IS 'The type of difference that this record represents - a package unique to the derived series, or missing, or in both.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.parent_package_diff IS 'The most recent package diff that was created for the base version to the parent version.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.source_version IS 'The version of the package in the derived series.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.parent_source_version IS 'The version of the package in the parent series.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.base_version IS 'The common base version of the package for the derived and parent series.';
+
+
+COMMENT ON COLUMN public.distroseriesdifference.parent_series IS 'The parent distroseries with the difference from its child.';
+
+
+CREATE SEQUENCE public.distroseriesdifference_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distroseriesdifference_id_seq OWNED BY public.distroseriesdifference.id;
+
+
+CREATE TABLE public.distroseriesdifferencemessage (
+    id integer NOT NULL,
+    distro_series_difference integer NOT NULL,
+    message integer NOT NULL
+);
+
+
+COMMENT ON TABLE public.distroseriesdifferencemessage IS 'A message/comment on a distro series difference.';
+
+
+COMMENT ON COLUMN public.distroseriesdifferencemessage.distro_series_difference IS 'The distro series difference for this comment.';
+
+
+COMMENT ON COLUMN public.distroseriesdifferencemessage.message IS 'The comment for the distro series difference.';
+
+
+CREATE SEQUENCE public.distroseriesdifferencemessage_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.distroseriesdifferencemessage_id_seq OWNED BY public.distroseriesdifferencemessage.id;
 
 
-COMMENT ON COLUMN public.distributionmirror.distribution IS 'The distribution to which the mirror refers to.';
+CREATE TABLE public.distroserieslanguage (
+    id integer NOT NULL,
+    distroseries integer,
+    language integer,
+    currentcount integer NOT NULL,
+    updatescount integer NOT NULL,
+    rosettacount integer NOT NULL,
+    contributorcount integer NOT NULL,
+    dateupdated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    unreviewed_count integer DEFAULT 0 NOT NULL
+);
 
 
-COMMENT ON COLUMN public.distributionmirror.name IS 'The unique name of the mirror.';
+COMMENT ON TABLE public.distroserieslanguage IS 'A cache of the current translation status of that language across an entire distroseries.';
 
 
-COMMENT ON COLUMN public.distributionmirror.http_base_url IS 'The HTTP URL used to access the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.currentcount IS 'As per IRosettaStats.';
 
 
-COMMENT ON COLUMN public.distributionmirror.ftp_base_url IS 'The FTP URL used to access the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.updatescount IS 'As per IRosettaStats.';
 
 
-COMMENT ON COLUMN public.distributionmirror.rsync_base_url IS 'The Rsync URL used to access the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.rosettacount IS 'As per IRosettaStats.';
 
 
-COMMENT ON COLUMN public.distributionmirror.displayname IS 'The displayname of the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.contributorcount IS 'The total number of contributors to the translation of this distroseries into this language.';
 
 
-COMMENT ON COLUMN public.distributionmirror.description IS 'A description of the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.dateupdated IS 'The date these statistucs were last updated.';
 
 
-COMMENT ON COLUMN public.distributionmirror.owner IS 'The owner of the mirror.';
+COMMENT ON COLUMN public.distroserieslanguage.unreviewed_count IS 'As per IRosettaStats.';
 
 
-COMMENT ON COLUMN public.distributionmirror.speed IS 'The speed of the mirror''s Internet link.';
+CREATE SEQUENCE public.distroserieslanguage_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distributionmirror.country IS 'The country where the mirror is located.';
+ALTER SEQUENCE public.distroserieslanguage_id_seq OWNED BY public.distroserieslanguage.id;
 
 
-COMMENT ON COLUMN public.distributionmirror.content IS 'The content that is mirrored.';
+CREATE TABLE public.distroseriespackagecache (
+    id integer NOT NULL,
+    distroseries integer NOT NULL,
+    binarypackagename integer NOT NULL,
+    name text,
+    summary text,
+    description text,
+    summaries text,
+    descriptions text,
+    fti public.ts2_tsvector,
+    archive integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.distributionmirror.official_candidate IS 'Is the mirror a candidate for becoming an official mirror?';
+COMMENT ON TABLE public.distroseriespackagecache IS 'A cache of the text associated with binary packages in the distroseries. This table allows for fast queries to find a binary packagename that matches a given text.';
 
 
-COMMENT ON COLUMN public.distributionmirror.enabled IS 'Is this mirror enabled?';
+COMMENT ON COLUMN public.distroseriespackagecache.distroseries IS 'The distroseries in which we are checking.';
 
 
-COMMENT ON COLUMN public.distributionmirror.date_created IS 'The date and time the mirror was created.';
+COMMENT ON COLUMN public.distroseriespackagecache.binarypackagename IS 'The binary package name for which we are caching details.';
 
 
-COMMENT ON COLUMN public.distributionmirror.whiteboard IS 'Notes on the current status of the mirror';
+COMMENT ON COLUMN public.distroseriespackagecache.name IS 'The binary package name itself. This is just a copy of the value of binarypackagename.name. We have it here so it can be part of the full text index.';
 
 
-COMMENT ON COLUMN public.distributionmirror.status IS 'This mirror''s status.';
+COMMENT ON COLUMN public.distroseriespackagecache.summary IS 'A single summary for one of the binary packages of this name in this distroseries. We could potentially have binary packages in different architectures with the same name and different summaries, so this is a way of collapsing to one arbitrarily-chosen one, for display purposes. The chances of actually having different summaries and descriptions is pretty small. It could happen, though, because of the way package superseding works when a package does not build on a specific architecture.';
 
 
-COMMENT ON COLUMN public.distributionmirror.date_reviewed IS 'The date and time the mirror was reviewed.';
+COMMENT ON COLUMN public.distroseriespackagecache.summaries IS 'The aggregated summaries of all the binary packages with this name in this distroseries.';
 
 
-COMMENT ON COLUMN public.distributionmirror.reviewer IS 'The person who reviewed the mirror.';
+COMMENT ON COLUMN public.distroseriespackagecache.descriptions IS 'The aggregated description of all the binary packages with this name in this distroseries.';
 
 
-COMMENT ON COLUMN public.distributionmirror.country_dns_mirror IS 'Is the mirror a country DNS mirror?';
+COMMENT ON COLUMN public.distroseriespackagecache.archive IS 'The archive where the binary is published.';
 
 
-CREATE SEQUENCE public.distributionmirror_id_seq
+CREATE SEQUENCE public.distroseriespackagecache_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7349,52 +8514,70 @@ CREATE SEQUENCE public.distributionmirror_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distributionmirror_id_seq OWNED BY public.distributionmirror.id;
+ALTER SEQUENCE public.distroseriespackagecache_id_seq OWNED BY public.distroseriespackagecache.id;
 
 
-CREATE TABLE public.distributionsourcepackage (
+CREATE TABLE public.distroseriesparent (
     id integer NOT NULL,
-    distribution integer NOT NULL,
-    sourcepackagename integer NOT NULL,
-    bug_reporting_guidelines text,
-    max_bug_heat integer,
-    bug_reported_acknowledgement text,
-    total_bug_heat integer,
-    bug_count integer,
-    po_message_count integer,
-    is_upstream_link_allowed boolean DEFAULT true NOT NULL,
-    enable_bugfiling_duplicate_search boolean DEFAULT true NOT NULL
+    derived_series integer NOT NULL,
+    parent_series integer NOT NULL,
+    initialized boolean NOT NULL,
+    is_overlay boolean DEFAULT false NOT NULL,
+    component integer,
+    pocket integer,
+    ordering integer DEFAULT 1 NOT NULL,
+    inherit_overrides boolean DEFAULT false NOT NULL
 );
 
 
-COMMENT ON TABLE public.distributionsourcepackage IS 'Representing a sourcepackage in a distribution across all distribution series.';
+COMMENT ON TABLE public.distroseriesparent IS 'A list of all the derived distroseries for a parent series.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.bug_reporting_guidelines IS 'Guidelines to the end user for reporting bugs on a particular a source package in a distribution.';
+COMMENT ON COLUMN public.distroseriesparent.derived_series IS 'The derived distroseries';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.max_bug_heat IS 'The highest heat value across bugs for this source package. NULL means it has not yet been calculated.';
+COMMENT ON COLUMN public.distroseriesparent.parent_series IS 'The parent distroseries';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.bug_reported_acknowledgement IS 'A message of acknowledgement to display to a bug reporter after they''ve reported a new bug.';
+COMMENT ON COLUMN public.distroseriesparent.initialized IS 'Whether or not the derived series was initialized by copying packages from the parent.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.total_bug_heat IS 'Sum of bug heat matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+COMMENT ON COLUMN public.distroseriesparent.is_overlay IS 'Whether or not the derived series is an overlay over the parent series.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.bug_count IS 'Number of bugs matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+COMMENT ON COLUMN public.distroseriesparent.component IS 'The component for this overlay.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.po_message_count IS 'Number of translations matching the package distribution and sourcepackagename. NULL means it has not yet been calculated.';
+COMMENT ON COLUMN public.distroseriesparent.pocket IS 'The pocket for this overlay.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.is_upstream_link_allowed IS 'Whether an upstream link may be added if it does not already exist.';
+COMMENT ON COLUMN public.distroseriesparent.ordering IS 'The parent ordering. Parents are ordered in ascending order starting from 1.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackage.enable_bugfiling_duplicate_search IS 'Enable/disable a search for posiible duplicates when a bug is filed.';
+CREATE SEQUENCE public.distroseriesparent_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-CREATE SEQUENCE public.distributionsourcepackage_id_seq
+ALTER SEQUENCE public.distroseriesparent_id_seq OWNED BY public.distroseriesparent.id;
+
+
+CREATE TABLE public.emailaddress (
+    id integer NOT NULL,
+    email text NOT NULL,
+    person integer NOT NULL,
+    status integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+);
+
+
+COMMENT ON COLUMN public.emailaddress.email IS 'An email address used by a Person. The email address is stored in a casesensitive way, but must be case insensitivly unique.';
+
+
+CREATE SEQUENCE public.emailaddress_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7402,51 +8585,61 @@ CREATE SEQUENCE public.distributionsourcepackage_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distributionsourcepackage_id_seq OWNED BY public.distributionsourcepackage.id;
+ALTER SEQUENCE public.emailaddress_id_seq OWNED BY public.emailaddress.id;
 
 
-CREATE TABLE public.distributionsourcepackagecache (
+CREATE TABLE public.faq (
     id integer NOT NULL,
-    distribution integer NOT NULL,
-    sourcepackagename integer NOT NULL,
-    name text,
-    binpkgnames text,
-    binpkgsummaries text,
-    binpkgdescriptions text,
+    title text NOT NULL,
+    tags text,
+    content text NOT NULL,
+    product integer,
+    distribution integer,
+    owner integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    last_updated_by integer,
+    date_last_updated timestamp without time zone,
     fti public.ts2_tsvector,
-    changelog text,
-    archive integer
+    CONSTRAINT product_or_distro CHECK (((product IS NULL) <> (distribution IS NULL)))
 );
 
 
-COMMENT ON TABLE public.distributionsourcepackagecache IS 'A cache of the text associated with binary and source packages in the distribution. This table allows for fast queries to find a source packagename that matches a given text.';
+COMMENT ON TABLE public.faq IS 'A technical document containing the answer to a common question.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.distribution IS 'The distribution in which we are checking.';
+COMMENT ON COLUMN public.faq.id IS 'The FAQ document sequence number.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.sourcepackagename IS 'The source package name for which we are caching details.';
+COMMENT ON COLUMN public.faq.title IS 'The document title.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.name IS 'The source package name itself. This is just a copy of the value of sourcepackagename.name. We have it here so it can be part of the full text index.';
+COMMENT ON COLUMN public.faq.tags IS 'White-space separated list of tags.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgnames IS 'The binary package names of binary packages generated from these source packages across all architectures.';
+COMMENT ON COLUMN public.faq.content IS 'The content of FAQ. It can also contain a short summary and a link.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgsummaries IS 'The aggregated summaries of all the binary packages generated from these source packages in this distribution.';
+COMMENT ON COLUMN public.faq.product IS 'The product to which this document is
+related. Either "product" or "distribution" must be set.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.binpkgdescriptions IS 'The aggregated description of all the binary packages generated from these source packages in this distribution.';
+COMMENT ON COLUMN public.faq.distribution IS 'The distribution to which this document
+is related. Either "product" or "distribution" must be set.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.changelog IS 'A concatenation of the source package release changelogs for this source package, where the status is not REMOVED.';
+COMMENT ON COLUMN public.faq.owner IS 'The person who created the document.';
 
 
-COMMENT ON COLUMN public.distributionsourcepackagecache.archive IS 'The archive where the source is published.';
+COMMENT ON COLUMN public.faq.date_created IS 'The datetime when the document was created.';
 
 
-CREATE SEQUENCE public.distributionsourcepackagecache_id_seq
+COMMENT ON COLUMN public.faq.last_updated_by IS 'The person who last modified the document.';
+
+
+COMMENT ON COLUMN public.faq.date_last_updated IS 'The datetime when the document was last modified.';
+
+
+CREATE SEQUENCE public.faq_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7454,45 +8647,80 @@ CREATE SEQUENCE public.distributionsourcepackagecache_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distributionsourcepackagecache_id_seq OWNED BY public.distributionsourcepackagecache.id;
+ALTER SEQUENCE public.faq_id_seq OWNED BY public.faq.id;
 
 
-CREATE TABLE public.distroarchseries (
+CREATE TABLE public.featuredproject (
     id integer NOT NULL,
-    distroseries integer NOT NULL,
-    architecturetag text NOT NULL,
-    owner integer NOT NULL,
-    official boolean NOT NULL,
-    package_count integer DEFAULT 0 NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    enabled boolean DEFAULT true NOT NULL,
-    processor integer NOT NULL,
-    CONSTRAINT valid_architecturetag CHECK (public.valid_name(architecturetag))
+    pillar_name integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.distroarchseries IS 'DistroArchSeries: A soyuz distribution release for a given architecture. A distroseries runs on various architectures. The distroarchseries groups that architecture-specific stuff.';
+COMMENT ON TABLE public.featuredproject IS 'A list of featured projects. This table is really just a list of pillarname IDs, if a project''s pillar name is in this list then it is a featured project and will be listed on the Launchpad home page.';
 
 
-COMMENT ON COLUMN public.distroarchseries.distroseries IS 'The distribution which this distroarchseries is part of.';
+COMMENT ON COLUMN public.featuredproject.pillar_name IS 'A reference to PillarName.id';
 
 
-COMMENT ON COLUMN public.distroarchseries.architecturetag IS 'The name of this architecture in the context of this specific distro release. For example, some distributions might label amd64 as amd64, others might call is x86_64. This information is used, for example, in determining the names of the actual package files... such as the "amd64" part of "apache2_2.0.56-1_amd64.deb"';
+CREATE SEQUENCE public.featuredproject_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distroarchseries.official IS 'Whether or not this architecture or "port" is an official release. If it is not official then you may not be able to install it or get all the packages for it.';
+ALTER SEQUENCE public.featuredproject_id_seq OWNED BY public.featuredproject.id;
 
 
-COMMENT ON COLUMN public.distroarchseries.package_count IS 'A cache of the number of binary packages published in this distro arch release. The count only includes packages published in the release pocket.';
+CREATE TABLE public.featureflag (
+    scope text NOT NULL,
+    priority integer NOT NULL,
+    flag text NOT NULL,
+    value text NOT NULL,
+    date_modified timestamp without time zone DEFAULT timezone('utc'::text, now()) NOT NULL
+);
 
 
-COMMENT ON COLUMN public.distroarchseries.enabled IS 'Whether to allow build creation and publishing for this DistroArchSeries.';
+COMMENT ON TABLE public.featureflag IS 'Configuration that varies by the active scope and that 
+can be changed without restarting Launchpad
+<https://dev.launchpad.net/LEP/FeatureFlags>';
 
 
-COMMENT ON COLUMN public.distroarchseries.processor IS 'A link to the Processor table, giving the architecture of this DistroArchSeries.';
+COMMENT ON COLUMN public.featureflag.scope IS 'Scope in which this setting is active';
 
 
-CREATE SEQUENCE public.distroarchseries_id_seq
+COMMENT ON COLUMN public.featureflag.priority IS 'Higher priority flags override lower';
+
+
+COMMENT ON COLUMN public.featureflag.flag IS 'Name of the flag being controlled';
+
+
+CREATE TABLE public.featureflagchangelogentry (
+    id integer NOT NULL,
+    date_changed timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    diff text NOT NULL,
+    comment text NOT NULL,
+    person integer NOT NULL
+);
+
+
+COMMENT ON TABLE public.featureflagchangelogentry IS 'A record of changes to the FeatureFlag table.';
+
+
+COMMENT ON COLUMN public.featureflagchangelogentry.date_changed IS 'The timestamp for when the change was made';
+
+
+COMMENT ON COLUMN public.featureflagchangelogentry.diff IS 'A unified diff of the change.';
+
+
+COMMENT ON COLUMN public.featureflagchangelogentry.comment IS 'A comment explaining the change.';
+
+
+COMMENT ON COLUMN public.featureflagchangelogentry.person IS 'The person who made this change.';
+
+
+CREATE SEQUENCE public.featureflagchangelogentry_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7500,263 +8728,273 @@ CREATE SEQUENCE public.distroarchseries_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distroarchseries_id_seq OWNED BY public.distroarchseries.id;
+ALTER SEQUENCE public.featureflagchangelogentry_id_seq OWNED BY public.featureflagchangelogentry.id;
 
 
-CREATE TABLE public.distroseries (
+CREATE TABLE public.flatpackagesetinclusion (
     id integer NOT NULL,
-    distribution integer NOT NULL,
-    name text NOT NULL,
-    title text NOT NULL,
-    description text NOT NULL,
-    version text NOT NULL,
-    releasestatus integer NOT NULL,
-    datereleased timestamp without time zone,
-    parent_series integer,
-    registrant integer NOT NULL,
-    summary text NOT NULL,
-    displayname text NOT NULL,
-    datelastlangpack timestamp without time zone,
-    messagecount integer DEFAULT 0 NOT NULL,
-    nominatedarchindep integer,
-    changeslist text,
-    binarycount integer DEFAULT 0 NOT NULL,
-    sourcecount integer DEFAULT 0 NOT NULL,
-    driver integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    hide_all_translations boolean DEFAULT true NOT NULL,
-    defer_translation_imports boolean DEFAULT true NOT NULL,
-    language_pack_base integer,
-    language_pack_delta integer,
-    language_pack_proposed integer,
-    language_pack_full_export_requested boolean DEFAULT false NOT NULL,
-    backports_not_automatic boolean DEFAULT false NOT NULL,
-    include_long_descriptions boolean DEFAULT true NOT NULL,
-    proposed_not_automatic boolean DEFAULT false NOT NULL,
-    publishing_options text,
-    CONSTRAINT valid_language_pack_delta CHECK (((language_pack_base IS NOT NULL) OR (language_pack_delta IS NULL))),
-    CONSTRAINT valid_name CHECK (public.valid_name(name)),
-    CONSTRAINT valid_version CHECK (public.sane_version(version))
+    parent integer NOT NULL,
+    child integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.distroseries IS 'DistroSeries: A soyuz distribution release. A DistroSeries is a given version of a distribution. E.g. "Warty" "Hoary" "Sarge" etc.';
+COMMENT ON TABLE public.flatpackagesetinclusion IS 'In order to facilitate the querying of set-subset relationships an expanded or flattened representation of the set-subset hierarchy is provided by this table.';
 
 
-COMMENT ON COLUMN public.distroseries.distribution IS 'The distribution which contains this distroseries.';
+COMMENT ON COLUMN public.flatpackagesetinclusion.parent IS 'The package set that is (directly or indirectly) including a subset.';
 
 
-COMMENT ON COLUMN public.distroseries.name IS 'The unique name of the distroseries. This is a short name in lower case and would be used in sources.list configuration and in generated URLs. E.g. "warty" "sarge" "sid"';
+COMMENT ON COLUMN public.flatpackagesetinclusion.child IS 'The package set that is being included as a subset.';
 
 
-COMMENT ON COLUMN public.distroseries.title IS 'The display-name title of the distroseries E.g. "Warty Warthog"';
+CREATE SEQUENCE public.flatpackagesetinclusion_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distroseries.description IS 'The long detailed description of the release. This may describe the focus of the release or other related information.';
+ALTER SEQUENCE public.flatpackagesetinclusion_id_seq OWNED BY public.flatpackagesetinclusion.id;
 
 
-COMMENT ON COLUMN public.distroseries.version IS 'The version of the release. E.g. warty would be "4.10" and hoary would be "5.4"';
+CREATE TABLE public.fticache (
+    id integer NOT NULL,
+    tablename text NOT NULL,
+    columns text NOT NULL
+);
 
 
-COMMENT ON COLUMN public.distroseries.releasestatus IS 'The current release status of this distroseries. E.g. "pre-release freeze" or "released"';
+CREATE SEQUENCE public.fticache_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distroseries.datereleased IS 'The date on which this distroseries was released. (obviously only valid for released distributions)';
+ALTER SEQUENCE public.fticache_id_seq OWNED BY public.fticache.id;
 
 
-COMMENT ON COLUMN public.distroseries.parent_series IS 'The parent distroseries on which this distribution is based. This is related to the inheritance stuff.';
+CREATE TABLE public.garbojobstate (
+    name text NOT NULL,
+    json_data text
+);
 
 
-COMMENT ON COLUMN public.distroseries.registrant IS 'The user who registered this distroseries.';
+COMMENT ON TABLE public.garbojobstate IS 'Contains persistent state for named garbo jobs.';
 
 
-COMMENT ON COLUMN public.distroseries.summary IS 'A brief summary of the distro release. This will be displayed in bold at the top of the distroseries page, above the distroseries description. It should include any high points that are particularly important to draw to the attention of users.';
+COMMENT ON COLUMN public.garbojobstate.name IS 'The name of the job.';
 
 
-COMMENT ON COLUMN public.distroseries.datelastlangpack IS 'The date we last generated a base language pack for this release. Language update packs for this release will only include translations added after that date.';
+COMMENT ON COLUMN public.garbojobstate.json_data IS 'A JSON struct containing data for the job.';
 
 
-COMMENT ON COLUMN public.distroseries.messagecount IS 'This is a cached value and may be a few hours out of sync with reality. It should, however, be in sync with the values in DistroSeriesLanguage, and should never be updated separately. The total number of translation messages in this distro release, as per IRosettaStats.';
+CREATE TABLE public.gitactivity (
+    id integer NOT NULL,
+    repository integer NOT NULL,
+    date_changed timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    changer integer NOT NULL,
+    changee integer,
+    what_changed integer NOT NULL,
+    old_value text,
+    new_value text
+);
 
 
-COMMENT ON COLUMN public.distroseries.nominatedarchindep IS 'This is the DistroArchSeries nominated to build architecture independent packages within this DistroRelase, it is mandatory for buildable distroseries, i.e., Auto Build System will avoid to create build jobs for a DistroSeries with no nominatedarchindep, but the database model allow us to do it (for non-buildable DistroSeries). See further info in NominatedArchIndep specification.';
+COMMENT ON TABLE public.gitactivity IS 'An activity log entry for a Git repository.';
 
 
-COMMENT ON COLUMN public.distroseries.changeslist IS 'The email address (name name) of the changes announcement list for this distroseries. If NULL, no announcement mail will be sent.';
+COMMENT ON COLUMN public.gitactivity.repository IS 'The repository that this log entry is for.';
 
 
-COMMENT ON COLUMN public.distroseries.binarycount IS 'A cache of the number of distinct binary package names published in this distro release.';
+COMMENT ON COLUMN public.gitactivity.date_changed IS 'The time when this change happened.';
 
 
-COMMENT ON COLUMN public.distroseries.sourcecount IS 'A cache of the number of distinct source package names published in this distro release.';
+COMMENT ON COLUMN public.gitactivity.changer IS 'The user who made this change.';
 
 
-COMMENT ON COLUMN public.distroseries.driver IS 'This is a person or team who can act as a driver for this specific release - note that the distribution drivers can also set goals for any release.';
+COMMENT ON COLUMN public.gitactivity.changee IS 'The person or team that this change was applied to.';
 
 
-COMMENT ON COLUMN public.distroseries.hide_all_translations IS 'Whether we should hid
-e all available translations for this distro release to non admin users.';
+COMMENT ON COLUMN public.gitactivity.what_changed IS 'The property of the repository that changed.';
 
 
-COMMENT ON COLUMN public.distroseries.defer_translation_imports IS 'Don''t accept PO imports for this release just now.';
+COMMENT ON COLUMN public.gitactivity.old_value IS 'JSON object representing the value before the change.';
 
 
-COMMENT ON COLUMN public.distroseries.language_pack_base IS 'Current full export language pack for this distribution release.';
+COMMENT ON COLUMN public.gitactivity.new_value IS 'JSON object representing the value after the change.';
 
 
-COMMENT ON COLUMN public.distroseries.language_pack_delta IS 'Current language pack update based on language_pack_base information.';
+CREATE SEQUENCE public.gitactivity_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.distroseries.language_pack_proposed IS 'Either a full or update language pack being tested to be used in language_pack_base or language_pack_delta.';
+ALTER SEQUENCE public.gitactivity_id_seq OWNED BY public.gitactivity.id;
 
 
-COMMENT ON COLUMN public.distroseries.language_pack_full_export_requested IS 'Whether next language pack export should be a full export or an update.';
+CREATE TABLE public.gitjob (
+    job integer NOT NULL,
+    repository integer,
+    job_type integer NOT NULL,
+    json_data text
+);
 
 
-COMMENT ON COLUMN public.distroseries.include_long_descriptions IS 'Include long descriptions in Packages rather than in Translation-en.';
+COMMENT ON TABLE public.gitjob IS 'Contains references to jobs that are executed for a Git repository.';
 
 
-COMMENT ON COLUMN public.distroseries.proposed_not_automatic IS 'Whether the -proposed pocket is set NotAutomatic and ButAutomaticUpgrades so that apt does not offer users upgrades into -proposed, but does offer upgrades within it.';
+COMMENT ON COLUMN public.gitjob.job IS 'A reference to a Job row that has all the common job details.';
 
 
-COMMENT ON COLUMN public.distroseries.publishing_options IS 'A JSON object containing options modifying the publisher''s behaviour for this series.';
+COMMENT ON COLUMN public.gitjob.repository IS 'The repository that this job is for.';
 
 
-CREATE SEQUENCE public.distroseries_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.gitjob.job_type IS 'The type of job, such as a ref scan.';
 
 
-ALTER SEQUENCE public.distroseries_id_seq OWNED BY public.distroseries.id;
+COMMENT ON COLUMN public.gitjob.json_data IS 'Data that is specific to a particular job type.';
 
 
-CREATE TABLE public.distroseriesdifference (
-    id integer NOT NULL,
-    derived_series integer NOT NULL,
-    source_package_name integer NOT NULL,
-    package_diff integer,
-    status integer NOT NULL,
-    difference_type integer NOT NULL,
-    parent_package_diff integer,
-    source_version public.debversion,
-    parent_source_version public.debversion,
-    base_version public.debversion,
-    parent_series integer NOT NULL,
-    CONSTRAINT valid_base_version CHECK (public.valid_debian_version((base_version)::text)),
-    CONSTRAINT valid_parent_source_version CHECK (public.valid_debian_version((parent_source_version)::text)),
-    CONSTRAINT valid_source_version CHECK (public.valid_debian_version((source_version)::text))
+CREATE TABLE public.gitref (
+    repository integer NOT NULL,
+    path text NOT NULL,
+    commit_sha1 character(40) NOT NULL,
+    object_type integer NOT NULL,
+    author integer,
+    author_date timestamp without time zone,
+    committer integer,
+    committer_date timestamp without time zone,
+    commit_message text
 );
 
 
-COMMENT ON TABLE public.distroseriesdifference IS 'A difference of versions for a package in a derived distroseries and its parent distroseries.';
+COMMENT ON TABLE public.gitref IS 'A reference in a Git repository.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.derived_series IS 'The derived distroseries with the difference from its parent.';
+COMMENT ON COLUMN public.gitref.repository IS 'The repository containing this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.source_package_name IS 'The name of the source package which is different in the two series.';
+COMMENT ON COLUMN public.gitref.path IS 'The full path of the reference, e.g. refs/heads/master.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.package_diff IS 'The most recent package diff that was created for the base version to derived version.';
+COMMENT ON COLUMN public.gitref.commit_sha1 IS 'The SHA-1 hash of the object pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.status IS 'A distroseries difference can be needing attention, ignored or resolved.';
+COMMENT ON COLUMN public.gitref.object_type IS 'The type of object pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.difference_type IS 'The type of difference that this record represents - a package unique to the derived series, or missing, or in both.';
+COMMENT ON COLUMN public.gitref.author IS 'The author of the commit pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.parent_package_diff IS 'The most recent package diff that was created for the base version to the parent version.';
+COMMENT ON COLUMN public.gitref.author_date IS 'The author date of the commit pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.source_version IS 'The version of the package in the derived series.';
+COMMENT ON COLUMN public.gitref.committer IS 'The committer of the commit pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.parent_source_version IS 'The version of the package in the parent series.';
+COMMENT ON COLUMN public.gitref.committer_date IS 'The committer date of the commit pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.base_version IS 'The common base version of the package for the derived and parent series.';
+COMMENT ON COLUMN public.gitref.commit_message IS 'The commit message of the commit pointed to by this reference.';
 
 
-COMMENT ON COLUMN public.distroseriesdifference.parent_series IS 'The parent distroseries with the difference from its child.';
+CREATE TABLE public.gitrepository (
+    id integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    registrant integer NOT NULL,
+    owner integer NOT NULL,
+    project integer,
+    distribution integer,
+    sourcepackagename integer,
+    name text NOT NULL,
+    information_type integer NOT NULL,
+    owner_default boolean DEFAULT false NOT NULL,
+    target_default boolean DEFAULT false NOT NULL,
+    access_policy integer,
+    access_grants integer[],
+    description text,
+    reviewer integer,
+    default_branch text,
+    repository_type integer NOT NULL,
+    deletion_status integer,
+    ociprojectname integer,
+    oci_project integer,
+    status integer DEFAULT 2 NOT NULL,
+    loose_object_count integer,
+    pack_count integer,
+    date_last_repacked timestamp without time zone,
+    date_last_scanned timestamp without time zone,
+    CONSTRAINT default_implies_target CHECK (((project IS NOT NULL) OR (distribution IS NOT NULL) OR (oci_project IS NOT NULL) OR ((NOT owner_default) AND (NOT target_default)))),
+    CONSTRAINT one_container CHECK ((((project IS NULL) AND (distribution IS NOT NULL) AND (sourcepackagename IS NULL) AND (ociprojectname IS NOT NULL)) OR ((project IS NOT NULL) AND (distribution IS NULL) AND (sourcepackagename IS NULL) AND (oci_project IS NULL) AND (ociprojectname IS NULL)) OR ((project IS NULL) AND (distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL) AND (oci_project IS NULL) AND (ociprojectname IS NULL)) OR ((project IS NULL) AND (distribution IS NULL) AND (sourcepackagename IS NULL) AND (oci_project IS NOT NULL) AND (ociprojectname IS NULL)) OR ((project IS NULL) AND (distribution IS NULL) AND (sourcepackagename IS NULL) AND (oci_project IS NULL)))),
+    CONSTRAINT valid_name CHECK (public.valid_git_repository_name(name))
+);
 
 
-CREATE SEQUENCE public.distroseriesdifference_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON TABLE public.gitrepository IS 'Git repository';
 
 
-ALTER SEQUENCE public.distroseriesdifference_id_seq OWNED BY public.distroseriesdifference.id;
+COMMENT ON COLUMN public.gitrepository.registrant IS 'The user who registered the repository.';
 
 
-CREATE TABLE public.distroseriesdifferencemessage (
-    id integer NOT NULL,
-    distro_series_difference integer NOT NULL,
-    message integer NOT NULL
-);
+COMMENT ON COLUMN public.gitrepository.owner IS 'The owner of the repository.';
 
 
-COMMENT ON TABLE public.distroseriesdifferencemessage IS 'A message/comment on a distro series difference.';
+COMMENT ON COLUMN public.gitrepository.project IS 'The project that this repository belongs to.';
 
 
-COMMENT ON COLUMN public.distroseriesdifferencemessage.distro_series_difference IS 'The distro series difference for this comment.';
+COMMENT ON COLUMN public.gitrepository.distribution IS 'The distribution that this repository belongs to.';
 
 
-COMMENT ON COLUMN public.distroseriesdifferencemessage.message IS 'The comment for the distro series difference.';
+COMMENT ON COLUMN public.gitrepository.sourcepackagename IS 'The source package that this repository belongs to.';
 
 
-CREATE SEQUENCE public.distroseriesdifferencemessage_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.gitrepository.name IS 'The name of this repository.';
 
 
-ALTER SEQUENCE public.distroseriesdifferencemessage_id_seq OWNED BY public.distroseriesdifferencemessage.id;
+COMMENT ON COLUMN public.gitrepository.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
 
 
-CREATE TABLE public.distroserieslanguage (
-    id integer NOT NULL,
-    distroseries integer,
-    language integer,
-    currentcount integer NOT NULL,
-    updatescount integer NOT NULL,
-    rosettacount integer NOT NULL,
-    contributorcount integer NOT NULL,
-    dateupdated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    unreviewed_count integer DEFAULT 0 NOT NULL
-);
+COMMENT ON COLUMN public.gitrepository.owner_default IS 'True if this repository is the default for its owner and target.';
+
+
+COMMENT ON COLUMN public.gitrepository.target_default IS 'True if this repository is the default for its target.';
+
+
+COMMENT ON COLUMN public.gitrepository.description IS 'A short description of this repository.';
+
 
+COMMENT ON COLUMN public.gitrepository.reviewer IS 'The reviewer (person or) team are able to transition merge proposals targeted at the repository through the CODE_APPROVED state.';
 
-COMMENT ON TABLE public.distroserieslanguage IS 'A cache of the current translation status of that language across an entire distroseries.';
 
+COMMENT ON COLUMN public.gitrepository.default_branch IS 'The reference path of this repository''s default branch, or "HEAD".';
 
-COMMENT ON COLUMN public.distroserieslanguage.currentcount IS 'As per IRosettaStats.';
 
+COMMENT ON COLUMN public.gitrepository.repository_type IS 'Repositories are currently one of HOSTED (1) or IMPORTED (3).';
 
-COMMENT ON COLUMN public.distroserieslanguage.updatescount IS 'As per IRosettaStats.';
 
+COMMENT ON COLUMN public.gitrepository.deletion_status IS 'The deletion status of this repository.';
 
-COMMENT ON COLUMN public.distroserieslanguage.rosettacount IS 'As per IRosettaStats.';
 
+COMMENT ON COLUMN public.gitrepository.ociprojectname IS 'Deprecated column. Check one_container and default_implies_target constraints before removing.';
 
-COMMENT ON COLUMN public.distroserieslanguage.contributorcount IS 'The total number of contributors to the translation of this distroseries into this language.';
 
+COMMENT ON COLUMN public.gitrepository.status IS 'The current status of this git repository.';
 
-COMMENT ON COLUMN public.distroserieslanguage.dateupdated IS 'The date these statistucs were last updated.';
 
+COMMENT ON COLUMN public.gitrepository.date_last_repacked IS 'The datetime that the last repack request was executed successfully on Turnip.';
 
-COMMENT ON COLUMN public.distroserieslanguage.unreviewed_count IS 'As per IRosettaStats.';
 
+COMMENT ON COLUMN public.gitrepository.date_last_scanned IS 'The datetime that packs and loose_objects were last updated for this repository.';
 
-CREATE SEQUENCE public.distroserieslanguage_id_seq
+
+CREATE SEQUENCE public.gitrepository_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7764,48 +9002,42 @@ CREATE SEQUENCE public.distroserieslanguage_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distroserieslanguage_id_seq OWNED BY public.distroserieslanguage.id;
+ALTER SEQUENCE public.gitrepository_id_seq OWNED BY public.gitrepository.id;
 
 
-CREATE TABLE public.distroseriespackagecache (
+CREATE TABLE public.gitrule (
     id integer NOT NULL,
-    distroseries integer NOT NULL,
-    binarypackagename integer NOT NULL,
-    name text,
-    summary text,
-    description text,
-    summaries text,
-    descriptions text,
-    fti public.ts2_tsvector,
-    archive integer NOT NULL
+    repository integer NOT NULL,
+    "position" integer NOT NULL,
+    ref_pattern text NOT NULL,
+    creator integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
 );
 
 
-COMMENT ON TABLE public.distroseriespackagecache IS 'A cache of the text associated with binary packages in the distroseries. This table allows for fast queries to find a binary packagename that matches a given text.';
-
-
-COMMENT ON COLUMN public.distroseriespackagecache.distroseries IS 'The distroseries in which we are checking.';
+COMMENT ON TABLE public.gitrule IS 'An access rule for a Git repository.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.binarypackagename IS 'The binary package name for which we are caching details.';
+COMMENT ON COLUMN public.gitrule.repository IS 'The repository that this rule is for.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.name IS 'The binary package name itself. This is just a copy of the value of binarypackagename.name. We have it here so it can be part of the full text index.';
+COMMENT ON COLUMN public.gitrule."position" IS 'The position of this rule in its repository''s rule order.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.summary IS 'A single summary for one of the binary packages of this name in this distroseries. We could potentially have binary packages in different architectures with the same name and different summaries, so this is a way of collapsing to one arbitrarily-chosen one, for display purposes. The chances of actually having different summaries and descriptions is pretty small. It could happen, though, because of the way package superseding works when a package does not build on a specific architecture.';
+COMMENT ON COLUMN public.gitrule.ref_pattern IS 'The pattern of references matched by this rule.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.summaries IS 'The aggregated summaries of all the binary packages with this name in this distroseries.';
+COMMENT ON COLUMN public.gitrule.creator IS 'The user who created this rule.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.descriptions IS 'The aggregated description of all the binary packages with this name in this distroseries.';
+COMMENT ON COLUMN public.gitrule.date_created IS 'The time when this rule was created.';
 
 
-COMMENT ON COLUMN public.distroseriespackagecache.archive IS 'The archive where the binary is published.';
+COMMENT ON COLUMN public.gitrule.date_last_modified IS 'The time when this rule was last modified.';
 
 
-CREATE SEQUENCE public.distroseriespackagecache_id_seq
+CREATE SEQUENCE public.gitrule_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7813,70 +9045,59 @@ CREATE SEQUENCE public.distroseriespackagecache_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.distroseriespackagecache_id_seq OWNED BY public.distroseriespackagecache.id;
+ALTER SEQUENCE public.gitrule_id_seq OWNED BY public.gitrule.id;
 
 
-CREATE TABLE public.distroseriesparent (
+CREATE TABLE public.gitrulegrant (
     id integer NOT NULL,
-    derived_series integer NOT NULL,
-    parent_series integer NOT NULL,
-    initialized boolean NOT NULL,
-    is_overlay boolean DEFAULT false NOT NULL,
-    component integer,
-    pocket integer,
-    ordering integer DEFAULT 1 NOT NULL,
-    inherit_overrides boolean DEFAULT false NOT NULL
+    repository integer NOT NULL,
+    rule integer NOT NULL,
+    grantee_type integer NOT NULL,
+    grantee integer,
+    can_create boolean DEFAULT false NOT NULL,
+    can_push boolean DEFAULT false NOT NULL,
+    can_force_push boolean DEFAULT false NOT NULL,
+    grantor integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    CONSTRAINT has_grantee CHECK (((grantee_type = 2) = (grantee IS NOT NULL)))
 );
 
 
-COMMENT ON TABLE public.distroseriesparent IS 'A list of all the derived distroseries for a parent series.';
-
-
-COMMENT ON COLUMN public.distroseriesparent.derived_series IS 'The derived distroseries';
+COMMENT ON TABLE public.gitrulegrant IS 'An access grant for a Git repository rule.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.parent_series IS 'The parent distroseries';
+COMMENT ON COLUMN public.gitrulegrant.repository IS 'The repository that this grant is for.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.initialized IS 'Whether or not the derived series was initialized by copying packages from the parent.';
+COMMENT ON COLUMN public.gitrulegrant.rule IS 'The rule that this grant is for.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.is_overlay IS 'Whether or not the derived series is an overlay over the parent series.';
+COMMENT ON COLUMN public.gitrulegrant.grantee_type IS 'The type of entity being granted access.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.component IS 'The component for this overlay.';
+COMMENT ON COLUMN public.gitrulegrant.grantee IS 'The person or team being granted access.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.pocket IS 'The pocket for this overlay.';
+COMMENT ON COLUMN public.gitrulegrant.can_create IS 'Whether creating references is allowed.';
 
 
-COMMENT ON COLUMN public.distroseriesparent.ordering IS 'The parent ordering. Parents are ordered in ascending order starting from 1.';
+COMMENT ON COLUMN public.gitrulegrant.can_push IS 'Whether pushing references is allowed.';
 
 
-CREATE SEQUENCE public.distroseriesparent_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.gitrulegrant.can_force_push IS 'Whether force-pushing references is allowed.';
 
 
-ALTER SEQUENCE public.distroseriesparent_id_seq OWNED BY public.distroseriesparent.id;
+COMMENT ON COLUMN public.gitrulegrant.grantor IS 'The user who created this grant.';
 
 
-CREATE TABLE public.emailaddress (
-    id integer NOT NULL,
-    email text NOT NULL,
-    person integer NOT NULL,
-    status integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
-);
+COMMENT ON COLUMN public.gitrulegrant.date_created IS 'The time when this grant was created.';
 
 
-COMMENT ON COLUMN public.emailaddress.email IS 'An email address used by a Person. The email address is stored in a casesensitive way, but must be case insensitivly unique.';
+COMMENT ON COLUMN public.gitrulegrant.date_last_modified IS 'The time when this grant was last modified.';
 
 
-CREATE SEQUENCE public.emailaddress_id_seq
+CREATE SEQUENCE public.gitrulegrant_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7884,61 +9105,47 @@ CREATE SEQUENCE public.emailaddress_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.emailaddress_id_seq OWNED BY public.emailaddress.id;
+ALTER SEQUENCE public.gitrulegrant_id_seq OWNED BY public.gitrulegrant.id;
 
 
-CREATE TABLE public.faq (
+CREATE TABLE public.gitsubscription (
     id integer NOT NULL,
-    title text NOT NULL,
-    tags text,
-    content text NOT NULL,
-    product integer,
-    distribution integer,
-    owner integer NOT NULL,
+    person integer NOT NULL,
+    repository integer NOT NULL,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    last_updated_by integer,
-    date_last_updated timestamp without time zone,
-    fti public.ts2_tsvector,
-    CONSTRAINT product_or_distro CHECK (((product IS NULL) <> (distribution IS NULL)))
+    notification_level integer DEFAULT 1 NOT NULL,
+    max_diff_lines integer,
+    review_level integer DEFAULT 0 NOT NULL,
+    subscribed_by integer NOT NULL,
+    paths text
 );
 
 
-COMMENT ON TABLE public.faq IS 'A technical document containing the answer to a common question.';
-
-
-COMMENT ON COLUMN public.faq.id IS 'The FAQ document sequence number.';
-
-
-COMMENT ON COLUMN public.faq.title IS 'The document title.';
-
-
-COMMENT ON COLUMN public.faq.tags IS 'White-space separated list of tags.';
+COMMENT ON TABLE public.gitsubscription IS 'An association between a person or team and a Git repository.';
 
 
-COMMENT ON COLUMN public.faq.content IS 'The content of FAQ. It can also contain a short summary and a link.';
+COMMENT ON COLUMN public.gitsubscription.person IS 'The person or team associated with the repository.';
 
 
-COMMENT ON COLUMN public.faq.product IS 'The product to which this document is
-related. Either "product" or "distribution" must be set.';
+COMMENT ON COLUMN public.gitsubscription.repository IS 'The repository associated with the person or team.';
 
 
-COMMENT ON COLUMN public.faq.distribution IS 'The distribution to which this document
-is related. Either "product" or "distribution" must be set.';
+COMMENT ON COLUMN public.gitsubscription.notification_level IS 'The level of email the person wants to receive from repository updates.';
 
 
-COMMENT ON COLUMN public.faq.owner IS 'The person who created the document.';
+COMMENT ON COLUMN public.gitsubscription.max_diff_lines IS 'If the generated diff for a revision is larger than this number, then the diff is not sent in the notification email.';
 
 
-COMMENT ON COLUMN public.faq.date_created IS 'The datetime when the document was created.';
+COMMENT ON COLUMN public.gitsubscription.review_level IS 'The level of email the person wants to receive from review activity.';
 
 
-COMMENT ON COLUMN public.faq.last_updated_by IS 'The person who last modified the document.';
+COMMENT ON COLUMN public.gitsubscription.subscribed_by IS 'The person who created this subscription.';
 
 
-COMMENT ON COLUMN public.faq.date_last_updated IS 'The datetime when the document was last modified.';
+COMMENT ON COLUMN public.gitsubscription.paths IS 'A JSON-encoded list of patterns matching subscribed reference paths.';
 
 
-CREATE SEQUENCE public.faq_id_seq
+CREATE SEQUENCE public.gitsubscription_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -7946,80 +9153,85 @@ CREATE SEQUENCE public.faq_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.faq_id_seq OWNED BY public.faq.id;
+ALTER SEQUENCE public.gitsubscription_id_seq OWNED BY public.gitsubscription.id;
 
 
-CREATE TABLE public.featuredproject (
+CREATE TABLE public.gpgkey (
     id integer NOT NULL,
-    pillar_name integer NOT NULL
+    owner integer NOT NULL,
+    keyid text NOT NULL,
+    fingerprint text NOT NULL,
+    active boolean NOT NULL,
+    algorithm integer NOT NULL,
+    keysize integer NOT NULL,
+    can_encrypt boolean DEFAULT false NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    CONSTRAINT valid_fingerprint CHECK (public.valid_fingerprint(fingerprint)),
+    CONSTRAINT valid_keyid CHECK (public.valid_keyid(keyid))
 );
 
 
-COMMENT ON TABLE public.featuredproject IS 'A list of featured projects. This table is really just a list of pillarname IDs, if a project''s pillar name is in this list then it is a featured project and will be listed on the Launchpad home page.';
+COMMENT ON TABLE public.gpgkey IS 'A GPG key belonging to a Person';
 
 
-COMMENT ON COLUMN public.featuredproject.pillar_name IS 'A reference to PillarName.id';
+COMMENT ON COLUMN public.gpgkey.keyid IS 'The 8 character GPG key id, uppercase and no whitespace';
 
 
-CREATE SEQUENCE public.featuredproject_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.gpgkey.fingerprint IS 'The 40 character GPG fingerprint, uppercase and no whitespace';
 
 
-ALTER SEQUENCE public.featuredproject_id_seq OWNED BY public.featuredproject.id;
+COMMENT ON COLUMN public.gpgkey.active IS 'True if this key is active for use in Launchpad context, false could be deactivated by user or revoked in the global key ring.';
 
 
-CREATE TABLE public.featureflag (
-    scope text NOT NULL,
-    priority integer NOT NULL,
-    flag text NOT NULL,
-    value text NOT NULL,
-    date_modified timestamp without time zone DEFAULT timezone('utc'::text, now()) NOT NULL
-);
+COMMENT ON COLUMN public.gpgkey.algorithm IS 'The algorithm used to generate this key. Valid values defined in dbschema.GPGKeyAlgorithms';
 
 
-COMMENT ON TABLE public.featureflag IS 'Configuration that varies by the active scope and that 
-can be changed without restarting Launchpad
-<https://dev.launchpad.net/LEP/FeatureFlags>';
+COMMENT ON COLUMN public.gpgkey.keysize IS 'Size of the key in bits, as reported by GPG. We may refuse to deal with keysizes < 768 bits in the future.';
 
 
-COMMENT ON COLUMN public.featureflag.scope IS 'Scope in which this setting is active';
+COMMENT ON COLUMN public.gpgkey.can_encrypt IS 'Whether the key has been validated for use in encryption (as opposed to just signing)';
 
 
-COMMENT ON COLUMN public.featureflag.priority IS 'Higher priority flags override lower';
+CREATE SEQUENCE public.gpgkey_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.featureflag.flag IS 'Name of the flag being controlled';
+ALTER SEQUENCE public.gpgkey_id_seq OWNED BY public.gpgkey.id;
 
 
-CREATE TABLE public.featureflagchangelogentry (
+CREATE TABLE public.hwdevice (
     id integer NOT NULL,
-    date_changed timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    diff text NOT NULL,
-    comment text NOT NULL,
-    person integer NOT NULL
+    bus_vendor_id integer NOT NULL,
+    bus_product_id text NOT NULL,
+    variant text,
+    name text NOT NULL,
+    submissions integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.featureflagchangelogentry IS 'A record of changes to the FeatureFlag table.';
+COMMENT ON TABLE public.hwdevice IS 'Basic information on devices.';
 
 
-COMMENT ON COLUMN public.featureflagchangelogentry.date_changed IS 'The timestamp for when the change was made';
+COMMENT ON COLUMN public.hwdevice.bus_vendor_id IS 'A reference to a HWVendorID record.';
 
 
-COMMENT ON COLUMN public.featureflagchangelogentry.diff IS 'A unified diff of the change.';
+COMMENT ON COLUMN public.hwdevice.bus_product_id IS 'The bus product ID of a device';
 
 
-COMMENT ON COLUMN public.featureflagchangelogentry.comment IS 'A comment explaining the change.';
+COMMENT ON COLUMN public.hwdevice.variant IS 'An optional additional description for a device that shares its vendor and product ID with another, technically different, device.';
 
 
-COMMENT ON COLUMN public.featureflagchangelogentry.person IS 'The person who made this change.';
+COMMENT ON COLUMN public.hwdevice.name IS 'The human readable product name of the device.';
 
 
-CREATE SEQUENCE public.featureflagchangelogentry_id_seq
+COMMENT ON COLUMN public.hwdevice.submissions IS 'The number of submissions that contain this device.';
+
+
+CREATE SEQUENCE public.hwdevice_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8027,44 +9239,30 @@ CREATE SEQUENCE public.featureflagchangelogentry_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.featureflagchangelogentry_id_seq OWNED BY public.featureflagchangelogentry.id;
+ALTER SEQUENCE public.hwdevice_id_seq OWNED BY public.hwdevice.id;
 
 
-CREATE TABLE public.flatpackagesetinclusion (
+CREATE TABLE public.hwdeviceclass (
     id integer NOT NULL,
-    parent integer NOT NULL,
-    child integer NOT NULL
+    device integer NOT NULL,
+    main_class integer NOT NULL,
+    sub_class integer
 );
 
 
-COMMENT ON TABLE public.flatpackagesetinclusion IS 'In order to facilitate the querying of set-subset relationships an expanded or flattened representation of the set-subset hierarchy is provided by this table.';
-
-
-COMMENT ON COLUMN public.flatpackagesetinclusion.parent IS 'The package set that is (directly or indirectly) including a subset.';
-
-
-COMMENT ON COLUMN public.flatpackagesetinclusion.child IS 'The package set that is being included as a subset.';
+COMMENT ON TABLE public.hwdeviceclass IS 'Capabilities of a device.';
 
 
-CREATE SEQUENCE public.flatpackagesetinclusion_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.hwdeviceclass.device IS 'A reference to a device.';
 
 
-ALTER SEQUENCE public.flatpackagesetinclusion_id_seq OWNED BY public.flatpackagesetinclusion.id;
+COMMENT ON COLUMN public.hwdeviceclass.main_class IS 'The main class of a device. Legal values are defined by the HWMainClass enumeration.';
 
 
-CREATE TABLE public.fticache (
-    id integer NOT NULL,
-    tablename text NOT NULL,
-    columns text NOT NULL
-);
+COMMENT ON COLUMN public.hwdeviceclass.sub_class IS 'The sub-class of a device. Legal values are defined by the HWSubClass enumeration.';
 
 
-CREATE SEQUENCE public.fticache_id_seq
+CREATE SEQUENCE public.hwdeviceclass_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8072,61 +9270,61 @@ CREATE SEQUENCE public.fticache_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.fticache_id_seq OWNED BY public.fticache.id;
+ALTER SEQUENCE public.hwdeviceclass_id_seq OWNED BY public.hwdeviceclass.id;
 
 
-CREATE TABLE public.garbojobstate (
-    name text NOT NULL,
-    json_data text
+CREATE TABLE public.hwdevicedriverlink (
+    id integer NOT NULL,
+    device integer NOT NULL,
+    driver integer
 );
 
 
-COMMENT ON TABLE public.garbojobstate IS 'Contains persistent state for named garbo jobs.';
-
-
-COMMENT ON COLUMN public.garbojobstate.name IS 'The name of the job.';
+COMMENT ON TABLE public.hwdevicedriverlink IS 'Combinations of devices and drivers mentioned in submissions.';
 
 
-COMMENT ON COLUMN public.garbojobstate.json_data IS 'A JSON struct containing data for the job.';
+COMMENT ON COLUMN public.hwdevicedriverlink.device IS 'The device controlled by the driver.';
 
 
-CREATE TABLE public.gitactivity (
-    id integer NOT NULL,
-    repository integer NOT NULL,
-    date_changed timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    changer integer NOT NULL,
-    changee integer,
-    what_changed integer NOT NULL,
-    old_value text,
-    new_value text
-);
+COMMENT ON COLUMN public.hwdevicedriverlink.driver IS 'The driver controlling the device.';
 
 
-COMMENT ON TABLE public.gitactivity IS 'An activity log entry for a Git repository.';
+CREATE SEQUENCE public.hwdevicedriverlink_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitactivity.repository IS 'The repository that this log entry is for.';
+ALTER SEQUENCE public.hwdevicedriverlink_id_seq OWNED BY public.hwdevicedriverlink.id;
 
 
-COMMENT ON COLUMN public.gitactivity.date_changed IS 'The time when this change happened.';
+CREATE TABLE public.hwdevicenamevariant (
+    id integer NOT NULL,
+    vendor_name integer NOT NULL,
+    product_name text NOT NULL,
+    device integer NOT NULL,
+    submissions integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.gitactivity.changer IS 'The user who made this change.';
+COMMENT ON TABLE public.hwdevicenamevariant IS 'Alternative vendor and product names of devices.';
 
 
-COMMENT ON COLUMN public.gitactivity.changee IS 'The person or team that this change was applied to.';
+COMMENT ON COLUMN public.hwdevicenamevariant.vendor_name IS 'The alternative vendor name.';
 
 
-COMMENT ON COLUMN public.gitactivity.what_changed IS 'The property of the repository that changed.';
+COMMENT ON COLUMN public.hwdevicenamevariant.product_name IS 'The alternative product name.';
 
 
-COMMENT ON COLUMN public.gitactivity.old_value IS 'JSON object representing the value before the change.';
+COMMENT ON COLUMN public.hwdevicenamevariant.device IS 'The device named by this alternative vendor and product names.';
 
 
-COMMENT ON COLUMN public.gitactivity.new_value IS 'JSON object representing the value after the change.';
+COMMENT ON COLUMN public.hwdevicenamevariant.submissions IS 'The number of submissions containing this alternative vendor and product name.';
 
 
-CREATE SEQUENCE public.gitactivity_id_seq
+CREATE SEQUENCE public.hwdevicenamevariant_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8134,186 +9332,179 @@ CREATE SEQUENCE public.gitactivity_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.gitactivity_id_seq OWNED BY public.gitactivity.id;
+ALTER SEQUENCE public.hwdevicenamevariant_id_seq OWNED BY public.hwdevicenamevariant.id;
 
 
-CREATE TABLE public.gitjob (
-    job integer NOT NULL,
-    repository integer,
-    job_type integer NOT NULL,
-    json_data text
+CREATE TABLE public.hwdmihandle (
+    id integer NOT NULL,
+    handle integer NOT NULL,
+    type integer NOT NULL,
+    submission integer
 );
 
 
-COMMENT ON TABLE public.gitjob IS 'Contains references to jobs that are executed for a Git repository.';
+COMMENT ON TABLE public.hwdmihandle IS 'A DMI Handle appearing in the DMI data of a submission.';
 
 
-COMMENT ON COLUMN public.gitjob.job IS 'A reference to a Job row that has all the common job details.';
+COMMENT ON COLUMN public.hwdmihandle.handle IS 'The ID of the handle.';
 
 
-COMMENT ON COLUMN public.gitjob.repository IS 'The repository that this job is for.';
+COMMENT ON COLUMN public.hwdmihandle.type IS 'The type of the handle.';
 
 
-COMMENT ON COLUMN public.gitjob.job_type IS 'The type of job, such as a ref scan.';
+CREATE SEQUENCE public.hwdmihandle_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitjob.json_data IS 'Data that is specific to a particular job type.';
+ALTER SEQUENCE public.hwdmihandle_id_seq OWNED BY public.hwdmihandle.id;
 
 
-CREATE TABLE public.gitref (
-    repository integer NOT NULL,
-    path text NOT NULL,
-    commit_sha1 character(40) NOT NULL,
-    object_type integer NOT NULL,
-    author integer,
-    author_date timestamp without time zone,
-    committer integer,
-    committer_date timestamp without time zone,
-    commit_message text
+CREATE TABLE public.hwdmivalue (
+    id integer NOT NULL,
+    key text,
+    value text,
+    handle integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.gitref IS 'A reference in a Git repository.';
-
-
-COMMENT ON COLUMN public.gitref.repository IS 'The repository containing this reference.';
-
-
-COMMENT ON COLUMN public.gitref.path IS 'The full path of the reference, e.g. refs/heads/master.';
-
-
-COMMENT ON COLUMN public.gitref.commit_sha1 IS 'The SHA-1 hash of the object pointed to by this reference.';
-
-
-COMMENT ON COLUMN public.gitref.object_type IS 'The type of object pointed to by this reference.';
+COMMENT ON TABLE public.hwdmivalue IS 'Key/value pairs of DMI data of a handle.';
 
 
-COMMENT ON COLUMN public.gitref.author IS 'The author of the commit pointed to by this reference.';
+COMMENT ON COLUMN public.hwdmivalue.key IS 'The key.';
 
 
-COMMENT ON COLUMN public.gitref.author_date IS 'The author date of the commit pointed to by this reference.';
+COMMENT ON COLUMN public.hwdmivalue.value IS 'The value';
 
 
-COMMENT ON COLUMN public.gitref.committer IS 'The committer of the commit pointed to by this reference.';
+COMMENT ON COLUMN public.hwdmivalue.handle IS 'The handle to which this key/value pair belongs.';
 
 
-COMMENT ON COLUMN public.gitref.committer_date IS 'The committer date of the commit pointed to by this reference.';
+CREATE SEQUENCE public.hwdmivalue_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitref.commit_message IS 'The commit message of the commit pointed to by this reference.';
+ALTER SEQUENCE public.hwdmivalue_id_seq OWNED BY public.hwdmivalue.id;
 
 
-CREATE TABLE public.gitrepository (
+CREATE TABLE public.hwdriver (
     id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    registrant integer NOT NULL,
-    owner integer NOT NULL,
-    project integer,
-    distribution integer,
-    sourcepackagename integer,
+    package_name text,
     name text NOT NULL,
-    information_type integer NOT NULL,
-    owner_default boolean DEFAULT false NOT NULL,
-    target_default boolean DEFAULT false NOT NULL,
-    access_policy integer,
-    access_grants integer[],
-    description text,
-    reviewer integer,
-    default_branch text,
-    repository_type integer NOT NULL,
-    CONSTRAINT default_implies_target CHECK ((((project IS NOT NULL) OR (distribution IS NOT NULL)) OR ((NOT owner_default) AND (NOT target_default)))),
-    CONSTRAINT one_container CHECK ((((project IS NULL) OR (distribution IS NULL)) AND ((distribution IS NULL) = (sourcepackagename IS NULL)))),
-    CONSTRAINT valid_name CHECK (public.valid_git_repository_name(name))
+    license integer
 );
 
 
-COMMENT ON TABLE public.gitrepository IS 'Git repository';
+COMMENT ON TABLE public.hwdriver IS 'Information about a driver for a device';
 
 
-COMMENT ON COLUMN public.gitrepository.registrant IS 'The user who registered the repository.';
+COMMENT ON COLUMN public.hwdriver.package_name IS 'The Debian package name a driver is a part of';
 
 
-COMMENT ON COLUMN public.gitrepository.owner IS 'The owner of the repository.';
+COMMENT ON COLUMN public.hwdriver.name IS 'The name of a driver.';
 
 
-COMMENT ON COLUMN public.gitrepository.project IS 'The project that this repository belongs to.';
+CREATE SEQUENCE public.hwdriver_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitrepository.distribution IS 'The distribution that this repository belongs to.';
+ALTER SEQUENCE public.hwdriver_id_seq OWNED BY public.hwdriver.id;
 
 
-COMMENT ON COLUMN public.gitrepository.sourcepackagename IS 'The source package that this repository belongs to.';
+CREATE VIEW public.hwdrivernames AS
+ SELECT DISTINCT ON (hwdriver.name) hwdriver.id,
+    hwdriver.name
+   FROM public.hwdriver
+  ORDER BY hwdriver.name, hwdriver.id;
 
 
-COMMENT ON COLUMN public.gitrepository.name IS 'The name of this repository.';
+COMMENT ON VIEW public.hwdrivernames IS 'A view returning the distinct driver names stored in HWDriver.';
 
 
-COMMENT ON COLUMN public.gitrepository.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine how to apply an access policy.';
+COMMENT ON COLUMN public.hwdrivernames.name IS 'The name of a driver.';
 
 
-COMMENT ON COLUMN public.gitrepository.owner_default IS 'True if this repository is the default for its owner and target.';
+CREATE VIEW public.hwdriverpackagenames AS
+ SELECT DISTINCT ON (hwdriver.package_name) hwdriver.id,
+    hwdriver.package_name
+   FROM public.hwdriver
+  ORDER BY hwdriver.package_name, hwdriver.id;
 
 
-COMMENT ON COLUMN public.gitrepository.target_default IS 'True if this repository is the default for its target.';
+COMMENT ON VIEW public.hwdriverpackagenames IS 'A view returning the distinct Debian package names stored in HWDriver.';
 
 
-COMMENT ON COLUMN public.gitrepository.description IS 'A short description of this repository.';
+COMMENT ON COLUMN public.hwdriverpackagenames.package_name IS 'The Debian package name a driver is a part of.';
 
 
-COMMENT ON COLUMN public.gitrepository.reviewer IS 'The reviewer (person or) team are able to transition merge proposals targeted at the repository through the CODE_APPROVED state.';
+CREATE TABLE public.hwsubmission (
+    id integer NOT NULL,
+    date_created timestamp without time zone NOT NULL,
+    date_submitted timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    format integer NOT NULL,
+    status integer DEFAULT 1 NOT NULL,
+    private boolean NOT NULL,
+    contactable boolean NOT NULL,
+    submission_key text NOT NULL,
+    owner integer,
+    distroarchseries integer,
+    raw_submission integer NOT NULL,
+    system_fingerprint integer NOT NULL,
+    raw_emailaddress text
+);
 
 
-COMMENT ON COLUMN public.gitrepository.default_branch IS 'The reference path of this repository''s default branch, or "HEAD".';
+COMMENT ON TABLE public.hwsubmission IS 'Raw HWDB submission data';
 
 
-COMMENT ON COLUMN public.gitrepository.repository_type IS 'Repositories are currently one of HOSTED (1) or IMPORTED (3).';
+COMMENT ON COLUMN public.hwsubmission.date_created IS 'Date and time of the submission (generated by the client).';
 
 
-CREATE SEQUENCE public.gitrepository_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.hwsubmission.date_submitted IS 'Date and time of the submission (generated by the server).';
 
 
-ALTER SEQUENCE public.gitrepository_id_seq OWNED BY public.gitrepository.id;
+COMMENT ON COLUMN public.hwsubmission.format IS 'The format version of the submitted data, as given by the HWDB client. See HWSubmissionFormat for valid values.';
 
 
-CREATE TABLE public.gitrule (
-    id integer NOT NULL,
-    repository integer NOT NULL,
-    "position" integer NOT NULL,
-    ref_pattern text NOT NULL,
-    creator integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
-);
+COMMENT ON COLUMN public.hwsubmission.status IS 'The status of the submission. See HWSubmissionProcessingStatus for valid values.';
 
 
-COMMENT ON TABLE public.gitrule IS 'An access rule for a Git repository.';
+COMMENT ON COLUMN public.hwsubmission.private IS 'If false, the submitter allows public access to the data. If true, the data may be used only for statistical purposes.';
 
 
-COMMENT ON COLUMN public.gitrule.repository IS 'The repository that this rule is for.';
+COMMENT ON COLUMN public.hwsubmission.contactable IS 'If True, the submitter agrees to be contacted by upstream developers and package maintainers for tests etc.';
 
 
-COMMENT ON COLUMN public.gitrule."position" IS 'The position of this rule in its repository''s rule order.';
+COMMENT ON COLUMN public.hwsubmission.submission_key IS 'A unique submission ID.';
 
 
-COMMENT ON COLUMN public.gitrule.ref_pattern IS 'The pattern of references matched by this rule.';
+COMMENT ON COLUMN public.hwsubmission.owner IS 'A reference to the Person table: The owner/submitter of the data.';
 
 
-COMMENT ON COLUMN public.gitrule.creator IS 'The user who created this rule.';
+COMMENT ON COLUMN public.hwsubmission.distroarchseries IS 'A reference to the distroarchseries of the submission. This value is null, if the submitted values for distribution, distroseries and architecture do not match an existing entry in the Distroarchseries table.';
 
 
-COMMENT ON COLUMN public.gitrule.date_created IS 'The time when this rule was created.';
+COMMENT ON COLUMN public.hwsubmission.raw_submission IS 'A reference to a row of LibraryFileAlias. The library file contains the raw submission data.';
 
 
-COMMENT ON COLUMN public.gitrule.date_last_modified IS 'The time when this rule was last modified.';
+COMMENT ON COLUMN public.hwsubmission.system_fingerprint IS 'A reference to an entry of the HWDBSystemFingerPrint table. This table stores the system name as returned by HAL (system.vendor, system.product)';
+
+
+COMMENT ON COLUMN public.hwsubmission.raw_emailaddress IS 'The email address of the submitter.';
 
 
-CREATE SEQUENCE public.gitrule_id_seq
+CREATE SEQUENCE public.hwsubmission_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8321,59 +9512,55 @@ CREATE SEQUENCE public.gitrule_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.gitrule_id_seq OWNED BY public.gitrule.id;
+ALTER SEQUENCE public.hwsubmission_id_seq OWNED BY public.hwsubmission.id;
 
 
-CREATE TABLE public.gitrulegrant (
+CREATE TABLE public.hwsubmissionbug (
     id integer NOT NULL,
-    repository integer NOT NULL,
-    rule integer NOT NULL,
-    grantee_type integer NOT NULL,
-    grantee integer,
-    can_create boolean DEFAULT false NOT NULL,
-    can_push boolean DEFAULT false NOT NULL,
-    can_force_push boolean DEFAULT false NOT NULL,
-    grantor integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    CONSTRAINT has_grantee CHECK (((grantee_type = 2) = (grantee IS NOT NULL)))
+    submission integer NOT NULL,
+    bug integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.gitrulegrant IS 'An access grant for a Git repository rule.';
-
-
-COMMENT ON COLUMN public.gitrulegrant.repository IS 'The repository that this grant is for.';
-
-
-COMMENT ON COLUMN public.gitrulegrant.rule IS 'The rule that this grant is for.';
+COMMENT ON TABLE public.hwsubmissionbug IS 'Link bugs to HWDB submissions';
 
 
-COMMENT ON COLUMN public.gitrulegrant.grantee_type IS 'The type of entity being granted access.';
+CREATE SEQUENCE public.hwsubmissionbug_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitrulegrant.grantee IS 'The person or team being granted access.';
+ALTER SEQUENCE public.hwsubmissionbug_id_seq OWNED BY public.hwsubmissionbug.id;
 
 
-COMMENT ON COLUMN public.gitrulegrant.can_create IS 'Whether creating references is allowed.';
+CREATE TABLE public.hwsubmissiondevice (
+    id integer NOT NULL,
+    device_driver_link integer NOT NULL,
+    submission integer NOT NULL,
+    parent integer,
+    hal_device_id integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.gitrulegrant.can_push IS 'Whether pushing references is allowed.';
+COMMENT ON TABLE public.hwsubmissiondevice IS 'Links between devices and submissions.';
 
 
-COMMENT ON COLUMN public.gitrulegrant.can_force_push IS 'Whether force-pushing references is allowed.';
+COMMENT ON COLUMN public.hwsubmissiondevice.device_driver_link IS 'The combination (device, driver) mentioned in a submission.';
 
 
-COMMENT ON COLUMN public.gitrulegrant.grantor IS 'The user who created this grant.';
+COMMENT ON COLUMN public.hwsubmissiondevice.submission IS 'The submission mentioning this (device, driver) combination.';
 
 
-COMMENT ON COLUMN public.gitrulegrant.date_created IS 'The time when this grant was created.';
+COMMENT ON COLUMN public.hwsubmissiondevice.parent IS 'The parent device of this device.';
 
 
-COMMENT ON COLUMN public.gitrulegrant.date_last_modified IS 'The time when this grant was last modified.';
+COMMENT ON COLUMN public.hwsubmissiondevice.hal_device_id IS 'The ID of the HAL node of this device in the submitted data.';
 
 
-CREATE SEQUENCE public.gitrulegrant_id_seq
+CREATE SEQUENCE public.hwsubmissiondevice_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8381,47 +9568,50 @@ CREATE SEQUENCE public.gitrulegrant_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.gitrulegrant_id_seq OWNED BY public.gitrulegrant.id;
+ALTER SEQUENCE public.hwsubmissiondevice_id_seq OWNED BY public.hwsubmissiondevice.id;
 
 
-CREATE TABLE public.gitsubscription (
+CREATE TABLE public.hwsystemfingerprint (
     id integer NOT NULL,
-    person integer NOT NULL,
-    repository integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    notification_level integer DEFAULT 1 NOT NULL,
-    max_diff_lines integer,
-    review_level integer DEFAULT 0 NOT NULL,
-    subscribed_by integer NOT NULL,
-    paths text
+    fingerprint text NOT NULL
 );
 
 
-COMMENT ON TABLE public.gitsubscription IS 'An association between a person or team and a Git repository.';
+COMMENT ON TABLE public.hwsystemfingerprint IS 'A distinct list of "fingerprints" (HAL system.name, system.vendor) from raw submission data';
 
 
-COMMENT ON COLUMN public.gitsubscription.person IS 'The person or team associated with the repository.';
+COMMENT ON COLUMN public.hwsystemfingerprint.fingerprint IS 'The fingerprint';
 
 
-COMMENT ON COLUMN public.gitsubscription.repository IS 'The repository associated with the person or team.';
+CREATE SEQUENCE public.hwsystemfingerprint_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.gitsubscription.notification_level IS 'The level of email the person wants to receive from repository updates.';
+ALTER SEQUENCE public.hwsystemfingerprint_id_seq OWNED BY public.hwsystemfingerprint.id;
 
 
-COMMENT ON COLUMN public.gitsubscription.max_diff_lines IS 'If the generated diff for a revision is larger than this number, then the diff is not sent in the notification email.';
+CREATE TABLE public.hwtest (
+    id integer NOT NULL,
+    namespace text,
+    name text NOT NULL,
+    version text NOT NULL
+);
 
 
-COMMENT ON COLUMN public.gitsubscription.review_level IS 'The level of email the person wants to receive from review activity.';
+COMMENT ON TABLE public.hwtest IS 'General information about a device test.';
 
 
-COMMENT ON COLUMN public.gitsubscription.subscribed_by IS 'The person who created this subscription.';
+COMMENT ON COLUMN public.hwtest.namespace IS 'The namespace of a test.';
 
 
-COMMENT ON COLUMN public.gitsubscription.paths IS 'A JSON-encoded list of patterns matching subscribed reference paths.';
+COMMENT ON COLUMN public.hwtest.name IS 'The name of a test.';
 
 
-CREATE SEQUENCE public.gitsubscription_id_seq
+CREATE SEQUENCE public.hwtest_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8429,46 +9619,42 @@ CREATE SEQUENCE public.gitsubscription_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.gitsubscription_id_seq OWNED BY public.gitsubscription.id;
+ALTER SEQUENCE public.hwtest_id_seq OWNED BY public.hwtest.id;
 
 
-CREATE TABLE public.gpgkey (
+CREATE TABLE public.hwtestanswer (
     id integer NOT NULL,
-    owner integer NOT NULL,
-    keyid text NOT NULL,
-    fingerprint text NOT NULL,
-    active boolean NOT NULL,
-    algorithm integer NOT NULL,
-    keysize integer NOT NULL,
-    can_encrypt boolean DEFAULT false NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    CONSTRAINT valid_fingerprint CHECK (public.valid_fingerprint(fingerprint)),
-    CONSTRAINT valid_keyid CHECK (public.valid_keyid(keyid))
+    test integer NOT NULL,
+    choice integer,
+    intval integer,
+    floatval double precision,
+    unit text,
+    comment text,
+    language integer,
+    submission integer NOT NULL,
+    CONSTRAINT hwtestanswer_check CHECK ((((choice IS NULL) AND (unit IS NOT NULL) AND ((intval IS NULL) <> (floatval IS NULL))) OR ((choice IS NOT NULL) AND (unit IS NULL) AND (intval IS NULL) AND (floatval IS NULL))))
 );
 
 
-COMMENT ON TABLE public.gpgkey IS 'A GPG key belonging to a Person';
-
-
-COMMENT ON COLUMN public.gpgkey.keyid IS 'The 8 character GPG key id, uppercase and no whitespace';
+COMMENT ON TABLE public.hwtestanswer IS 'The answer for a test from a submission. This can be either a multiple choice selection or a numerical value. Exactly one of the columns choice, intval, floatval must be non-null.';
 
 
-COMMENT ON COLUMN public.gpgkey.fingerprint IS 'The 40 character GPG fingerprint, uppercase and no whitespace';
+COMMENT ON COLUMN public.hwtestanswer.test IS 'The test answered by this answer.';
 
 
-COMMENT ON COLUMN public.gpgkey.active IS 'True if this key is active for use in Launchpad context, false could be deactivated by user or revoked in the global key ring.';
+COMMENT ON COLUMN public.hwtestanswer.choice IS 'The selected value of a multiple choice test.';
 
 
-COMMENT ON COLUMN public.gpgkey.algorithm IS 'The algorithm used to generate this key. Valid values defined in dbschema.GPGKeyAlgorithms';
+COMMENT ON COLUMN public.hwtestanswer.intval IS 'The integer result of a test with a numerical result.';
 
 
-COMMENT ON COLUMN public.gpgkey.keysize IS 'Size of the key in bits, as reported by GPG. We may refuse to deal with keysizes < 768 bits in the future.';
+COMMENT ON COLUMN public.hwtestanswer.floatval IS 'The double precision floating point number result of a test with a numerical result.';
 
 
-COMMENT ON COLUMN public.gpgkey.can_encrypt IS 'Whether the key has been validated for use in encryption (as opposed to just signing)';
+COMMENT ON COLUMN public.hwtestanswer.unit IS 'The physical unit of a test with a numerical result.';
 
 
-CREATE SEQUENCE public.gpgkey_id_seq
+CREATE SEQUENCE public.hwtestanswer_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8476,38 +9662,26 @@ CREATE SEQUENCE public.gpgkey_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.gpgkey_id_seq OWNED BY public.gpgkey.id;
+ALTER SEQUENCE public.hwtestanswer_id_seq OWNED BY public.hwtestanswer.id;
 
 
-CREATE TABLE public.hwdevice (
+CREATE TABLE public.hwtestanswerchoice (
     id integer NOT NULL,
-    bus_vendor_id integer NOT NULL,
-    bus_product_id text NOT NULL,
-    variant text,
-    name text NOT NULL,
-    submissions integer NOT NULL
+    choice text NOT NULL,
+    test integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdevice IS 'Basic information on devices.';
-
-
-COMMENT ON COLUMN public.hwdevice.bus_vendor_id IS 'A reference to a HWVendorID record.';
-
-
-COMMENT ON COLUMN public.hwdevice.bus_product_id IS 'The bus product ID of a device';
-
-
-COMMENT ON COLUMN public.hwdevice.variant IS 'An optional additional description for a device that shares its vendor and product ID with another, technically different, device.';
+COMMENT ON TABLE public.hwtestanswerchoice IS 'Choice values of multiple choice tests/questions.';
 
 
-COMMENT ON COLUMN public.hwdevice.name IS 'The human readable product name of the device.';
+COMMENT ON COLUMN public.hwtestanswerchoice.choice IS 'The choice value.';
 
 
-COMMENT ON COLUMN public.hwdevice.submissions IS 'The number of submissions that contain this device.';
+COMMENT ON COLUMN public.hwtestanswerchoice.test IS 'The test this choice belongs to.';
 
 
-CREATE SEQUENCE public.hwdevice_id_seq
+CREATE SEQUENCE public.hwtestanswerchoice_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8515,30 +9689,47 @@ CREATE SEQUENCE public.hwdevice_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdevice_id_seq OWNED BY public.hwdevice.id;
+ALTER SEQUENCE public.hwtestanswerchoice_id_seq OWNED BY public.hwtestanswerchoice.id;
 
 
-CREATE TABLE public.hwdeviceclass (
+CREATE TABLE public.hwtestanswercount (
     id integer NOT NULL,
-    device integer NOT NULL,
-    main_class integer NOT NULL,
-    sub_class integer
+    test integer NOT NULL,
+    distroarchseries integer,
+    choice integer,
+    average double precision,
+    sum_square double precision,
+    unit text,
+    num_answers integer NOT NULL,
+    CONSTRAINT hwtestanswercount_check CHECK ((((choice IS NULL) AND (average IS NOT NULL) AND (sum_square IS NOT NULL) AND (unit IS NOT NULL)) OR ((choice IS NOT NULL) AND (average IS NULL) AND (sum_square IS NULL) AND (unit IS NULL))))
 );
 
 
-COMMENT ON TABLE public.hwdeviceclass IS 'Capabilities of a device.';
+COMMENT ON TABLE public.hwtestanswercount IS 'Accumulated results of tests. Either the column choice or the columns average and sum_square must be non-null.';
 
 
-COMMENT ON COLUMN public.hwdeviceclass.device IS 'A reference to a device.';
+COMMENT ON COLUMN public.hwtestanswercount.test IS 'The test.';
 
 
-COMMENT ON COLUMN public.hwdeviceclass.main_class IS 'The main class of a device. Legal values are defined by the HWMainClass enumeration.';
+COMMENT ON COLUMN public.hwtestanswercount.distroarchseries IS 'The distroarchseries for which results are accumulated,';
 
 
-COMMENT ON COLUMN public.hwdeviceclass.sub_class IS 'The sub-class of a device. Legal values are defined by the HWSubClass enumeration.';
+COMMENT ON COLUMN public.hwtestanswercount.choice IS 'The choice value of a multiple choice test.';
 
 
-CREATE SEQUENCE public.hwdeviceclass_id_seq
+COMMENT ON COLUMN public.hwtestanswercount.average IS 'The average value of the result of a numerical test.';
+
+
+COMMENT ON COLUMN public.hwtestanswercount.sum_square IS 'The sum of the squares of the results of a numerical test.';
+
+
+COMMENT ON COLUMN public.hwtestanswercount.unit IS 'The physical unit of a numerical test result.';
+
+
+COMMENT ON COLUMN public.hwtestanswercount.num_answers IS 'The number of submissions from which the result is accumulated.';
+
+
+CREATE SEQUENCE public.hwtestanswercount_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8546,26 +9737,26 @@ CREATE SEQUENCE public.hwdeviceclass_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdeviceclass_id_seq OWNED BY public.hwdeviceclass.id;
+ALTER SEQUENCE public.hwtestanswercount_id_seq OWNED BY public.hwtestanswercount.id;
 
 
-CREATE TABLE public.hwdevicedriverlink (
+CREATE TABLE public.hwtestanswercountdevice (
     id integer NOT NULL,
-    device integer NOT NULL,
-    driver integer
+    answer integer NOT NULL,
+    device_driver integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdevicedriverlink IS 'Combinations of devices and drivers mentioned in submissions.';
+COMMENT ON TABLE public.hwtestanswercountdevice IS 'Association of accumulated test results and device/driver combinations.';
 
 
-COMMENT ON COLUMN public.hwdevicedriverlink.device IS 'The device controlled by the driver.';
+COMMENT ON COLUMN public.hwtestanswercountdevice.answer IS 'The test answer.';
 
 
-COMMENT ON COLUMN public.hwdevicedriverlink.driver IS 'The driver controlling the device.';
+COMMENT ON COLUMN public.hwtestanswercountdevice.device_driver IS 'The device/driver combination.';
 
 
-CREATE SEQUENCE public.hwdevicedriverlink_id_seq
+CREATE SEQUENCE public.hwtestanswercountdevice_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8573,34 +9764,26 @@ CREATE SEQUENCE public.hwdevicedriverlink_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdevicedriverlink_id_seq OWNED BY public.hwdevicedriverlink.id;
+ALTER SEQUENCE public.hwtestanswercountdevice_id_seq OWNED BY public.hwtestanswercountdevice.id;
 
 
-CREATE TABLE public.hwdevicenamevariant (
+CREATE TABLE public.hwtestanswerdevice (
     id integer NOT NULL,
-    vendor_name integer NOT NULL,
-    product_name text NOT NULL,
-    device integer NOT NULL,
-    submissions integer NOT NULL
+    answer integer NOT NULL,
+    device_driver integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdevicenamevariant IS 'Alternative vendor and product names of devices.';
-
-
-COMMENT ON COLUMN public.hwdevicenamevariant.vendor_name IS 'The alternative vendor name.';
-
-
-COMMENT ON COLUMN public.hwdevicenamevariant.product_name IS 'The alternative product name.';
+COMMENT ON TABLE public.hwtestanswerdevice IS 'Association of test results and device/driver combinations.';
 
 
-COMMENT ON COLUMN public.hwdevicenamevariant.device IS 'The device named by this alternative vendor and product names.';
+COMMENT ON COLUMN public.hwtestanswerdevice.answer IS 'The test answer.';
 
 
-COMMENT ON COLUMN public.hwdevicenamevariant.submissions IS 'The number of submissions containing this alternative vendor and product name.';
+COMMENT ON COLUMN public.hwtestanswerdevice.device_driver IS 'The device/driver combination.';
 
 
-CREATE SEQUENCE public.hwdevicenamevariant_id_seq
+CREATE SEQUENCE public.hwtestanswerdevice_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8608,27 +9791,27 @@ CREATE SEQUENCE public.hwdevicenamevariant_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdevicenamevariant_id_seq OWNED BY public.hwdevicenamevariant.id;
+ALTER SEQUENCE public.hwtestanswerdevice_id_seq OWNED BY public.hwtestanswerdevice.id;
 
 
-CREATE TABLE public.hwdmihandle (
+CREATE TABLE public.hwvendorid (
     id integer NOT NULL,
-    handle integer NOT NULL,
-    type integer NOT NULL,
-    submission integer
+    bus integer NOT NULL,
+    vendor_id_for_bus text NOT NULL,
+    vendor_name integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdmihandle IS 'A DMI Handle appearing in the DMI data of a submission.';
+COMMENT ON TABLE public.hwvendorid IS 'Associates tuples (bus, vendor ID for this bus) with vendor names.';
 
 
-COMMENT ON COLUMN public.hwdmihandle.handle IS 'The ID of the handle.';
+COMMENT ON COLUMN public.hwvendorid.bus IS 'The bus.';
 
 
-COMMENT ON COLUMN public.hwdmihandle.type IS 'The type of the handle.';
+COMMENT ON COLUMN public.hwvendorid.vendor_id_for_bus IS 'The ID of a vendor for the bus given by column `bus`';
 
 
-CREATE SEQUENCE public.hwdmihandle_id_seq
+CREATE SEQUENCE public.hwvendorid_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8636,30 +9819,22 @@ CREATE SEQUENCE public.hwdmihandle_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdmihandle_id_seq OWNED BY public.hwdmihandle.id;
+ALTER SEQUENCE public.hwvendorid_id_seq OWNED BY public.hwvendorid.id;
 
 
-CREATE TABLE public.hwdmivalue (
+CREATE TABLE public.hwvendorname (
     id integer NOT NULL,
-    key text,
-    value text,
-    handle integer NOT NULL
+    name text NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdmivalue IS 'Key/value pairs of DMI data of a handle.';
-
-
-COMMENT ON COLUMN public.hwdmivalue.key IS 'The key.';
-
-
-COMMENT ON COLUMN public.hwdmivalue.value IS 'The value';
+COMMENT ON TABLE public.hwvendorname IS 'A list of hardware vendor names.';
 
 
-COMMENT ON COLUMN public.hwdmivalue.handle IS 'The handle to which this key/value pair belongs.';
+COMMENT ON COLUMN public.hwvendorname.name IS 'The name of a vendor.';
 
 
-CREATE SEQUENCE public.hwdmivalue_id_seq
+CREATE SEQUENCE public.hwvendorname_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8667,27 +9842,34 @@ CREATE SEQUENCE public.hwdmivalue_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdmivalue_id_seq OWNED BY public.hwdmivalue.id;
+ALTER SEQUENCE public.hwvendorname_id_seq OWNED BY public.hwvendorname.id;
 
 
-CREATE TABLE public.hwdriver (
+CREATE TABLE public.incrementaldiff (
     id integer NOT NULL,
-    package_name text,
-    name text NOT NULL,
-    license integer
+    diff integer NOT NULL,
+    branch_merge_proposal integer NOT NULL,
+    old_revision integer NOT NULL,
+    new_revision integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwdriver IS 'Information about a driver for a device';
+COMMENT ON TABLE public.incrementaldiff IS 'Incremental diffs for merge proposals.';
 
 
-COMMENT ON COLUMN public.hwdriver.package_name IS 'The Debian package name a driver is a part of';
+COMMENT ON COLUMN public.incrementaldiff.diff IS 'The contents of the diff.';
 
 
-COMMENT ON COLUMN public.hwdriver.name IS 'The name of a driver.';
+COMMENT ON COLUMN public.incrementaldiff.branch_merge_proposal IS 'The merge proposal the diff is for.';
 
 
-CREATE SEQUENCE public.hwdriver_id_seq
+COMMENT ON COLUMN public.incrementaldiff.old_revision IS 'The revision the diff is from.';
+
+
+COMMENT ON COLUMN public.incrementaldiff.new_revision IS 'The revision the diff is to.';
+
+
+CREATE SEQUENCE public.incrementaldiff_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8695,113 +9877,113 @@ CREATE SEQUENCE public.hwdriver_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwdriver_id_seq OWNED BY public.hwdriver.id;
+ALTER SEQUENCE public.incrementaldiff_id_seq OWNED BY public.incrementaldiff.id;
 
 
-CREATE VIEW public.hwdrivernames AS
- SELECT DISTINCT ON (hwdriver.name) hwdriver.id,
-    hwdriver.name
-   FROM public.hwdriver
-  ORDER BY hwdriver.name, hwdriver.id;
+CREATE TABLE public.ircid (
+    id integer NOT NULL,
+    person integer NOT NULL,
+    network text NOT NULL,
+    nickname text NOT NULL
+);
 
 
-COMMENT ON VIEW public.hwdrivernames IS 'A view returning the distinct driver names stored in HWDriver.';
+CREATE SEQUENCE public.ircid_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.hwdrivernames.name IS 'The name of a driver.';
+ALTER SEQUENCE public.ircid_id_seq OWNED BY public.ircid.id;
 
 
-CREATE VIEW public.hwdriverpackagenames AS
- SELECT DISTINCT ON (hwdriver.package_name) hwdriver.id,
-    hwdriver.package_name
-   FROM public.hwdriver
-  ORDER BY hwdriver.package_name, hwdriver.id;
+CREATE TABLE public.jabberid (
+    id integer NOT NULL,
+    person integer NOT NULL,
+    jabberid text NOT NULL
+);
 
 
-COMMENT ON VIEW public.hwdriverpackagenames IS 'A view returning the distinct Debian package names stored in HWDriver.';
+CREATE SEQUENCE public.jabberid_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.hwdriverpackagenames.package_name IS 'The Debian package name a driver is a part of.';
+ALTER SEQUENCE public.jabberid_id_seq OWNED BY public.jabberid.id;
 
 
-CREATE TABLE public.hwsubmission (
+CREATE TABLE public.job (
     id integer NOT NULL,
-    date_created timestamp without time zone NOT NULL,
-    date_submitted timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    format integer NOT NULL,
-    status integer DEFAULT 1 NOT NULL,
-    private boolean NOT NULL,
-    contactable boolean NOT NULL,
-    submission_key text NOT NULL,
-    owner integer,
-    distroarchseries integer,
-    raw_submission integer NOT NULL,
-    system_fingerprint integer NOT NULL,
-    raw_emailaddress text
+    requester integer,
+    reason text,
+    status integer NOT NULL,
+    progress integer,
+    last_report_seen timestamp without time zone,
+    next_report_due timestamp without time zone,
+    attempt_count integer DEFAULT 0 NOT NULL,
+    max_retries integer DEFAULT 0 NOT NULL,
+    log text,
+    scheduled_start timestamp without time zone,
+    lease_expires timestamp without time zone,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_started timestamp without time zone,
+    date_finished timestamp without time zone,
+    json_data text,
+    job_type integer
 );
 
 
-COMMENT ON TABLE public.hwsubmission IS 'Raw HWDB submission data';
-
-
-COMMENT ON COLUMN public.hwsubmission.date_created IS 'Date and time of the submission (generated by the client).';
-
-
-COMMENT ON COLUMN public.hwsubmission.date_submitted IS 'Date and time of the submission (generated by the server).';
+COMMENT ON TABLE public.job IS 'Common info about a job.';
 
 
-COMMENT ON COLUMN public.hwsubmission.format IS 'The format version of the submitted data, as given by the HWDB client. See HWSubmissionFormat for valid values.';
+COMMENT ON COLUMN public.job.requester IS 'Ther person who requested this job (if applicable).';
 
 
-COMMENT ON COLUMN public.hwsubmission.status IS 'The status of the submission. See HWSubmissionProcessingStatus for valid values.';
+COMMENT ON COLUMN public.job.reason IS 'The reason that this job was created (if applicable)';
 
 
-COMMENT ON COLUMN public.hwsubmission.private IS 'If false, the submitter allows public access to the data. If true, the data may be used only for statistical purposes.';
+COMMENT ON COLUMN public.job.status IS 'An enum (JobStatus) indicating the job status, one of: new, in-progress, complete, failed, cancelling, cancelled.';
 
 
-COMMENT ON COLUMN public.hwsubmission.contactable IS 'If True, the submitter agrees to be contacted by upstream developers and package maintainers for tests etc.';
+COMMENT ON COLUMN public.job.progress IS 'The percentage complete.  Can be NULL for some jobs that do not report progress.';
 
 
-COMMENT ON COLUMN public.hwsubmission.submission_key IS 'A unique submission ID.';
+COMMENT ON COLUMN public.job.last_report_seen IS 'The last time the progress was reported.';
 
 
-COMMENT ON COLUMN public.hwsubmission.owner IS 'A reference to the Person table: The owner/submitter of the data.';
+COMMENT ON COLUMN public.job.next_report_due IS 'The next time a progress report is expected.';
 
 
-COMMENT ON COLUMN public.hwsubmission.distroarchseries IS 'A reference to the distroarchseries of the submission. This value is null, if the submitted values for distribution, distroseries and architecture do not match an existing entry in the Distroarchseries table.';
+COMMENT ON COLUMN public.job.attempt_count IS 'The number of times this job has been attempted.';
 
 
-COMMENT ON COLUMN public.hwsubmission.raw_submission IS 'A reference to a row of LibraryFileAlias. The library file contains the raw submission data.';
+COMMENT ON COLUMN public.job.max_retries IS 'The maximum number of retries valid for this job.';
 
 
-COMMENT ON COLUMN public.hwsubmission.system_fingerprint IS 'A reference to an entry of the HWDBSystemFingerPrint table. This table stores the system name as returned by HAL (system.vendor, system.product)';
+COMMENT ON COLUMN public.job.log IS 'If provided, this is the tail of the log file being generated by the running job.';
 
 
-COMMENT ON COLUMN public.hwsubmission.raw_emailaddress IS 'The email address of the submitter.';
+COMMENT ON COLUMN public.job.scheduled_start IS 'The time when the job should start';
 
 
-CREATE SEQUENCE public.hwsubmission_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.job.lease_expires IS 'The time when the lease expires.';
 
 
-ALTER SEQUENCE public.hwsubmission_id_seq OWNED BY public.hwsubmission.id;
+COMMENT ON COLUMN public.job.date_created IS 'The time when the job was created.';
 
 
-CREATE TABLE public.hwsubmissionbug (
-    id integer NOT NULL,
-    submission integer NOT NULL,
-    bug integer NOT NULL
-);
+COMMENT ON COLUMN public.job.date_started IS 'If the job has started, the time when the job started.';
 
 
-COMMENT ON TABLE public.hwsubmissionbug IS 'Link bugs to HWDB submissions';
+COMMENT ON COLUMN public.job.date_finished IS 'If the job has finished, the time when the job finished.';
 
 
-CREATE SEQUENCE public.hwsubmissionbug_id_seq
+CREATE SEQUENCE public.job_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8809,57 +9991,43 @@ CREATE SEQUENCE public.hwsubmissionbug_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwsubmissionbug_id_seq OWNED BY public.hwsubmissionbug.id;
+ALTER SEQUENCE public.job_id_seq OWNED BY public.job.id;
 
 
-CREATE TABLE public.hwsubmissiondevice (
+CREATE TABLE public.karma (
     id integer NOT NULL,
-    device_driver_link integer NOT NULL,
-    submission integer NOT NULL,
-    parent integer,
-    hal_device_id integer NOT NULL
-);
-
-
-COMMENT ON TABLE public.hwsubmissiondevice IS 'Links between devices and submissions.';
-
-
-COMMENT ON COLUMN public.hwsubmissiondevice.device_driver_link IS 'The combination (device, driver) mentioned in a submission.';
-
-
-COMMENT ON COLUMN public.hwsubmissiondevice.submission IS 'The submission mentioning this (device, driver) combination.';
+    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    person integer NOT NULL,
+    action integer NOT NULL,
+    product integer,
+    distribution integer,
+    sourcepackagename integer
+)
+WITH (fillfactor='100');
 
 
-COMMENT ON COLUMN public.hwsubmissiondevice.parent IS 'The parent device of this device.';
+COMMENT ON TABLE public.karma IS 'Used to quantify all the ''operations'' a user performs inside the system, which maybe reporting and fixing bugs, uploading packages, end-user support, wiki editting, etc.';
 
 
-COMMENT ON COLUMN public.hwsubmissiondevice.hal_device_id IS 'The ID of the HAL node of this device in the submitted data.';
+COMMENT ON COLUMN public.karma.datecreated IS 'A timestamp for the assignment of this Karma.';
 
 
-CREATE SEQUENCE public.hwsubmissiondevice_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.karma.person IS 'The Person for wich this Karma was assigned.';
 
 
-ALTER SEQUENCE public.hwsubmissiondevice_id_seq OWNED BY public.hwsubmissiondevice.id;
+COMMENT ON COLUMN public.karma.action IS 'A foreign key to the KarmaAction table.';
 
 
-CREATE TABLE public.hwsystemfingerprint (
-    id integer NOT NULL,
-    fingerprint text NOT NULL
-);
+COMMENT ON COLUMN public.karma.product IS 'The Project to which this Product belongs.  An entry on this table with a non-NULL Project and a NULL Product represents the total karma of the person across all products of that project..';
 
 
-COMMENT ON TABLE public.hwsystemfingerprint IS 'A distinct list of "fingerprints" (HAL system.name, system.vendor) from raw submission data';
+COMMENT ON COLUMN public.karma.distribution IS 'The Distribution on which a person performed an action that resulted on this karma.';
 
 
-COMMENT ON COLUMN public.hwsystemfingerprint.fingerprint IS 'The fingerprint';
+COMMENT ON COLUMN public.karma.sourcepackagename IS 'The SourcePackageName on which a person performed an action that resulted on this karma.';
 
 
-CREATE SEQUENCE public.hwsystemfingerprint_id_seq
+CREATE SEQUENCE public.karma_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8867,27 +10035,32 @@ CREATE SEQUENCE public.hwsystemfingerprint_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwsystemfingerprint_id_seq OWNED BY public.hwsystemfingerprint.id;
+ALTER SEQUENCE public.karma_id_seq OWNED BY public.karma.id;
 
 
-CREATE TABLE public.hwtest (
+CREATE TABLE public.karmaaction (
     id integer NOT NULL,
-    namespace text,
+    category integer,
+    points integer,
     name text NOT NULL,
-    version text NOT NULL
+    title text NOT NULL,
+    summary text NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwtest IS 'General information about a device test.';
+COMMENT ON TABLE public.karmaaction IS 'Stores all the actions that would give karma to the user which performed it.';
 
 
-COMMENT ON COLUMN public.hwtest.namespace IS 'The namespace of a test.';
+COMMENT ON COLUMN public.karmaaction.category IS 'A dbschema value used to group actions together.';
 
 
-COMMENT ON COLUMN public.hwtest.name IS 'The name of a test.';
+COMMENT ON COLUMN public.karmaaction.points IS 'The number of points this action is worth of.';
 
 
-CREATE SEQUENCE public.hwtest_id_seq
+COMMENT ON COLUMN public.karmaaction.name IS 'The unique name of this action.';
+
+
+CREATE SEQUENCE public.karmaaction_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8895,42 +10068,38 @@ CREATE SEQUENCE public.hwtest_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwtest_id_seq OWNED BY public.hwtest.id;
+ALTER SEQUENCE public.karmaaction_id_seq OWNED BY public.karmaaction.id;
 
 
-CREATE TABLE public.hwtestanswer (
-    id integer NOT NULL,
-    test integer NOT NULL,
-    choice integer,
-    intval integer,
-    floatval double precision,
-    unit text,
-    comment text,
-    language integer,
-    submission integer NOT NULL,
-    CONSTRAINT hwtestanswer_check CHECK (((((choice IS NULL) AND (unit IS NOT NULL)) AND ((intval IS NULL) <> (floatval IS NULL))) OR ((((choice IS NOT NULL) AND (unit IS NULL)) AND (intval IS NULL)) AND (floatval IS NULL))))
+CREATE TABLE public.karmacache (
+    person integer NOT NULL,
+    category integer,
+    karmavalue integer NOT NULL,
+    product integer,
+    distribution integer,
+    sourcepackagename integer,
+    project integer,
+    id bigint NOT NULL,
+    CONSTRAINT just_distribution CHECK (((distribution IS NULL) OR ((product IS NULL) AND (project IS NULL)))),
+    CONSTRAINT just_product CHECK (((product IS NULL) OR ((project IS NULL) AND (distribution IS NULL)))),
+    CONSTRAINT just_project CHECK (((project IS NULL) OR ((product IS NULL) AND (distribution IS NULL)))),
+    CONSTRAINT sourcepackagename_requires_distribution CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
 );
 
 
-COMMENT ON TABLE public.hwtestanswer IS 'The answer for a test from a submission. This can be either a multiple choice selection or a numerical value. Exactly one of the columns choice, intval, floatval must be non-null.';
-
-
-COMMENT ON COLUMN public.hwtestanswer.test IS 'The test answered by this answer.';
-
-
-COMMENT ON COLUMN public.hwtestanswer.choice IS 'The selected value of a multiple choice test.';
+COMMENT ON TABLE public.karmacache IS 'Stores a cached value of a person''s karma points, grouped by the action category and the context where that action was performed.';
 
 
-COMMENT ON COLUMN public.hwtestanswer.intval IS 'The integer result of a test with a numerical result.';
+COMMENT ON COLUMN public.karmacache.person IS 'The person which performed the actions of this category, and thus got the karma.';
 
 
-COMMENT ON COLUMN public.hwtestanswer.floatval IS 'The double precision floating point number result of a test with a numerical result.';
+COMMENT ON COLUMN public.karmacache.category IS 'The category of the actions.';
 
 
-COMMENT ON COLUMN public.hwtestanswer.unit IS 'The physical unit of a test with a numerical result.';
+COMMENT ON COLUMN public.karmacache.karmavalue IS 'The karma points of all actions of this category performed by this person on this context (product/distribution).';
 
 
-CREATE SEQUENCE public.hwtestanswer_id_seq
+CREATE SEQUENCE public.karmacache_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8938,26 +10107,41 @@ CREATE SEQUENCE public.hwtestanswer_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwtestanswer_id_seq OWNED BY public.hwtestanswer.id;
+ALTER SEQUENCE public.karmacache_id_seq OWNED BY public.karmacache.id;
 
 
-CREATE TABLE public.hwtestanswerchoice (
+CREATE TABLE public.karmacategory (
     id integer NOT NULL,
-    choice text NOT NULL,
-    test integer NOT NULL
+    name text NOT NULL,
+    title text NOT NULL,
+    summary text NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwtestanswerchoice IS 'Choice values of multiple choice tests/questions.';
+COMMENT ON TABLE public.karmacategory IS 'A category of karma. This allows us to
+present an overall picture of the different areas where a user has been
+active.';
 
 
-COMMENT ON COLUMN public.hwtestanswerchoice.choice IS 'The choice value.';
+CREATE SEQUENCE public.karmacategory_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.hwtestanswerchoice.test IS 'The test this choice belongs to.';
+ALTER SEQUENCE public.karmacategory_id_seq OWNED BY public.karmacategory.id;
 
 
-CREATE SEQUENCE public.hwtestanswerchoice_id_seq
+CREATE TABLE public.karmatotalcache (
+    id integer NOT NULL,
+    person integer NOT NULL,
+    karma_total integer NOT NULL
+);
+
+
+CREATE SEQUENCE public.karmatotalcache_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -8965,47 +10149,51 @@ CREATE SEQUENCE public.hwtestanswerchoice_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwtestanswerchoice_id_seq OWNED BY public.hwtestanswerchoice.id;
+ALTER SEQUENCE public.karmatotalcache_id_seq OWNED BY public.karmatotalcache.id;
 
 
-CREATE TABLE public.hwtestanswercount (
+CREATE TABLE public.language (
     id integer NOT NULL,
-    test integer NOT NULL,
-    distroarchseries integer,
-    choice integer,
-    average double precision,
-    sum_square double precision,
-    unit text,
-    num_answers integer NOT NULL,
-    CONSTRAINT hwtestanswercount_check CHECK ((((((choice IS NULL) AND (average IS NOT NULL)) AND (sum_square IS NOT NULL)) AND (unit IS NOT NULL)) OR ((((choice IS NOT NULL) AND (average IS NULL)) AND (sum_square IS NULL)) AND (unit IS NULL))))
+    code text NOT NULL,
+    englishname text NOT NULL,
+    nativename text,
+    pluralforms integer,
+    pluralexpression text,
+    visible boolean NOT NULL,
+    direction integer DEFAULT 0 NOT NULL,
+    uuid text,
+    CONSTRAINT valid_language CHECK (((pluralforms IS NULL) = (pluralexpression IS NULL)))
 );
 
 
-COMMENT ON TABLE public.hwtestanswercount IS 'Accumulated results of tests. Either the column choice or the columns average and sum_square must be non-null.';
+COMMENT ON TABLE public.language IS 'A human language.';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.test IS 'The test.';
+COMMENT ON COLUMN public.language.code IS 'The ISO 639 code for this language';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.distroarchseries IS 'The distroarchseries for which results are accumulated,';
+COMMENT ON COLUMN public.language.englishname IS 'The english name for this language';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.choice IS 'The choice value of a multiple choice test.';
+COMMENT ON COLUMN public.language.nativename IS 'The name of this language in the language itself';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.average IS 'The average value of the result of a numerical test.';
+COMMENT ON COLUMN public.language.pluralforms IS 'The number of plural forms this language has';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.sum_square IS 'The sum of the squares of the results of a numerical test.';
+COMMENT ON COLUMN public.language.pluralexpression IS 'The plural expression for this language, as used by gettext';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.unit IS 'The physical unit of a numerical test result.';
+COMMENT ON COLUMN public.language.visible IS 'Whether this language should usually be visible or not';
 
 
-COMMENT ON COLUMN public.hwtestanswercount.num_answers IS 'The number of submissions from which the result is accumulated.';
+COMMENT ON COLUMN public.language.direction IS 'The direction that text is written in this language';
 
 
-CREATE SEQUENCE public.hwtestanswercount_id_seq
+COMMENT ON COLUMN public.language.uuid IS 'Mozilla language pack unique ID';
+
+
+CREATE SEQUENCE public.language_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9013,53 +10201,43 @@ CREATE SEQUENCE public.hwtestanswercount_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwtestanswercount_id_seq OWNED BY public.hwtestanswercount.id;
+ALTER SEQUENCE public.language_id_seq OWNED BY public.language.id;
 
 
-CREATE TABLE public.hwtestanswercountdevice (
+CREATE TABLE public.languagepack (
     id integer NOT NULL,
-    answer integer NOT NULL,
-    device_driver integer NOT NULL
+    file integer NOT NULL,
+    date_exported timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_last_used timestamp without time zone DEFAULT timezone('UTC'::text, now()),
+    distroseries integer NOT NULL,
+    type integer DEFAULT 1 NOT NULL,
+    updates integer,
+    CONSTRAINT valid_updates CHECK ((((type = 2) AND (updates IS NOT NULL)) OR ((type = 1) AND (updates IS NULL))))
 );
 
 
-COMMENT ON TABLE public.hwtestanswercountdevice IS 'Association of accumulated test results and device/driver combinations.';
-
-
-COMMENT ON COLUMN public.hwtestanswercountdevice.answer IS 'The test answer.';
-
-
-COMMENT ON COLUMN public.hwtestanswercountdevice.device_driver IS 'The device/driver combination.';
+COMMENT ON TABLE public.languagepack IS 'Store exported language packs for DistroSeries.';
 
 
-CREATE SEQUENCE public.hwtestanswercountdevice_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.languagepack.file IS 'Librarian file where the language pack is stored.';
 
 
-ALTER SEQUENCE public.hwtestanswercountdevice_id_seq OWNED BY public.hwtestanswercountdevice.id;
+COMMENT ON COLUMN public.languagepack.date_exported IS 'When was exported the language pack.';
 
 
-CREATE TABLE public.hwtestanswerdevice (
-    id integer NOT NULL,
-    answer integer NOT NULL,
-    device_driver integer NOT NULL
-);
+COMMENT ON COLUMN public.languagepack.date_last_used IS 'When did we stop using the language pack. It''s used to decide whether we can remove it completely from the system. When it''s being used, its value is NULL';
 
 
-COMMENT ON TABLE public.hwtestanswerdevice IS 'Association of test results and device/driver combinations.';
+COMMENT ON COLUMN public.languagepack.distroseries IS 'The distribution series from where this language pack was exported.';
 
 
-COMMENT ON COLUMN public.hwtestanswerdevice.answer IS 'The test answer.';
+COMMENT ON COLUMN public.languagepack.type IS 'Type of language pack. There are two types available, 1: Full export, 2: Update export based on language_pack_that_updates export.';
 
 
-COMMENT ON COLUMN public.hwtestanswerdevice.device_driver IS 'The device/driver combination.';
+COMMENT ON COLUMN public.languagepack.updates IS 'The LanguagePack that this one updates.';
 
 
-CREATE SEQUENCE public.hwtestanswerdevice_id_seq
+CREATE SEQUENCE public.languagepack_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9067,50 +10245,73 @@ CREATE SEQUENCE public.hwtestanswerdevice_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwtestanswerdevice_id_seq OWNED BY public.hwtestanswerdevice.id;
+ALTER SEQUENCE public.languagepack_id_seq OWNED BY public.languagepack.id;
 
 
-CREATE TABLE public.hwvendorid (
+CREATE VIEW public.latestdatabasediskutilization AS
+ SELECT databasediskutilization.date_created,
+    databasediskutilization.namespace,
+    databasediskutilization.name,
+    databasediskutilization.sub_namespace,
+    databasediskutilization.sub_name,
+    databasediskutilization.kind,
+    databasediskutilization.sort,
+    databasediskutilization.table_len,
+    databasediskutilization.tuple_count,
+    databasediskutilization.tuple_len,
+    databasediskutilization.tuple_percent,
+    databasediskutilization.dead_tuple_count,
+    databasediskutilization.dead_tuple_len,
+    databasediskutilization.dead_tuple_percent,
+    databasediskutilization.free_space,
+    databasediskutilization.free_percent
+   FROM public.databasediskutilization
+  WHERE (databasediskutilization.date_created = ( SELECT max(databasediskutilization_1.date_created) AS max
+           FROM public.databasediskutilization databasediskutilization_1));
+
+
+CREATE TABLE public.latestpersonsourcepackagereleasecache (
     id integer NOT NULL,
-    bus integer NOT NULL,
-    vendor_id_for_bus text NOT NULL,
-    vendor_name integer NOT NULL
+    publication integer NOT NULL,
+    date_uploaded timestamp without time zone NOT NULL,
+    creator integer,
+    maintainer integer,
+    archive_purpose integer NOT NULL,
+    upload_archive integer NOT NULL,
+    upload_distroseries integer NOT NULL,
+    sourcepackagename integer NOT NULL,
+    sourcepackagerelease integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.hwvendorid IS 'Associates tuples (bus, vendor ID for this bus) with vendor names.';
+COMMENT ON TABLE public.latestpersonsourcepackagereleasecache IS 'LatestPersonSourcePackageReleaseCache: The most recent published source package releases for a given (distroseries, archive, sourcepackage).';
 
 
-COMMENT ON COLUMN public.hwvendorid.bus IS 'The bus.';
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.date_uploaded IS 'The date/time on which the source was actually published into the archive.';
 
 
-COMMENT ON COLUMN public.hwvendorid.vendor_id_for_bus IS 'The ID of a vendor for the bus given by column `bus`';
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.creator IS 'The creator of the source package release.';
 
 
-CREATE SEQUENCE public.hwvendorid_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.maintainer IS 'The maintainer of the source package in the DSC.';
 
 
-ALTER SEQUENCE public.hwvendorid_id_seq OWNED BY public.hwvendorid.id;
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.archive_purpose IS 'The purpose of the archive, e.g. COMMERCIAL.  See the ArchivePurpose DBSchema item.';
 
 
-CREATE TABLE public.hwvendorname (
-    id integer NOT NULL,
-    name text NOT NULL
-);
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.upload_archive IS 'The target archive for the release.';
 
 
-COMMENT ON TABLE public.hwvendorname IS 'A list of hardware vendor names.';
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.upload_distroseries IS 'The distroseries into which the sourcepackagerelease was published.';
 
 
-COMMENT ON COLUMN public.hwvendorname.name IS 'The name of a vendor.';
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.sourcepackagename IS 'The SourcePackageName of the release.';
 
 
-CREATE SEQUENCE public.hwvendorname_id_seq
+COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.sourcepackagerelease IS 'The sourcepackagerelease which was published.';
+
+
+CREATE SEQUENCE public.latestpersonsourcepackagereleasecache_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9118,53 +10319,47 @@ CREATE SEQUENCE public.hwvendorname_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.hwvendorname_id_seq OWNED BY public.hwvendorname.id;
+ALTER SEQUENCE public.latestpersonsourcepackagereleasecache_id_seq OWNED BY public.latestpersonsourcepackagereleasecache.id;
 
 
-CREATE TABLE public.incrementaldiff (
-    id integer NOT NULL,
-    diff integer NOT NULL,
-    branch_merge_proposal integer NOT NULL,
-    old_revision integer NOT NULL,
-    new_revision integer NOT NULL
+CREATE TABLE public.launchpaddatabaserevision (
+    major integer NOT NULL,
+    minor integer NOT NULL,
+    patch integer NOT NULL,
+    start_time timestamp without time zone DEFAULT timezone('UTC'::text, transaction_timestamp()),
+    end_time timestamp without time zone DEFAULT timezone('UTC'::text, clock_timestamp()),
+    branch_nick text,
+    revno integer,
+    revid text
 );
 
 
-COMMENT ON TABLE public.incrementaldiff IS 'Incremental diffs for merge proposals.';
-
-
-COMMENT ON COLUMN public.incrementaldiff.diff IS 'The contents of the diff.';
-
-
-COMMENT ON COLUMN public.incrementaldiff.branch_merge_proposal IS 'The merge proposal the diff is for.';
-
-
-COMMENT ON COLUMN public.incrementaldiff.old_revision IS 'The revision the diff is from.';
+COMMENT ON TABLE public.launchpaddatabaserevision IS 'This table contains a list of the database patches that have been successfully applied to this database.';
 
 
-COMMENT ON COLUMN public.incrementaldiff.new_revision IS 'The revision the diff is to.';
+COMMENT ON COLUMN public.launchpaddatabaserevision.major IS 'Major number. This is the version of the baseline schema the patch was made agains.';
 
 
-CREATE SEQUENCE public.incrementaldiff_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.launchpaddatabaserevision.minor IS 'Minor number. Patches made during development each increment the minor number.';
 
 
-ALTER SEQUENCE public.incrementaldiff_id_seq OWNED BY public.incrementaldiff.id;
+COMMENT ON COLUMN public.launchpaddatabaserevision.patch IS 'The patch number will hopefully always be ''0'', as it exists to support emergency patches made to the production server. eg. If production is running ''4.0.0'' and needs to have a patch applied ASAP, we would create a ''4.0.1'' patch and roll it out. We then may need to refactor all the existing ''4.x.0'' patches.';
 
 
-CREATE TABLE public.ircid (
+CREATE TABLE public.launchpaddatabaseupdatelog (
     id integer NOT NULL,
-    person integer NOT NULL,
-    network text NOT NULL,
-    nickname text NOT NULL
+    start_time timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    end_time timestamp without time zone,
+    branch_nick text,
+    revno integer,
+    revid text
 );
 
 
-CREATE SEQUENCE public.ircid_id_seq
+COMMENT ON TABLE public.launchpaddatabaseupdatelog IS 'Record of Launchpad database schema updates. When and what update.py was run.';
+
+
+CREATE SEQUENCE public.launchpaddatabaseupdatelog_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9172,17 +10367,21 @@ CREATE SEQUENCE public.ircid_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.ircid_id_seq OWNED BY public.ircid.id;
+ALTER SEQUENCE public.launchpaddatabaseupdatelog_id_seq OWNED BY public.launchpaddatabaseupdatelog.id;
 
 
-CREATE TABLE public.jabberid (
+CREATE TABLE public.launchpadstatistic (
     id integer NOT NULL,
-    person integer NOT NULL,
-    jabberid text NOT NULL
+    name text NOT NULL,
+    value integer NOT NULL,
+    dateupdated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL
 );
 
 
-CREATE SEQUENCE public.jabberid_id_seq
+COMMENT ON TABLE public.launchpadstatistic IS 'A store of system-wide statistics or other integer values, keyed by names. The names are unique and the values can be any integer. Each field has a place to store the timestamp when it was last updated, so it is possible to know how far out of date any given statistic is.';
+
+
+CREATE SEQUENCE public.launchpadstatistic_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9190,76 +10389,47 @@ CREATE SEQUENCE public.jabberid_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.jabberid_id_seq OWNED BY public.jabberid.id;
+ALTER SEQUENCE public.launchpadstatistic_id_seq OWNED BY public.launchpadstatistic.id;
 
 
-CREATE TABLE public.job (
+CREATE TABLE public.libraryfilealias (
     id integer NOT NULL,
-    requester integer,
-    reason text,
-    status integer NOT NULL,
-    progress integer,
-    last_report_seen timestamp without time zone,
-    next_report_due timestamp without time zone,
-    attempt_count integer DEFAULT 0 NOT NULL,
-    max_retries integer DEFAULT 0 NOT NULL,
-    log text,
-    scheduled_start timestamp without time zone,
-    lease_expires timestamp without time zone,
+    filename text NOT NULL,
+    mimetype text NOT NULL,
+    expires timestamp without time zone,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_started timestamp without time zone,
-    date_finished timestamp without time zone,
-    json_data text,
-    job_type integer
+    restricted boolean DEFAULT false NOT NULL,
+    hits integer DEFAULT 0 NOT NULL,
+    content bigint,
+    CONSTRAINT valid_filename CHECK ((filename !~~ '%/%'::text))
 );
 
 
-COMMENT ON TABLE public.job IS 'Common info about a job.';
-
-
-COMMENT ON COLUMN public.job.requester IS 'Ther person who requested this job (if applicable).';
-
-
-COMMENT ON COLUMN public.job.reason IS 'The reason that this job was created (if applicable)';
-
-
-COMMENT ON COLUMN public.job.status IS 'An enum (JobStatus) indicating the job status, one of: new, in-progress, complete, failed, cancelling, cancelled.';
-
-
-COMMENT ON COLUMN public.job.progress IS 'The percentage complete.  Can be NULL for some jobs that do not report progress.';
-
-
-COMMENT ON COLUMN public.job.last_report_seen IS 'The last time the progress was reported.';
-
-
-COMMENT ON COLUMN public.job.next_report_due IS 'The next time a progress report is expected.';
-
-
-COMMENT ON COLUMN public.job.attempt_count IS 'The number of times this job has been attempted.';
+COMMENT ON TABLE public.libraryfilealias IS 'LibraryFileAlias: A librarian file''s alias. The librarian stores, along with the file contents, a record stating the file name and mimetype. This table represents it.';
 
 
-COMMENT ON COLUMN public.job.max_retries IS 'The maximum number of retries valid for this job.';
+COMMENT ON COLUMN public.libraryfilealias.filename IS 'The name of the file. E.g. "foo_1.0-1_i386.deb"';
 
 
-COMMENT ON COLUMN public.job.log IS 'If provided, this is the tail of the log file being generated by the running job.';
+COMMENT ON COLUMN public.libraryfilealias.mimetype IS 'The mime type of the file. E.g. "application/x-debian-package"';
 
 
-COMMENT ON COLUMN public.job.scheduled_start IS 'The time when the job should start';
+COMMENT ON COLUMN public.libraryfilealias.expires IS 'The expiry date of this file. If NULL, this item may be removed as soon as it is no longer referenced. If set, the item will not be removed until this date. Once the date is passed, the file may be removed from disk even if this item is still being referenced (in which case content.deleted will be true)';
 
 
-COMMENT ON COLUMN public.job.lease_expires IS 'The time when the lease expires.';
+COMMENT ON COLUMN public.libraryfilealias.date_created IS 'The timestamp when this alias was created.';
 
 
-COMMENT ON COLUMN public.job.date_created IS 'The time when the job was created.';
+COMMENT ON COLUMN public.libraryfilealias.restricted IS 'Is this file available only from the restricted librarian?';
 
 
-COMMENT ON COLUMN public.job.date_started IS 'If the job has started, the time when the job started.';
+COMMENT ON COLUMN public.libraryfilealias.hits IS 'The number of times this file has been downloaded.';
 
 
-COMMENT ON COLUMN public.job.date_finished IS 'If the job has finished, the time when the job finished.';
+COMMENT ON COLUMN public.libraryfilealias.content IS 'The libraryfilecontent which is the data in this file.';
 
 
-CREATE SEQUENCE public.job_id_seq
+CREATE SEQUENCE public.libraryfilealias_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9267,43 +10437,39 @@ CREATE SEQUENCE public.job_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.job_id_seq OWNED BY public.job.id;
+ALTER SEQUENCE public.libraryfilealias_id_seq OWNED BY public.libraryfilealias.id;
 
 
-CREATE TABLE public.karma (
-    id integer NOT NULL,
+CREATE TABLE public.libraryfilecontent (
     datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    person integer NOT NULL,
-    action integer NOT NULL,
-    product integer,
-    distribution integer,
-    sourcepackagename integer
+    filesize bigint NOT NULL,
+    sha1 character(40) NOT NULL,
+    md5 character(32) NOT NULL,
+    sha256 character(64) NOT NULL,
+    id bigint NOT NULL
 )
 WITH (fillfactor='100');
 
 
-COMMENT ON TABLE public.karma IS 'Used to quantify all the ''operations'' a user performs inside the system, which maybe reporting and fixing bugs, uploading packages, end-user support, wiki editting, etc.';
-
-
-COMMENT ON COLUMN public.karma.datecreated IS 'A timestamp for the assignment of this Karma.';
+COMMENT ON TABLE public.libraryfilecontent IS 'LibraryFileContent: A librarian file''s contents. The librarian stores files in a safe and transactional way. This table represents the contents of those files within the database.';
 
 
-COMMENT ON COLUMN public.karma.person IS 'The Person for wich this Karma was assigned.';
+COMMENT ON COLUMN public.libraryfilecontent.datecreated IS 'The date on which this librarian file was created';
 
 
-COMMENT ON COLUMN public.karma.action IS 'A foreign key to the KarmaAction table.';
+COMMENT ON COLUMN public.libraryfilecontent.filesize IS 'The size of the file';
 
 
-COMMENT ON COLUMN public.karma.product IS 'The Project to which this Product belongs.  An entry on this table with a non-NULL Project and a NULL Product represents the total karma of the person across all products of that project..';
+COMMENT ON COLUMN public.libraryfilecontent.sha1 IS 'The SHA1 sum of the file''s contents';
 
 
-COMMENT ON COLUMN public.karma.distribution IS 'The Distribution on which a person performed an action that resulted on this karma.';
+COMMENT ON COLUMN public.libraryfilecontent.md5 IS 'The MD5 sum of the file''s contents';
 
 
-COMMENT ON COLUMN public.karma.sourcepackagename IS 'The SourcePackageName on which a person performed an action that resulted on this karma.';
+COMMENT ON COLUMN public.libraryfilecontent.sha256 IS 'The SHA256 sum of the file''s contents';
 
 
-CREATE SEQUENCE public.karma_id_seq
+CREATE SEQUENCE public.libraryfilecontent_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9311,32 +10477,34 @@ CREATE SEQUENCE public.karma_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.karma_id_seq OWNED BY public.karma.id;
+ALTER SEQUENCE public.libraryfilecontent_id_seq OWNED BY public.libraryfilecontent.id;
 
 
-CREATE TABLE public.karmaaction (
+CREATE TABLE public.libraryfiledownloadcount (
     id integer NOT NULL,
-    category integer,
-    points integer,
-    name text NOT NULL,
-    title text NOT NULL,
-    summary text NOT NULL
+    libraryfilealias integer NOT NULL,
+    day date NOT NULL,
+    count integer NOT NULL,
+    country integer
 );
 
 
-COMMENT ON TABLE public.karmaaction IS 'Stores all the actions that would give karma to the user which performed it.';
+COMMENT ON TABLE public.libraryfiledownloadcount IS 'The number of daily downloads for a given LibraryFileAlias.';
 
 
-COMMENT ON COLUMN public.karmaaction.category IS 'A dbschema value used to group actions together.';
+COMMENT ON COLUMN public.libraryfiledownloadcount.libraryfilealias IS 'The LibraryFileAlias.';
 
 
-COMMENT ON COLUMN public.karmaaction.points IS 'The number of points this action is worth of.';
+COMMENT ON COLUMN public.libraryfiledownloadcount.day IS 'The day of the downloads.';
 
 
-COMMENT ON COLUMN public.karmaaction.name IS 'The unique name of this action.';
+COMMENT ON COLUMN public.libraryfiledownloadcount.count IS 'The number of downloads.';
 
 
-CREATE SEQUENCE public.karmaaction_id_seq
+COMMENT ON COLUMN public.libraryfiledownloadcount.country IS 'The country from where the download requests came from.';
+
+
+CREATE SEQUENCE public.libraryfiledownloadcount_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9344,62 +10512,53 @@ CREATE SEQUENCE public.karmaaction_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.karmaaction_id_seq OWNED BY public.karmaaction.id;
+ALTER SEQUENCE public.libraryfiledownloadcount_id_seq OWNED BY public.libraryfiledownloadcount.id;
 
 
-CREATE TABLE public.karmacache (
+CREATE TABLE public.livefs (
     id integer NOT NULL,
-    person integer NOT NULL,
-    category integer,
-    karmavalue integer NOT NULL,
-    product integer,
-    distribution integer,
-    sourcepackagename integer,
-    project integer,
-    CONSTRAINT just_distribution CHECK (((distribution IS NULL) OR ((product IS NULL) AND (project IS NULL)))),
-    CONSTRAINT just_product CHECK (((product IS NULL) OR ((project IS NULL) AND (distribution IS NULL)))),
-    CONSTRAINT just_project CHECK (((project IS NULL) OR ((product IS NULL) AND (distribution IS NULL)))),
-    CONSTRAINT sourcepackagename_requires_distribution CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    registrant integer NOT NULL,
+    owner integer NOT NULL,
+    distro_series integer NOT NULL,
+    name text NOT NULL,
+    json_data text,
+    require_virtualized boolean DEFAULT true NOT NULL,
+    relative_build_score integer DEFAULT 0 NOT NULL,
+    keep_binary_files_interval interval DEFAULT '1 day'::interval,
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
 );
 
 
-COMMENT ON TABLE public.karmacache IS 'Stores a cached value of a person''s karma points, grouped by the action category and the context where that action was performed.';
+COMMENT ON TABLE public.livefs IS 'A class of buildable live filesystem images.  Rows in this table only partially define how to build an image; the rest of the information comes from LiveFSBuild.';
 
 
-COMMENT ON COLUMN public.karmacache.person IS 'The person which performed the actions of this category, and thus got the karma.';
+COMMENT ON COLUMN public.livefs.registrant IS 'The user who registered the live filesystem image.';
 
 
-COMMENT ON COLUMN public.karmacache.category IS 'The category of the actions.';
+COMMENT ON COLUMN public.livefs.owner IS 'The owner of the live filesystem image.';
 
 
-COMMENT ON COLUMN public.karmacache.karmavalue IS 'The karma points of all actions of this category performed by this person on this context (product/distribution).';
+COMMENT ON COLUMN public.livefs.distro_series IS 'The DistroSeries for which the image should be built.';
 
 
-CREATE SEQUENCE public.karmacache_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.livefs.name IS 'The name of the live filesystem image, unique per DistroSeries.';
 
 
-ALTER SEQUENCE public.karmacache_id_seq OWNED BY public.karmacache.id;
+COMMENT ON COLUMN public.livefs.json_data IS 'A JSON struct containing data for the image build.';
 
 
-CREATE TABLE public.karmacategory (
-    id integer NOT NULL,
-    name text NOT NULL,
-    title text NOT NULL,
-    summary text NOT NULL
-);
+COMMENT ON COLUMN public.livefs.require_virtualized IS 'If True, this live filesystem image must be built only on a virtual machine.';
 
 
-COMMENT ON TABLE public.karmacategory IS 'A category of karma. This allows us to
-present an overall picture of the different areas where a user has been
-active.';
+COMMENT ON COLUMN public.livefs.relative_build_score IS 'A delta to the build score that is applied to all builds of this live filesystem.';
 
 
-CREATE SEQUENCE public.karmacategory_id_seq
+COMMENT ON COLUMN public.livefs.keep_binary_files_interval IS 'Keep binary files attached to builds of this live filesystem for at least this long.';
+
+
+CREATE SEQUENCE public.livefs_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9407,69 +10566,99 @@ CREATE SEQUENCE public.karmacategory_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.karmacategory_id_seq OWNED BY public.karmacategory.id;
+ALTER SEQUENCE public.livefs_id_seq OWNED BY public.livefs.id;
 
 
-CREATE TABLE public.karmatotalcache (
+CREATE TABLE public.livefsbuild (
     id integer NOT NULL,
-    person integer NOT NULL,
-    karma_total integer NOT NULL
+    requester integer NOT NULL,
+    livefs integer NOT NULL,
+    archive integer NOT NULL,
+    distro_arch_series integer NOT NULL,
+    pocket integer NOT NULL,
+    unique_key text,
+    json_data_override text,
+    processor integer NOT NULL,
+    virtualized boolean NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_started timestamp without time zone,
+    date_finished timestamp without time zone,
+    date_first_dispatched timestamp without time zone,
+    builder integer,
+    status integer NOT NULL,
+    log integer,
+    upload_log integer,
+    dependencies text,
+    failure_count integer DEFAULT 0 NOT NULL,
+    build_farm_job integer NOT NULL,
+    version text
 );
 
 
-CREATE SEQUENCE public.karmatotalcache_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON TABLE public.livefsbuild IS 'A build record for a live filesystem image.';
+
+
+COMMENT ON COLUMN public.livefsbuild.requester IS 'The person who requested this live filesystem image build.';
+
+
+COMMENT ON COLUMN public.livefsbuild.livefs IS 'Live filesystem image to build.';
+
+
+COMMENT ON COLUMN public.livefsbuild.archive IS 'The archive that the live filesystem image should build from.';
+
+
+COMMENT ON COLUMN public.livefsbuild.distro_arch_series IS 'The distroarchseries that the live filesystem image should build from.';
+
+
+COMMENT ON COLUMN public.livefsbuild.pocket IS 'The pocket that the live filesystem image should build from.';
+
+
+COMMENT ON COLUMN public.livefsbuild.unique_key IS 'A unique key distinguishing this build from others for the same livefs/archive/distroarchseries/pocket, or NULL.';
+
+
+COMMENT ON COLUMN public.livefsbuild.json_data_override IS 'A JSON struct containing data for the image build, each key of which overrides the same key from livefs.json_data.';
+
+
+COMMENT ON COLUMN public.livefsbuild.virtualized IS 'The virtualization setting required by this build farm job.';
+
+
+COMMENT ON COLUMN public.livefsbuild.date_created IS 'When the build farm job record was created.';
 
 
-ALTER SEQUENCE public.karmatotalcache_id_seq OWNED BY public.karmatotalcache.id;
+COMMENT ON COLUMN public.livefsbuild.date_started IS 'When the build farm job started being processed.';
 
 
-CREATE TABLE public.language (
-    id integer NOT NULL,
-    code text NOT NULL,
-    englishname text NOT NULL,
-    nativename text,
-    pluralforms integer,
-    pluralexpression text,
-    visible boolean NOT NULL,
-    direction integer DEFAULT 0 NOT NULL,
-    uuid text,
-    CONSTRAINT valid_language CHECK (((pluralforms IS NULL) = (pluralexpression IS NULL)))
-);
+COMMENT ON COLUMN public.livefsbuild.date_finished IS 'When the build farm job finished being processed.';
 
 
-COMMENT ON TABLE public.language IS 'A human language.';
+COMMENT ON COLUMN public.livefsbuild.date_first_dispatched IS 'The instant the build was dispatched the first time.  This value will not get overridden if the build is retried.';
 
 
-COMMENT ON COLUMN public.language.code IS 'The ISO 639 code for this language';
+COMMENT ON COLUMN public.livefsbuild.builder IS 'The builder which processed this build farm job.';
 
 
-COMMENT ON COLUMN public.language.englishname IS 'The english name for this language';
+COMMENT ON COLUMN public.livefsbuild.status IS 'The current build status.';
 
 
-COMMENT ON COLUMN public.language.nativename IS 'The name of this language in the language itself';
+COMMENT ON COLUMN public.livefsbuild.log IS 'The log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.language.pluralforms IS 'The number of plural forms this language has';
+COMMENT ON COLUMN public.livefsbuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.language.pluralexpression IS 'The plural expression for this language, as used by gettext';
+COMMENT ON COLUMN public.livefsbuild.dependencies IS 'A Debian-like dependency line specifying the current missing dependencies for this build.';
 
 
-COMMENT ON COLUMN public.language.visible IS 'Whether this language should usually be visible or not';
+COMMENT ON COLUMN public.livefsbuild.failure_count IS 'The number of consecutive failures on this job.  If excessive, the job may be terminated.';
 
 
-COMMENT ON COLUMN public.language.direction IS 'The direction that text is written in this language';
+COMMENT ON COLUMN public.livefsbuild.build_farm_job IS 'The build farm job with the base information.';
 
 
-COMMENT ON COLUMN public.language.uuid IS 'Mozilla language pack unique ID';
+COMMENT ON COLUMN public.livefsbuild.version IS 'A version string for this build.';
 
 
-CREATE SEQUENCE public.language_id_seq
+CREATE SEQUENCE public.livefsbuild_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9477,43 +10666,26 @@ CREATE SEQUENCE public.language_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.language_id_seq OWNED BY public.language.id;
+ALTER SEQUENCE public.livefsbuild_id_seq OWNED BY public.livefsbuild.id;
 
 
-CREATE TABLE public.languagepack (
+CREATE TABLE public.livefsfile (
     id integer NOT NULL,
-    file integer NOT NULL,
-    date_exported timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_used timestamp without time zone DEFAULT timezone('UTC'::text, now()),
-    distroseries integer NOT NULL,
-    type integer DEFAULT 1 NOT NULL,
-    updates integer,
-    CONSTRAINT valid_updates CHECK ((((type = 2) AND (updates IS NOT NULL)) OR ((type = 1) AND (updates IS NULL))))
+    livefsbuild integer NOT NULL,
+    libraryfile integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.languagepack IS 'Store exported language packs for DistroSeries.';
-
-
-COMMENT ON COLUMN public.languagepack.file IS 'Librarian file where the language pack is stored.';
-
-
-COMMENT ON COLUMN public.languagepack.date_exported IS 'When was exported the language pack.';
-
-
-COMMENT ON COLUMN public.languagepack.date_last_used IS 'When did we stop using the language pack. It''s used to decide whether we can remove it completely from the system. When it''s being used, its value is NULL';
-
-
-COMMENT ON COLUMN public.languagepack.distroseries IS 'The distribution series from where this language pack was exported.';
+COMMENT ON TABLE public.livefsfile IS 'A link between a live filesystem build and a file in the librarian that it produces.';
 
 
-COMMENT ON COLUMN public.languagepack.type IS 'Type of language pack. There are two types available, 1: Full export, 2: Update export based on language_pack_that_updates export.';
+COMMENT ON COLUMN public.livefsfile.livefsbuild IS 'The live filesystem build producing this file.';
 
 
-COMMENT ON COLUMN public.languagepack.updates IS 'The LanguagePack that this one updates.';
+COMMENT ON COLUMN public.livefsfile.libraryfile IS 'A file in the librarian.';
 
 
-CREATE SEQUENCE public.languagepack_id_seq
+CREATE SEQUENCE public.livefsfile_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9521,73 +10693,52 @@ CREATE SEQUENCE public.languagepack_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.languagepack_id_seq OWNED BY public.languagepack.id;
-
-
-CREATE VIEW public.latestdatabasediskutilization AS
- SELECT databasediskutilization.date_created,
-    databasediskutilization.namespace,
-    databasediskutilization.name,
-    databasediskutilization.sub_namespace,
-    databasediskutilization.sub_name,
-    databasediskutilization.kind,
-    databasediskutilization.sort,
-    databasediskutilization.table_len,
-    databasediskutilization.tuple_count,
-    databasediskutilization.tuple_len,
-    databasediskutilization.tuple_percent,
-    databasediskutilization.dead_tuple_count,
-    databasediskutilization.dead_tuple_len,
-    databasediskutilization.dead_tuple_percent,
-    databasediskutilization.free_space,
-    databasediskutilization.free_percent
-   FROM public.databasediskutilization
-  WHERE (databasediskutilization.date_created = ( SELECT max(databasediskutilization_1.date_created) AS max
-           FROM public.databasediskutilization databasediskutilization_1));
+ALTER SEQUENCE public.livefsfile_id_seq OWNED BY public.livefsfile.id;
 
 
-CREATE TABLE public.latestpersonsourcepackagereleasecache (
+CREATE TABLE public.logintoken (
     id integer NOT NULL,
-    publication integer NOT NULL,
-    date_uploaded timestamp without time zone NOT NULL,
-    creator integer,
-    maintainer integer,
-    archive_purpose integer NOT NULL,
-    upload_archive integer NOT NULL,
-    upload_distroseries integer NOT NULL,
-    sourcepackagename integer NOT NULL,
-    sourcepackagerelease integer NOT NULL
+    requester integer,
+    requesteremail text,
+    email text NOT NULL,
+    created timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
+    tokentype integer NOT NULL,
+    token text,
+    fingerprint text,
+    redirection_url text,
+    date_consumed timestamp without time zone,
+    CONSTRAINT valid_fingerprint CHECK (((fingerprint IS NULL) OR public.valid_fingerprint(fingerprint)))
 );
 
 
-COMMENT ON TABLE public.latestpersonsourcepackagereleasecache IS 'LatestPersonSourcePackageReleaseCache: The most recent published source package releases for a given (distroseries, archive, sourcepackage).';
+COMMENT ON TABLE public.logintoken IS 'LoginToken stores one time tokens used by Launchpad for validating email addresses and other tasks that require verifying an email address is valid such as password recovery and account merging. This table will be cleaned occasionally to remove expired tokens. Expiry time is not yet defined.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.date_uploaded IS 'The date/time on which the source was actually published into the archive.';
+COMMENT ON COLUMN public.logintoken.requester IS 'The Person that made this request. This will be null for password recovery requests.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.creator IS 'The creator of the source package release.';
+COMMENT ON COLUMN public.logintoken.requesteremail IS 'The email address that was used to login when making this request. This provides an audit trail to help the end user confirm that this is a valid request. It is not a link to the EmailAddress table as this may be changed after the request is made. This field will be null for password recovery requests.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.maintainer IS 'The maintainer of the source package in the DSC.';
+COMMENT ON COLUMN public.logintoken.email IS 'The email address that this request was sent to.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.archive_purpose IS 'The purpose of the archive, e.g. COMMERCIAL.  See the ArchivePurpose DBSchema item.';
+COMMENT ON COLUMN public.logintoken.created IS 'The timestamp that this request was made.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.upload_archive IS 'The target archive for the release.';
+COMMENT ON COLUMN public.logintoken.tokentype IS 'The type of request, as per dbschema.TokenType.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.upload_distroseries IS 'The distroseries into which the sourcepackagerelease was published.';
+COMMENT ON COLUMN public.logintoken.token IS 'The token (not the URL) emailed used to uniquely identify this request. This token will be used to generate a URL that when clicked on will continue a workflow.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.sourcepackagename IS 'The SourcePackageName of the release.';
+COMMENT ON COLUMN public.logintoken.fingerprint IS 'The GPG key fingerprint to be validated on this transaction, it means that a new register will be created relating this given key with the requester in question. The requesteremail still passing for the same usual checks.';
 
 
-COMMENT ON COLUMN public.latestpersonsourcepackagereleasecache.sourcepackagerelease IS 'The sourcepackagerelease which was published.';
+COMMENT ON COLUMN public.logintoken.date_consumed IS 'The date and time when this token was consumed. It''s NULL if it hasn''t been consumed yet.';
 
 
-CREATE SEQUENCE public.latestpersonsourcepackagereleasecache_id_seq
+CREATE SEQUENCE public.logintoken_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9595,69 +10746,125 @@ CREATE SEQUENCE public.latestpersonsourcepackagereleasecache_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.latestpersonsourcepackagereleasecache_id_seq OWNED BY public.latestpersonsourcepackagereleasecache.id;
+ALTER SEQUENCE public.logintoken_id_seq OWNED BY public.logintoken.id;
 
 
-CREATE TABLE public.launchpaddatabaserevision (
-    major integer NOT NULL,
-    minor integer NOT NULL,
-    patch integer NOT NULL,
-    start_time timestamp without time zone DEFAULT timezone('UTC'::text, transaction_timestamp()),
-    end_time timestamp without time zone DEFAULT timezone('UTC'::text, clock_timestamp()),
-    branch_nick text,
-    revno integer,
-    revid text
+CREATE TABLE public.lp_account (
+    id integer NOT NULL,
+    openid_identifier text NOT NULL
 );
 
 
-COMMENT ON TABLE public.launchpaddatabaserevision IS 'This table contains a list of the database patches that have been successfully applied to this database.';
+CREATE TABLE public.lp_openididentifier (
+    identifier text NOT NULL,
+    account integer NOT NULL,
+    date_created timestamp without time zone NOT NULL
+);
 
 
-COMMENT ON COLUMN public.launchpaddatabaserevision.major IS 'Major number. This is the version of the baseline schema the patch was made agains.';
+CREATE TABLE public.lp_person (
+    id integer NOT NULL,
+    displayname text,
+    teamowner integer,
+    teamdescription text,
+    name text,
+    language integer,
+    fti public.ts2_tsvector,
+    defaultmembershipperiod integer,
+    defaultrenewalperiod integer,
+    subscriptionpolicy integer,
+    merged integer,
+    datecreated timestamp without time zone,
+    addressline1 text,
+    addressline2 text,
+    organization text,
+    city text,
+    province text,
+    country integer,
+    postcode text,
+    phone text,
+    homepage_content text,
+    icon integer,
+    mugshot integer,
+    hide_email_addresses boolean,
+    creation_rationale integer,
+    creation_comment text,
+    registrant integer,
+    logo integer,
+    renewal_policy integer,
+    personal_standing integer,
+    personal_standing_reason text,
+    mail_resumption_date date,
+    mailing_list_auto_subscribe_policy integer,
+    mailing_list_receive_duplicates boolean,
+    visibility integer,
+    verbose_bugnotifications boolean,
+    account integer
+);
 
 
-COMMENT ON COLUMN public.launchpaddatabaserevision.minor IS 'Minor number. Patches made during development each increment the minor number.';
+CREATE TABLE public.lp_personlocation (
+    id integer NOT NULL,
+    date_created timestamp without time zone,
+    person integer,
+    latitude double precision,
+    longitude double precision,
+    time_zone text,
+    last_modified_by integer,
+    date_last_modified timestamp without time zone,
+    visible boolean,
+    locked boolean
+);
 
 
-COMMENT ON COLUMN public.launchpaddatabaserevision.patch IS 'The patch number will hopefully always be ''0'', as it exists to support emergency patches made to the production server. eg. If production is running ''4.0.0'' and needs to have a patch applied ASAP, we would create a ''4.0.1'' patch and roll it out. We then may need to refactor all the existing ''4.x.0'' patches.';
+CREATE TABLE public.lp_teamparticipation (
+    id integer NOT NULL,
+    team integer,
+    person integer
+);
 
 
-CREATE TABLE public.launchpaddatabaseupdatelog (
+CREATE TABLE public.mailinglist (
     id integer NOT NULL,
-    start_time timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    end_time timestamp without time zone,
-    branch_nick text,
-    revno integer,
-    revid text
+    team integer NOT NULL,
+    registrant integer NOT NULL,
+    date_registered timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    reviewer integer,
+    date_reviewed timestamp without time zone DEFAULT timezone('UTC'::text, now()),
+    date_activated timestamp without time zone DEFAULT timezone('UTC'::text, now()),
+    status integer DEFAULT 1 NOT NULL,
+    welcome_message text
 );
 
 
-COMMENT ON TABLE public.launchpaddatabaseupdatelog IS 'Record of Launchpad database schema updates. When and what update.py was run.';
+COMMENT ON TABLE public.mailinglist IS 'The mailing list for a team.  Teams may have zero or one mailing list, and a mailing list is associated with exactly one team.  This table manages the state changes that a team mailing list can go through, and it contains information that will be used to instruct Mailman how to create, delete, and modify mailing lists (via XMLRPC).';
 
 
-CREATE SEQUENCE public.launchpaddatabaseupdatelog_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.mailinglist.team IS 'The team this mailing list is associated with.';
 
 
-ALTER SEQUENCE public.launchpaddatabaseupdatelog_id_seq OWNED BY public.launchpaddatabaseupdatelog.id;
+COMMENT ON COLUMN public.mailinglist.registrant IS 'The id of the Person who requested this list be created.';
 
 
-CREATE TABLE public.launchpadstatistic (
-    id integer NOT NULL,
-    name text NOT NULL,
-    value integer NOT NULL,
-    dateupdated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL
-);
+COMMENT ON COLUMN public.mailinglist.date_registered IS 'Date the list was requested to be created';
+
+
+COMMENT ON COLUMN public.mailinglist.reviewer IS 'The id of the Person who reviewed the creation request, or NULL if not yet reviewed.';
+
+
+COMMENT ON COLUMN public.mailinglist.date_reviewed IS 'The date the request was reviewed, or NULL if not yet reviewed.';
+
+
+COMMENT ON COLUMN public.mailinglist.date_activated IS 'The date the list was (last) activated.  If the list is not yet active, this field will be NULL.';
+
+
+COMMENT ON COLUMN public.mailinglist.status IS 'The current status of the mailing list, as a dbschema.MailingListStatus value.';
 
 
-COMMENT ON TABLE public.launchpadstatistic IS 'A store of system-wide statistics or other integer values, keyed by names. The names are unique and the values can be any integer. Each field has a place to store the timestamp when it was last updated, so it is possible to know how far out of date any given statistic is.';
+COMMENT ON COLUMN public.mailinglist.welcome_message IS 'Text sent to new members when they are subscribed to the team list.  If NULL, no welcome message is sent.';
 
 
-CREATE SEQUENCE public.launchpadstatistic_id_seq
+CREATE SEQUENCE public.mailinglist_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9665,47 +10872,34 @@ CREATE SEQUENCE public.launchpadstatistic_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.launchpadstatistic_id_seq OWNED BY public.launchpadstatistic.id;
+ALTER SEQUENCE public.mailinglist_id_seq OWNED BY public.mailinglist.id;
 
 
-CREATE TABLE public.libraryfilealias (
+CREATE TABLE public.mailinglistsubscription (
     id integer NOT NULL,
-    filename text NOT NULL,
-    mimetype text NOT NULL,
-    expires timestamp without time zone,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    restricted boolean DEFAULT false NOT NULL,
-    hits integer DEFAULT 0 NOT NULL,
-    content bigint,
-    CONSTRAINT valid_filename CHECK ((filename !~~ '%/%'::text))
+    person integer NOT NULL,
+    mailing_list integer NOT NULL,
+    date_joined timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    email_address integer
 );
 
 
-COMMENT ON TABLE public.libraryfilealias IS 'LibraryFileAlias: A librarian file''s alias. The librarian stores, along with the file contents, a record stating the file name and mimetype. This table represents it.';
-
-
-COMMENT ON COLUMN public.libraryfilealias.filename IS 'The name of the file. E.g. "foo_1.0-1_i386.deb"';
-
-
-COMMENT ON COLUMN public.libraryfilealias.mimetype IS 'The mime type of the file. E.g. "application/x-debian-package"';
-
-
-COMMENT ON COLUMN public.libraryfilealias.expires IS 'The expiry date of this file. If NULL, this item may be removed as soon as it is no longer referenced. If set, the item will not be removed until this date. Once the date is passed, the file may be removed from disk even if this item is still being referenced (in which case content.deleted will be true)';
+COMMENT ON TABLE public.mailinglistsubscription IS 'Track the subscriptions of a person to team mailing lists.';
 
 
-COMMENT ON COLUMN public.libraryfilealias.date_created IS 'The timestamp when this alias was created.';
+COMMENT ON COLUMN public.mailinglistsubscription.person IS 'The person who is subscribed to the mailing list.';
 
 
-COMMENT ON COLUMN public.libraryfilealias.restricted IS 'Is this file available only from the restricted librarian?';
+COMMENT ON COLUMN public.mailinglistsubscription.mailing_list IS 'The mailing list this person is subscribed to.';
 
 
-COMMENT ON COLUMN public.libraryfilealias.hits IS 'The number of times this file has been downloaded.';
+COMMENT ON COLUMN public.mailinglistsubscription.date_joined IS 'The date this person subscribed to the mailing list.';
 
 
-COMMENT ON COLUMN public.libraryfilealias.content IS 'The libraryfilecontent which is the data in this file.';
+COMMENT ON COLUMN public.mailinglistsubscription.email_address IS 'Which of the person''s email addresses are subscribed to the mailing list.  This may be NULL to indicate that it''s the person''s preferred address.';
 
 
-CREATE SEQUENCE public.libraryfilealias_id_seq
+CREATE SEQUENCE public.mailinglistsubscription_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9713,39 +10907,45 @@ CREATE SEQUENCE public.libraryfilealias_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.libraryfilealias_id_seq OWNED BY public.libraryfilealias.id;
+ALTER SEQUENCE public.mailinglistsubscription_id_seq OWNED BY public.mailinglistsubscription.id;
 
 
-CREATE TABLE public.libraryfilecontent (
+CREATE TABLE public.message (
+    id integer NOT NULL,
     datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    filesize bigint NOT NULL,
-    sha1 character(40) NOT NULL,
-    md5 character(32) NOT NULL,
-    sha256 character(64) NOT NULL,
-    id bigint NOT NULL
+    subject text,
+    owner integer,
+    parent integer,
+    distribution integer,
+    rfc822msgid text NOT NULL,
+    fti public.ts2_tsvector,
+    raw integer,
+    visible boolean DEFAULT true NOT NULL,
+    date_deleted timestamp without time zone,
+    date_last_edited timestamp without time zone
 )
 WITH (fillfactor='100');
 
 
-COMMENT ON TABLE public.libraryfilecontent IS 'LibraryFileContent: A librarian file''s contents. The librarian stores files in a safe and transactional way. This table represents the contents of those files within the database.';
+COMMENT ON TABLE public.message IS 'This table stores a single RFC822-style message. Messages can be threaded (using the parent field). These messages can then be referenced from elsewhere in the system, such as the BugMessage table, integrating messageboard facilities with the rest of The Launchpad.';
 
 
-COMMENT ON COLUMN public.libraryfilecontent.datecreated IS 'The date on which this librarian file was created';
+COMMENT ON COLUMN public.message.subject IS 'The title text of the message, or the subject if it was an email.';
 
 
-COMMENT ON COLUMN public.libraryfilecontent.filesize IS 'The size of the file';
+COMMENT ON COLUMN public.message.parent IS 'A "parent message". This allows for some level of threading in Messages.';
 
 
-COMMENT ON COLUMN public.libraryfilecontent.sha1 IS 'The SHA1 sum of the file''s contents';
+COMMENT ON COLUMN public.message.distribution IS 'The distribution in which this message originated, if we know it.';
 
 
-COMMENT ON COLUMN public.libraryfilecontent.md5 IS 'The MD5 sum of the file''s contents';
+COMMENT ON COLUMN public.message.raw IS 'The original unadulterated message if it arrived via email. This is required to provide access to the original, undecoded message.';
 
 
-COMMENT ON COLUMN public.libraryfilecontent.sha256 IS 'The SHA256 sum of the file''s contents';
+COMMENT ON COLUMN public.message.visible IS 'If false, the message is hidden and should not be shown in any UI.';
 
 
-CREATE SEQUENCE public.libraryfilecontent_id_seq
+CREATE SEQUENCE public.message_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9753,34 +10953,54 @@ CREATE SEQUENCE public.libraryfilecontent_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.libraryfilecontent_id_seq OWNED BY public.libraryfilecontent.id;
+ALTER SEQUENCE public.message_id_seq OWNED BY public.message.id;
 
 
-CREATE TABLE public.libraryfiledownloadcount (
+CREATE TABLE public.messageapproval (
     id integer NOT NULL,
-    libraryfilealias integer NOT NULL,
-    day date NOT NULL,
-    count integer NOT NULL,
-    country integer
+    posted_by integer NOT NULL,
+    mailing_list integer NOT NULL,
+    posted_message integer NOT NULL,
+    posted_date timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    status integer DEFAULT 0 NOT NULL,
+    disposed_by integer,
+    disposal_date timestamp without time zone DEFAULT timezone('UTC'::text, now()),
+    reason text,
+    message integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.libraryfiledownloadcount IS 'The number of daily downloads for a given LibraryFileAlias.';
+COMMENT ON TABLE public.messageapproval IS 'Track mailing list postings awaiting approval from the team owner.';
 
 
-COMMENT ON COLUMN public.libraryfiledownloadcount.libraryfilealias IS 'The LibraryFileAlias.';
+COMMENT ON COLUMN public.messageapproval.posted_by IS 'The person who posted the message.';
 
 
-COMMENT ON COLUMN public.libraryfiledownloadcount.day IS 'The day of the downloads.';
+COMMENT ON COLUMN public.messageapproval.mailing_list IS 'The mailing list to which the message was posted.';
 
 
-COMMENT ON COLUMN public.libraryfiledownloadcount.count IS 'The number of downloads.';
+COMMENT ON COLUMN public.messageapproval.posted_message IS 'Foreign key to libraryfilealias table pointing to where the posted message''s text lives.';
 
 
-COMMENT ON COLUMN public.libraryfiledownloadcount.country IS 'The country from where the download requests came from.';
+COMMENT ON COLUMN public.messageapproval.posted_date IS 'The date the message was posted.';
 
 
-CREATE SEQUENCE public.libraryfiledownloadcount_id_seq
+COMMENT ON COLUMN public.messageapproval.status IS 'The status of the posted message.  Values are described in dbschema.PostedMessageStatus.';
+
+
+COMMENT ON COLUMN public.messageapproval.disposed_by IS 'The person who disposed of (i.e. approved or rejected) the message, or NULL if no disposition has yet been made.';
+
+
+COMMENT ON COLUMN public.messageapproval.disposal_date IS 'The date on which this message was disposed, or NULL if no disposition has yet been made.';
+
+
+COMMENT ON COLUMN public.messageapproval.reason IS 'The reason for the current status if any. This information will be displayed to the end user and mailing list moderators need to be aware of this - not a private whiteboard.';
+
+
+COMMENT ON COLUMN public.messageapproval.message IS 'Foreign key to message table pointing to the posted message.';
+
+
+CREATE SEQUENCE public.messageapproval_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9788,49 +11008,72 @@ CREATE SEQUENCE public.libraryfiledownloadcount_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.libraryfiledownloadcount_id_seq OWNED BY public.libraryfiledownloadcount.id;
+ALTER SEQUENCE public.messageapproval_id_seq OWNED BY public.messageapproval.id;
 
 
-CREATE TABLE public.livefs (
+CREATE TABLE public.messagechunk (
     id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    registrant integer NOT NULL,
-    owner integer NOT NULL,
-    distro_series integer NOT NULL,
-    name text NOT NULL,
-    json_data text,
-    require_virtualized boolean DEFAULT true NOT NULL,
-    relative_build_score integer DEFAULT 0 NOT NULL,
-    CONSTRAINT valid_name CHECK (public.valid_name(name))
-);
+    message integer NOT NULL,
+    sequence integer NOT NULL,
+    content text,
+    blob integer,
+    fti public.ts2_tsvector,
+    CONSTRAINT text_or_content CHECK ((((blob IS NULL) AND (content IS NULL)) OR ((blob IS NULL) <> (content IS NULL))))
+)
+WITH (fillfactor='100');
 
 
-COMMENT ON TABLE public.livefs IS 'A class of buildable live filesystem images.  Rows in this table only partially define how to build an image; the rest of the information comes from LiveFSBuild.';
+COMMENT ON TABLE public.messagechunk IS 'This table stores a single chunk of a possibly multipart message. There will be at least one row in this table for each message. text/* parts are stored in the content column. All other parts are stored in the Librarian and referenced via the blob column. If both content and blob are NULL, then this chunk has been removed (eg. offensive, legal reasons, virus etc.)';
 
 
-COMMENT ON COLUMN public.livefs.registrant IS 'The user who registered the live filesystem image.';
+COMMENT ON COLUMN public.messagechunk.sequence IS 'Order of a particular chunk. Chunks are orders in ascending order starting from 1.';
 
 
-COMMENT ON COLUMN public.livefs.owner IS 'The owner of the live filesystem image.';
+COMMENT ON COLUMN public.messagechunk.content IS 'Text content for this chunk of the message. This content is full text searchable.';
 
 
-COMMENT ON COLUMN public.livefs.distro_series IS 'The DistroSeries for which the image should be built.';
+COMMENT ON COLUMN public.messagechunk.blob IS 'Binary content for this chunk of the message.';
 
 
-COMMENT ON COLUMN public.livefs.name IS 'The name of the live filesystem image, unique per DistroSeries.';
+CREATE SEQUENCE public.messagechunk_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.livefs.json_data IS 'A JSON struct containing data for the image build.';
+ALTER SEQUENCE public.messagechunk_id_seq OWNED BY public.messagechunk.id;
 
 
-COMMENT ON COLUMN public.livefs.require_virtualized IS 'If True, this live filesystem image must be built only on a virtual machine.';
+CREATE TABLE public.messagerevision (
+    id integer NOT NULL,
+    message integer NOT NULL,
+    revision integer NOT NULL,
+    subject text,
+    date_created timestamp without time zone NOT NULL,
+    date_deleted timestamp without time zone
+)
+WITH (fillfactor='100');
 
 
-COMMENT ON COLUMN public.livefs.relative_build_score IS 'A delta to the build score that is applied to all builds of this live filesystem.';
+COMMENT ON TABLE public.messagerevision IS 'Old versions of an edited Message';
 
 
-CREATE SEQUENCE public.livefs_id_seq
+COMMENT ON COLUMN public.messagerevision.message IS 'The current message of this revision';
+
+
+COMMENT ON COLUMN public.messagerevision.revision IS 'The revision monotonic increasing number';
+
+
+COMMENT ON COLUMN public.messagerevision.date_created IS 'When the original message was edited and created this revision';
+
+
+COMMENT ON COLUMN public.messagerevision.date_deleted IS 'If this revision was deleted, when did that happen';
+
+
+CREATE SEQUENCE public.messagerevision_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9838,99 +11081,117 @@ CREATE SEQUENCE public.livefs_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.livefs_id_seq OWNED BY public.livefs.id;
+ALTER SEQUENCE public.messagerevision_id_seq OWNED BY public.messagerevision.id;
 
 
-CREATE TABLE public.livefsbuild (
+CREATE TABLE public.messagerevisionchunk (
     id integer NOT NULL,
-    requester integer NOT NULL,
-    livefs integer NOT NULL,
-    archive integer NOT NULL,
-    distro_arch_series integer NOT NULL,
-    pocket integer NOT NULL,
-    unique_key text,
-    json_data_override text,
-    processor integer NOT NULL,
-    virtualized boolean NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_started timestamp without time zone,
-    date_finished timestamp without time zone,
-    date_first_dispatched timestamp without time zone,
-    builder integer,
-    status integer NOT NULL,
-    log integer,
-    upload_log integer,
-    dependencies text,
-    failure_count integer DEFAULT 0 NOT NULL,
-    build_farm_job integer NOT NULL,
-    version text
-);
+    messagerevision integer NOT NULL,
+    sequence integer NOT NULL,
+    content text NOT NULL
+)
+WITH (fillfactor='100');
 
 
-COMMENT ON TABLE public.livefsbuild IS 'A build record for a live filesystem image.';
+COMMENT ON TABLE public.messagerevisionchunk IS 'Old chunks of a message when a revision was created for it';
 
 
-COMMENT ON COLUMN public.livefsbuild.requester IS 'The person who requested this live filesystem image build.';
+COMMENT ON COLUMN public.messagerevisionchunk.sequence IS 'Order of this particular chunk';
 
 
-COMMENT ON COLUMN public.livefsbuild.livefs IS 'Live filesystem image to build.';
+COMMENT ON COLUMN public.messagerevisionchunk.content IS 'Text content for this chunk of the message.';
 
 
-COMMENT ON COLUMN public.livefsbuild.archive IS 'The archive that the live filesystem image should build from.';
+CREATE SEQUENCE public.messagerevisionchunk_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.livefsbuild.distro_arch_series IS 'The distroarchseries that the live filesystem image should build from.';
+ALTER SEQUENCE public.messagerevisionchunk_id_seq OWNED BY public.messagerevisionchunk.id;
 
 
-COMMENT ON COLUMN public.livefsbuild.pocket IS 'The pocket that the live filesystem image should build from.';
+CREATE TABLE public.milestone (
+    id integer NOT NULL,
+    product integer,
+    name text NOT NULL,
+    distribution integer,
+    dateexpected timestamp without time zone,
+    active boolean DEFAULT true NOT NULL,
+    productseries integer,
+    distroseries integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    summary text,
+    codename text,
+    CONSTRAINT valid_name CHECK (public.valid_name(name)),
+    CONSTRAINT valid_target CHECK ((NOT ((product IS NULL) AND (distribution IS NULL))))
+);
 
 
-COMMENT ON COLUMN public.livefsbuild.unique_key IS 'A unique key distinguishing this build from others for the same livefs/archive/distroarchseries/pocket, or NULL.';
+COMMENT ON TABLE public.milestone IS 'An identifier that helps a maintainer group together things in some way, e.g. "1.2" could be a Milestone that bazaar developers could use to mark a task as needing fixing in bazaar 1.2.';
 
 
-COMMENT ON COLUMN public.livefsbuild.json_data_override IS 'A JSON struct containing data for the image build, each key of which overrides the same key from livefs.json_data.';
+COMMENT ON COLUMN public.milestone.product IS 'The product for which this is a milestone.';
 
 
-COMMENT ON COLUMN public.livefsbuild.virtualized IS 'The virtualization setting required by this build farm job.';
+COMMENT ON COLUMN public.milestone.name IS 'The identifier text, e.g. "1.2."';
 
 
-COMMENT ON COLUMN public.livefsbuild.date_created IS 'When the build farm job record was created.';
+COMMENT ON COLUMN public.milestone.distribution IS 'The distribution to which this milestone belongs, if it is a distro milestone.';
 
 
-COMMENT ON COLUMN public.livefsbuild.date_started IS 'When the build farm job started being processed.';
+COMMENT ON COLUMN public.milestone.dateexpected IS 'If set, the date on which we expect this milestone to be delivered. This allows for optional sorting by date.';
 
 
-COMMENT ON COLUMN public.livefsbuild.date_finished IS 'When the build farm job finished being processed.';
+COMMENT ON COLUMN public.milestone.active IS 'Whether or not this milestone should be displayed in general listings. All milestones will be visible on the "page of milestones for product foo", but we want to be able to screen out obviously old milestones over time, for the general listings and vocabularies.';
 
 
-COMMENT ON COLUMN public.livefsbuild.date_first_dispatched IS 'The instant the build was dispatched the first time.  This value will not get overridden if the build is retried.';
+COMMENT ON COLUMN public.milestone.productseries IS 'The productseries for which this is a milestone. A milestone on a productseries is ALWAYS also a milestone for the same product. This is because milestones started out on products/distributions but are moving to being on series/distroseries.';
 
 
-COMMENT ON COLUMN public.livefsbuild.builder IS 'The builder which processed this build farm job.';
+COMMENT ON COLUMN public.milestone.distroseries IS 'The distroseries for which this is a milestone. A milestone on a distroseries is ALWAYS also a milestone for the same distribution. This is because milestones started out on products/distributions but are moving to being on series/distroseries.';
 
 
-COMMENT ON COLUMN public.livefsbuild.status IS 'The current build status.';
+COMMENT ON COLUMN public.milestone.summary IS 'This can be used to summarize the changes included in past milestones and to document the status of current milestones.';
 
 
-COMMENT ON COLUMN public.livefsbuild.log IS 'The log file for this build farm job stored in the librarian.';
+COMMENT ON COLUMN public.milestone.codename IS 'A fun or easier to remember name for the milestone/release.';
+
+
+CREATE SEQUENCE public.milestone_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.livefsbuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
+ALTER SEQUENCE public.milestone_id_seq OWNED BY public.milestone.id;
 
 
-COMMENT ON COLUMN public.livefsbuild.dependencies IS 'A Debian-like dependency line specifying the current missing dependencies for this build.';
+CREATE TABLE public.milestonetag (
+    id integer NOT NULL,
+    milestone integer NOT NULL,
+    tag text NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    created_by integer NOT NULL,
+    CONSTRAINT valid_tag CHECK (public.valid_name(tag))
+);
 
 
-COMMENT ON COLUMN public.livefsbuild.failure_count IS 'The number of consecutive failures on this job.  If excessive, the job may be terminated.';
+COMMENT ON TABLE public.milestonetag IS 'Attaches simple text tags to a milestone.';
 
 
-COMMENT ON COLUMN public.livefsbuild.build_farm_job IS 'The build farm job with the base information.';
+COMMENT ON COLUMN public.milestonetag.milestone IS 'The milestone the tag is attached to.';
 
 
-COMMENT ON COLUMN public.livefsbuild.version IS 'A version string for this build.';
+COMMENT ON COLUMN public.milestonetag.tag IS 'The text representation of the tag.';
 
 
-CREATE SEQUENCE public.livefsbuild_id_seq
+CREATE SEQUENCE public.milestonetag_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9938,26 +11199,31 @@ CREATE SEQUENCE public.livefsbuild_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.livefsbuild_id_seq OWNED BY public.livefsbuild.id;
+ALTER SEQUENCE public.milestonetag_id_seq OWNED BY public.milestonetag.id;
 
 
-CREATE TABLE public.livefsfile (
+CREATE TABLE public.mirrorcdimagedistroseries (
     id integer NOT NULL,
-    livefsbuild integer NOT NULL,
-    libraryfile integer NOT NULL
+    distribution_mirror integer NOT NULL,
+    distroseries integer NOT NULL,
+    flavour text NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
 );
 
 
-COMMENT ON TABLE public.livefsfile IS 'A link between a live filesystem build and a file in the librarian that it produces.';
+COMMENT ON TABLE public.mirrorcdimagedistroseries IS 'The mirror of a given CD/DVD image.';
 
 
-COMMENT ON COLUMN public.livefsfile.livefsbuild IS 'The live filesystem build producing this file.';
+COMMENT ON COLUMN public.mirrorcdimagedistroseries.distribution_mirror IS 'The distribution mirror.';
 
 
-COMMENT ON COLUMN public.livefsfile.libraryfile IS 'A file in the librarian.';
+COMMENT ON COLUMN public.mirrorcdimagedistroseries.distroseries IS 'The Distribution Release.';
 
 
-CREATE SEQUENCE public.livefsfile_id_seq
+COMMENT ON COLUMN public.mirrorcdimagedistroseries.flavour IS 'The Distribution Release Flavour.';
+
+
+CREATE SEQUENCE public.mirrorcdimagedistroseries_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -9965,178 +11231,133 @@ CREATE SEQUENCE public.livefsfile_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.livefsfile_id_seq OWNED BY public.livefsfile.id;
+ALTER SEQUENCE public.mirrorcdimagedistroseries_id_seq OWNED BY public.mirrorcdimagedistroseries.id;
 
 
-CREATE TABLE public.logintoken (
+CREATE TABLE public.mirrordistroarchseries (
     id integer NOT NULL,
-    requester integer,
-    requesteremail text,
-    email text NOT NULL,
-    created timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    tokentype integer NOT NULL,
-    token text,
-    fingerprint text,
-    redirection_url text,
-    date_consumed timestamp without time zone,
-    CONSTRAINT valid_fingerprint CHECK (((fingerprint IS NULL) OR public.valid_fingerprint(fingerprint)))
+    distribution_mirror integer NOT NULL,
+    distroarchseries integer NOT NULL,
+    freshness integer NOT NULL,
+    pocket integer NOT NULL,
+    component integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
 );
 
 
-COMMENT ON TABLE public.logintoken IS 'LoginToken stores one time tokens used by Launchpad for validating email addresses and other tasks that require verifying an email address is valid such as password recovery and account merging. This table will be cleaned occasionally to remove expired tokens. Expiry time is not yet defined.';
+COMMENT ON TABLE public.mirrordistroarchseries IS 'The mirror of the packages of a given Distro Arch Release.';
 
 
-COMMENT ON COLUMN public.logintoken.requester IS 'The Person that made this request. This will be null for password recovery requests.';
+COMMENT ON COLUMN public.mirrordistroarchseries.distribution_mirror IS 'The distribution mirror.';
 
 
-COMMENT ON COLUMN public.logintoken.requesteremail IS 'The email address that was used to login when making this request. This provides an audit trail to help the end user confirm that this is a valid request. It is not a link to the EmailAddress table as this may be changed after the request is made. This field will be null for password recovery requests.';
+COMMENT ON COLUMN public.mirrordistroarchseries.distroarchseries IS 'The distro arch series.';
 
 
-COMMENT ON COLUMN public.logintoken.email IS 'The email address that this request was sent to.';
+COMMENT ON COLUMN public.mirrordistroarchseries.freshness IS 'The freshness of the mirror, that is, how up-to-date it is.';
 
 
-COMMENT ON COLUMN public.logintoken.created IS 'The timestamp that this request was made.';
+COMMENT ON COLUMN public.mirrordistroarchseries.pocket IS 'The PackagePublishingPocket.';
 
 
-COMMENT ON COLUMN public.logintoken.tokentype IS 'The type of request, as per dbschema.TokenType.';
+CREATE SEQUENCE public.mirrordistroarchseries_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.logintoken.token IS 'The token (not the URL) emailed used to uniquely identify this request. This token will be used to generate a URL that when clicked on will continue a workflow.';
+ALTER SEQUENCE public.mirrordistroarchseries_id_seq OWNED BY public.mirrordistroarchseries.id;
 
 
-COMMENT ON COLUMN public.logintoken.fingerprint IS 'The GPG key fingerprint to be validated on this transaction, it means that a new register will be created relating this given key with the requester in question. The requesteremail still passing for the same usual checks.';
+CREATE TABLE public.mirrordistroseriessource (
+    id integer NOT NULL,
+    distribution_mirror integer NOT NULL,
+    distroseries integer NOT NULL,
+    freshness integer NOT NULL,
+    pocket integer NOT NULL,
+    component integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+);
 
 
-COMMENT ON COLUMN public.logintoken.date_consumed IS 'The date and time when this token was consumed. It''s NULL if it hasn''t been consumed yet.';
+COMMENT ON TABLE public.mirrordistroseriessource IS 'The mirror of a given Distro Release';
 
 
-CREATE SEQUENCE public.logintoken_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.mirrordistroseriessource.distribution_mirror IS 'The distribution mirror.';
 
 
-ALTER SEQUENCE public.logintoken_id_seq OWNED BY public.logintoken.id;
+COMMENT ON COLUMN public.mirrordistroseriessource.distroseries IS 'The Distribution Release.';
 
 
-CREATE TABLE public.lp_account (
-    id integer NOT NULL,
-    openid_identifier text NOT NULL
-);
+COMMENT ON COLUMN public.mirrordistroseriessource.freshness IS 'The freshness of the mirror, that is, how up-to-date it is.';
 
 
-CREATE TABLE public.lp_openididentifier (
-    identifier text NOT NULL,
-    account integer NOT NULL,
-    date_created timestamp without time zone NOT NULL
-);
+CREATE SEQUENCE public.mirrordistroseriessource_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-CREATE TABLE public.lp_person (
-    id integer NOT NULL,
-    displayname text,
-    teamowner integer,
-    teamdescription text,
-    name text,
-    language integer,
-    fti public.ts2_tsvector,
-    defaultmembershipperiod integer,
-    defaultrenewalperiod integer,
-    subscriptionpolicy integer,
-    merged integer,
-    datecreated timestamp without time zone,
-    addressline1 text,
-    addressline2 text,
-    organization text,
-    city text,
-    province text,
-    country integer,
-    postcode text,
-    phone text,
-    homepage_content text,
-    icon integer,
-    mugshot integer,
-    hide_email_addresses boolean,
-    creation_rationale integer,
-    creation_comment text,
-    registrant integer,
-    logo integer,
-    renewal_policy integer,
-    personal_standing integer,
-    personal_standing_reason text,
-    mail_resumption_date date,
-    mailing_list_auto_subscribe_policy integer,
-    mailing_list_receive_duplicates boolean,
-    visibility integer,
-    verbose_bugnotifications boolean,
-    account integer
-);
+ALTER SEQUENCE public.mirrordistroseriessource_id_seq OWNED BY public.mirrordistroseriessource.id;
 
 
-CREATE TABLE public.lp_personlocation (
+CREATE TABLE public.mirrorproberecord (
     id integer NOT NULL,
-    date_created timestamp without time zone,
-    person integer,
-    latitude double precision,
-    longitude double precision,
-    time_zone text,
-    last_modified_by integer,
-    date_last_modified timestamp without time zone,
-    visible boolean,
-    locked boolean
+    distribution_mirror integer NOT NULL,
+    log_file integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL
 );
 
 
-CREATE TABLE public.lp_teamparticipation (
-    id integer NOT NULL,
-    team integer,
-    person integer
-);
+COMMENT ON TABLE public.mirrorproberecord IS 'Records stored when a mirror is probed.';
 
 
-CREATE TABLE public.mailinglist (
-    id integer NOT NULL,
-    team integer NOT NULL,
-    registrant integer NOT NULL,
-    date_registered timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    reviewer integer,
-    date_reviewed timestamp without time zone DEFAULT timezone('UTC'::text, now()),
-    date_activated timestamp without time zone DEFAULT timezone('UTC'::text, now()),
-    status integer DEFAULT 1 NOT NULL,
-    welcome_message text
-);
+COMMENT ON COLUMN public.mirrorproberecord.distribution_mirror IS 'The DistributionMirror.';
 
 
-COMMENT ON TABLE public.mailinglist IS 'The mailing list for a team.  Teams may have zero or one mailing list, and a mailing list is associated with exactly one team.  This table manages the state changes that a team mailing list can go through, and it contains information that will be used to instruct Mailman how to create, delete, and modify mailing lists (via XMLRPC).';
+COMMENT ON COLUMN public.mirrorproberecord.log_file IS 'The log file of the probe.';
 
 
-COMMENT ON COLUMN public.mailinglist.team IS 'The team this mailing list is associated with.';
+COMMENT ON COLUMN public.mirrorproberecord.date_created IS 'The date and time the probe was performed.';
 
 
-COMMENT ON COLUMN public.mailinglist.registrant IS 'The id of the Person who requested this list be created.';
+CREATE SEQUENCE public.mirrorproberecord_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.mailinglist.date_registered IS 'Date the list was requested to be created';
+ALTER SEQUENCE public.mirrorproberecord_id_seq OWNED BY public.mirrorproberecord.id;
 
 
-COMMENT ON COLUMN public.mailinglist.reviewer IS 'The id of the Person who reviewed the creation request, or NULL if not yet reviewed.';
+CREATE TABLE public.nameblacklist (
+    id integer NOT NULL,
+    regexp text NOT NULL,
+    comment text,
+    admin integer,
+    CONSTRAINT valid_regexp CHECK (public.valid_regexp(regexp))
+);
 
 
-COMMENT ON COLUMN public.mailinglist.date_reviewed IS 'The date the request was reviewed, or NULL if not yet reviewed.';
+COMMENT ON TABLE public.nameblacklist IS 'A list of regular expressions used to blacklist names.';
 
 
-COMMENT ON COLUMN public.mailinglist.date_activated IS 'The date the list was (last) activated.  If the list is not yet active, this field will be NULL.';
+COMMENT ON COLUMN public.nameblacklist.regexp IS 'A Python regular expression. It will be compiled with the IGNORECASE, UNICODE and VERBOSE flags. The Python search method will be used rather than match, so ^ markers should be used to indicate the start of a string.';
 
 
-COMMENT ON COLUMN public.mailinglist.status IS 'The current status of the mailing list, as a dbschema.MailingListStatus value.';
+COMMENT ON COLUMN public.nameblacklist.comment IS 'An optional comment on why this regexp was entered. It should not be displayed to non-admins and its only purpose is documentation.';
 
 
-COMMENT ON COLUMN public.mailinglist.welcome_message IS 'Text sent to new members when they are subscribed to the team list.  If NULL, no welcome message is sent.';
+COMMENT ON COLUMN public.nameblacklist.admin IS 'The person who can override the blacklisted name.';
 
 
-CREATE SEQUENCE public.mailinglist_id_seq
+CREATE SEQUENCE public.nameblacklist_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10144,34 +11365,65 @@ CREATE SEQUENCE public.mailinglist_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.mailinglist_id_seq OWNED BY public.mailinglist.id;
+ALTER SEQUENCE public.nameblacklist_id_seq OWNED BY public.nameblacklist.id;
 
 
-CREATE TABLE public.mailinglistsubscription (
+CREATE TABLE public.oauthaccesstoken (
     id integer NOT NULL,
+    consumer integer NOT NULL,
     person integer NOT NULL,
-    mailing_list integer NOT NULL,
-    date_joined timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    email_address integer
+    permission integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_expires timestamp without time zone,
+    key text NOT NULL,
+    secret text NOT NULL,
+    product integer,
+    project integer,
+    distribution integer,
+    sourcepackagename integer,
+    CONSTRAINT just_one_context CHECK ((public.null_count(ARRAY[product, project, distribution]) >= 2)),
+    CONSTRAINT sourcepackagename_needs_distro CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
 );
 
 
-COMMENT ON TABLE public.mailinglistsubscription IS 'Track the subscriptions of a person to team mailing lists.';
+COMMENT ON TABLE public.oauthaccesstoken IS 'An access token used by the consumer to act on behalf of one of our users.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.consumer IS 'The consumer which is going to access the protected resources.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.person IS 'The person on whose behalf the
+consumer will access Launchpad.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.permission IS 'The permission given by that person to the consumer.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.date_created IS 'The date/time in which the token was created.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.date_expires IS 'The date/time in which this token will stop being accepted by Launchpad.';
+
+
+COMMENT ON COLUMN public.oauthaccesstoken.key IS 'This token''s unique key.';
 
 
-COMMENT ON COLUMN public.mailinglistsubscription.person IS 'The person who is subscribed to the mailing list.';
+COMMENT ON COLUMN public.oauthaccesstoken.secret IS 'The secret used by the consumer (together with the token''s key) to access Launchpad on behalf of the person.';
 
 
-COMMENT ON COLUMN public.mailinglistsubscription.mailing_list IS 'The mailing list this person is subscribed to.';
+COMMENT ON COLUMN public.oauthaccesstoken.product IS 'The product associated with this token.';
 
 
-COMMENT ON COLUMN public.mailinglistsubscription.date_joined IS 'The date this person subscribed to the mailing list.';
+COMMENT ON COLUMN public.oauthaccesstoken.project IS 'The project associated with this token.';
 
 
-COMMENT ON COLUMN public.mailinglistsubscription.email_address IS 'Which of the person''s email addresses are subscribed to the mailing list.  This may be NULL to indicate that it''s the person''s preferred address.';
+COMMENT ON COLUMN public.oauthaccesstoken.distribution IS 'The distribution associated with this token.';
 
 
-CREATE SEQUENCE public.mailinglistsubscription_id_seq
+COMMENT ON COLUMN public.oauthaccesstoken.sourcepackagename IS 'The sourcepackagename associated with this token.';
+
+
+CREATE SEQUENCE public.oauthaccesstoken_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10179,43 +11431,34 @@ CREATE SEQUENCE public.mailinglistsubscription_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.mailinglistsubscription_id_seq OWNED BY public.mailinglistsubscription.id;
+ALTER SEQUENCE public.oauthaccesstoken_id_seq OWNED BY public.oauthaccesstoken.id;
 
 
-CREATE TABLE public.message (
+CREATE TABLE public.oauthconsumer (
     id integer NOT NULL,
-    datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    subject text,
-    owner integer,
-    parent integer,
-    distribution integer,
-    rfc822msgid text NOT NULL,
-    fti public.ts2_tsvector,
-    raw integer,
-    visible boolean DEFAULT true NOT NULL
-)
-WITH (fillfactor='100');
-
-
-COMMENT ON TABLE public.message IS 'This table stores a single RFC822-style message. Messages can be threaded (using the parent field). These messages can then be referenced from elsewhere in the system, such as the BugMessage table, integrating messageboard facilities with the rest of The Launchpad.';
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    disabled boolean DEFAULT false NOT NULL,
+    key text NOT NULL,
+    secret text
+);
 
 
-COMMENT ON COLUMN public.message.subject IS 'The title text of the message, or the subject if it was an email.';
+COMMENT ON TABLE public.oauthconsumer IS 'A third part application that will access Launchpad on behalf of one of our users.';
 
 
-COMMENT ON COLUMN public.message.parent IS 'A "parent message". This allows for some level of threading in Messages.';
+COMMENT ON COLUMN public.oauthconsumer.date_created IS 'The creation date.';
 
 
-COMMENT ON COLUMN public.message.distribution IS 'The distribution in which this message originated, if we know it.';
+COMMENT ON COLUMN public.oauthconsumer.disabled IS 'Is this consumer disabled?';
 
 
-COMMENT ON COLUMN public.message.raw IS 'The original unadulterated message if it arrived via email. This is required to provide access to the original, undecoded message.';
+COMMENT ON COLUMN public.oauthconsumer.key IS 'The unique key for this consumer.';
 
 
-COMMENT ON COLUMN public.message.visible IS 'If false, the message is hidden and should not be shown in any UI.';
+COMMENT ON COLUMN public.oauthconsumer.secret IS 'The secret used by this consumer (together with its key) to identify itself with Launchpad.';
 
 
-CREATE SEQUENCE public.message_id_seq
+CREATE SEQUENCE public.oauthconsumer_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10223,54 +11466,70 @@ CREATE SEQUENCE public.message_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.message_id_seq OWNED BY public.message.id;
+ALTER SEQUENCE public.oauthconsumer_id_seq OWNED BY public.oauthconsumer.id;
 
 
-CREATE TABLE public.messageapproval (
+CREATE TABLE public.oauthrequesttoken (
     id integer NOT NULL,
-    posted_by integer NOT NULL,
-    mailing_list integer NOT NULL,
-    posted_message integer NOT NULL,
-    posted_date timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    status integer DEFAULT 0 NOT NULL,
-    disposed_by integer,
-    disposal_date timestamp without time zone DEFAULT timezone('UTC'::text, now()),
-    reason text,
-    message integer NOT NULL
+    consumer integer NOT NULL,
+    person integer,
+    permission integer,
+    date_expires timestamp without time zone,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
+    date_reviewed timestamp without time zone,
+    key text NOT NULL,
+    secret text NOT NULL,
+    product integer,
+    project integer,
+    distribution integer,
+    sourcepackagename integer,
+    CONSTRAINT just_one_context CHECK ((public.null_count(ARRAY[product, project, distribution]) >= 2)),
+    CONSTRAINT reviewed_request CHECK ((((date_reviewed IS NULL) = (person IS NULL)) AND ((date_reviewed IS NULL) = (permission IS NULL)))),
+    CONSTRAINT sourcepackagename_needs_distro CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
 );
 
 
-COMMENT ON TABLE public.messageapproval IS 'Track mailing list postings awaiting approval from the team owner.';
+COMMENT ON TABLE public.oauthrequesttoken IS 'A request token which, once authorized by the user, is exchanged for an access token.';
 
 
-COMMENT ON COLUMN public.messageapproval.posted_by IS 'The person who posted the message.';
+COMMENT ON COLUMN public.oauthrequesttoken.consumer IS 'The consumer which is going to access the protected resources.';
 
 
-COMMENT ON COLUMN public.messageapproval.mailing_list IS 'The mailing list to which the message was posted.';
+COMMENT ON COLUMN public.oauthrequesttoken.person IS 'The person who authorized this token.';
 
 
-COMMENT ON COLUMN public.messageapproval.posted_message IS 'Foreign key to libraryfilealias table pointing to where the posted message''s text lives.';
+COMMENT ON COLUMN public.oauthrequesttoken.permission IS 'The permission given by the
+person to the consumer.';
 
 
-COMMENT ON COLUMN public.messageapproval.posted_date IS 'The date the message was posted.';
+COMMENT ON COLUMN public.oauthrequesttoken.date_expires IS 'When the authorization is to expire.';
 
 
-COMMENT ON COLUMN public.messageapproval.status IS 'The status of the posted message.  Values are described in dbschema.PostedMessageStatus.';
+COMMENT ON COLUMN public.oauthrequesttoken.date_created IS 'The date/time in which the token was created.';
 
 
-COMMENT ON COLUMN public.messageapproval.disposed_by IS 'The person who disposed of (i.e. approved or rejected) the message, or NULL if no disposition has yet been made.';
+COMMENT ON COLUMN public.oauthrequesttoken.date_reviewed IS 'When the authorization request was authorized or rejected by the person.';
 
 
-COMMENT ON COLUMN public.messageapproval.disposal_date IS 'The date on which this message was disposed, or NULL if no disposition has yet been made.';
+COMMENT ON COLUMN public.oauthrequesttoken.key IS 'This token''s unique key.';
 
 
-COMMENT ON COLUMN public.messageapproval.reason IS 'The reason for the current status if any. This information will be displayed to the end user and mailing list moderators need to be aware of this - not a private whiteboard.';
+COMMENT ON COLUMN public.oauthrequesttoken.secret IS 'The secret used by the consumer (together with the token''s key) to get an access token once the user has authorized its use.';
 
 
-COMMENT ON COLUMN public.messageapproval.message IS 'Foreign key to message table pointing to the posted message.';
+COMMENT ON COLUMN public.oauthrequesttoken.product IS 'The product associated with this token.';
 
 
-CREATE SEQUENCE public.messageapproval_id_seq
+COMMENT ON COLUMN public.oauthrequesttoken.project IS 'The project associated with this token.';
+
+
+COMMENT ON COLUMN public.oauthrequesttoken.distribution IS 'The distribution associated with this token.';
+
+
+COMMENT ON COLUMN public.oauthrequesttoken.sourcepackagename IS 'The sourcepackagename associated with this token.';
+
+
+CREATE SEQUENCE public.oauthrequesttoken_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10278,34 +11537,35 @@ CREATE SEQUENCE public.messageapproval_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.messageapproval_id_seq OWNED BY public.messageapproval.id;
+ALTER SEQUENCE public.oauthrequesttoken_id_seq OWNED BY public.oauthrequesttoken.id;
 
 
-CREATE TABLE public.messagechunk (
+CREATE TABLE public.ocifile (
     id integer NOT NULL,
-    message integer NOT NULL,
-    sequence integer NOT NULL,
-    content text,
-    blob integer,
-    fti public.ts2_tsvector,
-    CONSTRAINT text_or_content CHECK ((((blob IS NULL) AND (content IS NULL)) OR ((blob IS NULL) <> (content IS NULL))))
-)
-WITH (fillfactor='100');
+    build integer NOT NULL,
+    library_file integer NOT NULL,
+    layer_file_digest character(80),
+    date_last_used timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL
+);
 
 
-COMMENT ON TABLE public.messagechunk IS 'This table stores a single chunk of a possibly multipart message. There will be at least one row in this table for each message. text/* parts are stored in the content column. All other parts are stored in the Librarian and referenced via the blob column. If both content and blob are NULL, then this chunk has been removed (eg. offensive, legal reasons, virus etc.)';
+COMMENT ON TABLE public.ocifile IS 'A link between an OCI recipe build and a file in the librarian that it produces.';
 
 
-COMMENT ON COLUMN public.messagechunk.sequence IS 'Order of a particular chunk. Chunks are orders in ascending order starting from 1.';
+COMMENT ON COLUMN public.ocifile.build IS 'The OCI recipe build producing this file.';
 
 
-COMMENT ON COLUMN public.messagechunk.content IS 'Text content for this chunk of the message. This content is full text searchable.';
+COMMENT ON COLUMN public.ocifile.library_file IS 'A file in the librarian.';
 
 
-COMMENT ON COLUMN public.messagechunk.blob IS 'Binary content for this chunk of the message.';
+COMMENT ON COLUMN public.ocifile.layer_file_digest IS 'Content-addressable hash of the file''s contents, used for reassembling image layers when pushing a build to a registry.  This hash is in an opaque format generated by the OCI build tool.';
 
 
-CREATE SEQUENCE public.messagechunk_id_seq
+COMMENT ON COLUMN public.ocifile.date_last_used IS 'The datetime this file was last used in a build.';
+
+
+CREATE SEQUENCE public.ocifile_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10313,57 +11573,60 @@ CREATE SEQUENCE public.messagechunk_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.messagechunk_id_seq OWNED BY public.messagechunk.id;
+ALTER SEQUENCE public.ocifile_id_seq OWNED BY public.ocifile.id;
 
 
-CREATE TABLE public.milestone (
+CREATE TABLE public.ociproject (
     id integer NOT NULL,
-    product integer,
-    name text NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    registrant integer NOT NULL,
     distribution integer,
-    dateexpected timestamp without time zone,
-    active boolean DEFAULT true NOT NULL,
-    productseries integer,
-    distroseries integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    summary text,
-    codename text,
-    CONSTRAINT valid_name CHECK (public.valid_name(name)),
-    CONSTRAINT valid_target CHECK ((NOT ((product IS NULL) AND (distribution IS NULL))))
+    ociprojectname integer NOT NULL,
+    description text,
+    bug_reporting_guidelines text,
+    bug_reported_acknowledgement text,
+    enable_bugfiling_duplicate_search boolean DEFAULT true NOT NULL,
+    project integer,
+    CONSTRAINT one_container CHECK (((project IS NULL) <> (distribution IS NULL)))
 );
 
 
-COMMENT ON TABLE public.milestone IS 'An identifier that helps a maintainer group together things in some way, e.g. "1.2" could be a Milestone that bazaar developers could use to mark a task as needing fixing in bazaar 1.2.';
+COMMENT ON TABLE public.ociproject IS 'A project containing Open Container Initiative recipes.';
 
 
-COMMENT ON COLUMN public.milestone.product IS 'The product for which this is a milestone.';
+COMMENT ON COLUMN public.ociproject.date_created IS 'The date on which this OCI project was created in Launchpad.';
 
 
-COMMENT ON COLUMN public.milestone.name IS 'The identifier text, e.g. "1.2."';
+COMMENT ON COLUMN public.ociproject.date_last_modified IS 'The date on which this OCI project was last modified in Launchpad.';
 
 
-COMMENT ON COLUMN public.milestone.distribution IS 'The distribution to which this milestone belongs, if it is a distro milestone.';
+COMMENT ON COLUMN public.ociproject.registrant IS 'The user who registered this OCI project.';
 
 
-COMMENT ON COLUMN public.milestone.dateexpected IS 'If set, the date on which we expect this milestone to be delivered. This allows for optional sorting by date.';
+COMMENT ON COLUMN public.ociproject.distribution IS 'The distribution that this OCI project belongs to.';
 
 
-COMMENT ON COLUMN public.milestone.active IS 'Whether or not this milestone should be displayed in general listings. All milestones will be visible on the "page of milestones for product foo", but we want to be able to screen out obviously old milestones over time, for the general listings and vocabularies.';
+COMMENT ON COLUMN public.ociproject.ociprojectname IS 'The name of this OCI project.';
 
 
-COMMENT ON COLUMN public.milestone.productseries IS 'The productseries for which this is a milestone. A milestone on a productseries is ALWAYS also a milestone for the same product. This is because milestones started out on products/distributions but are moving to being on series/distroseries.';
+COMMENT ON COLUMN public.ociproject.description IS 'A short description of this OCI project.';
 
 
-COMMENT ON COLUMN public.milestone.distroseries IS 'The distroseries for which this is a milestone. A milestone on a distroseries is ALWAYS also a milestone for the same distribution. This is because milestones started out on products/distributions but are moving to being on series/distroseries.';
+COMMENT ON COLUMN public.ociproject.bug_reporting_guidelines IS 'Guidelines to the end user for reporting bugs on this OCI project';
 
 
-COMMENT ON COLUMN public.milestone.summary IS 'This can be used to summarize the changes included in past milestones and to document the status of current milestones.';
+COMMENT ON COLUMN public.ociproject.bug_reported_acknowledgement IS 'A message of acknowledgement to display to a bug reporter after they''ve reported a new bug.';
 
 
-COMMENT ON COLUMN public.milestone.codename IS 'A fun or easier to remember name for the milestone/release.';
+COMMENT ON COLUMN public.ociproject.enable_bugfiling_duplicate_search IS 'Enable/disable a search for possible duplicates when a bug is filed.';
 
 
-CREATE SEQUENCE public.milestone_id_seq
+COMMENT ON COLUMN public.ociproject.project IS 'The project that this OCI project is associated with.';
+
+
+CREATE SEQUENCE public.ociproject_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10371,29 +11634,24 @@ CREATE SEQUENCE public.milestone_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.milestone_id_seq OWNED BY public.milestone.id;
+ALTER SEQUENCE public.ociproject_id_seq OWNED BY public.ociproject.id;
 
 
-CREATE TABLE public.milestonetag (
+CREATE TABLE public.ociprojectname (
     id integer NOT NULL,
-    milestone integer NOT NULL,
-    tag text NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    created_by integer NOT NULL,
-    CONSTRAINT valid_tag CHECK (public.valid_name(tag))
+    name text NOT NULL,
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
 );
 
 
-COMMENT ON TABLE public.milestonetag IS 'Attaches simple text tags to a milestone.';
-
-
-COMMENT ON COLUMN public.milestonetag.milestone IS 'The milestone the tag is attached to.';
+COMMENT ON TABLE public.ociprojectname IS 'A name of an Open Container Initiative project.';
 
 
-COMMENT ON COLUMN public.milestonetag.tag IS 'The text representation of the tag.';
+COMMENT ON COLUMN public.ociprojectname.name IS 'A lowercase name identifying an OCI project.';
 
 
-CREATE SEQUENCE public.milestonetag_id_seq
+CREATE SEQUENCE public.ociprojectname_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10401,31 +11659,44 @@ CREATE SEQUENCE public.milestonetag_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.milestonetag_id_seq OWNED BY public.milestonetag.id;
+ALTER SEQUENCE public.ociprojectname_id_seq OWNED BY public.ociprojectname.id;
 
 
-CREATE TABLE public.mirrorcdimagedistroseries (
+CREATE TABLE public.ociprojectseries (
     id integer NOT NULL,
-    distribution_mirror integer NOT NULL,
-    distroseries integer NOT NULL,
-    flavour text NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+    ociproject integer NOT NULL,
+    name text NOT NULL,
+    summary text NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    registrant integer NOT NULL,
+    status integer DEFAULT 2 NOT NULL,
+    CONSTRAINT valid_name CHECK (public.valid_name(name))
 );
 
 
-COMMENT ON TABLE public.mirrorcdimagedistroseries IS 'The mirror of a given CD/DVD image.';
+COMMENT ON TABLE public.ociprojectseries IS 'A series of an Open Container Initiative project, used to allow tracking bugs against multiple versions of images.';
 
 
-COMMENT ON COLUMN public.mirrorcdimagedistroseries.distribution_mirror IS 'The distribution mirror.';
+COMMENT ON COLUMN public.ociprojectseries.ociproject IS 'The OCI project that this series belongs to.';
 
 
-COMMENT ON COLUMN public.mirrorcdimagedistroseries.distroseries IS 'The Distribution Release.';
+COMMENT ON COLUMN public.ociprojectseries.name IS 'The name of this series.';
 
 
-COMMENT ON COLUMN public.mirrorcdimagedistroseries.flavour IS 'The Distribution Release Flavour.';
+COMMENT ON COLUMN public.ociprojectseries.summary IS 'A brief summary of this series.';
 
 
-CREATE SEQUENCE public.mirrorcdimagedistroseries_id_seq
+COMMENT ON COLUMN public.ociprojectseries.date_created IS 'The date on which this series was created in Launchpad.';
+
+
+COMMENT ON COLUMN public.ociprojectseries.registrant IS 'The user who registered this series.';
+
+
+COMMENT ON COLUMN public.ociprojectseries.status IS 'The current status of this series.';
+
+
+CREATE SEQUENCE public.ociprojectseries_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10433,36 +11704,31 @@ CREATE SEQUENCE public.mirrorcdimagedistroseries_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.mirrorcdimagedistroseries_id_seq OWNED BY public.mirrorcdimagedistroseries.id;
+ALTER SEQUENCE public.ociprojectseries_id_seq OWNED BY public.ociprojectseries.id;
 
 
-CREATE TABLE public.mirrordistroarchseries (
+CREATE TABLE public.ocipushrule (
     id integer NOT NULL,
-    distribution_mirror integer NOT NULL,
-    distroarchseries integer NOT NULL,
-    freshness integer NOT NULL,
-    pocket integer NOT NULL,
-    component integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+    recipe integer NOT NULL,
+    registry_credentials integer NOT NULL,
+    image_name text NOT NULL
 );
 
 
-COMMENT ON TABLE public.mirrordistroarchseries IS 'The mirror of the packages of a given Distro Arch Release.';
-
-
-COMMENT ON COLUMN public.mirrordistroarchseries.distribution_mirror IS 'The distribution mirror.';
+COMMENT ON TABLE public.ocipushrule IS 'A rule for pushing builds of an OCI recipe to a registry.';
 
 
-COMMENT ON COLUMN public.mirrordistroarchseries.distroarchseries IS 'The distro arch series.';
+COMMENT ON COLUMN public.ocipushrule.recipe IS 'The recipe for which the rule is defined.';
 
 
-COMMENT ON COLUMN public.mirrordistroarchseries.freshness IS 'The freshness of the mirror, that is, how up-to-date it is.';
+COMMENT ON COLUMN public.ocipushrule.registry_credentials IS 'The registry credentials to use.';
 
 
-COMMENT ON COLUMN public.mirrordistroarchseries.pocket IS 'The PackagePublishingPocket.';
+COMMENT ON COLUMN public.ocipushrule.image_name IS 'The intended name of the image on the registry.';
 
 
-CREATE SEQUENCE public.mirrordistroarchseries_id_seq
+CREATE SEQUENCE public.ocipushrule_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10470,64 +11736,94 @@ CREATE SEQUENCE public.mirrordistroarchseries_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.mirrordistroarchseries_id_seq OWNED BY public.mirrordistroarchseries.id;
+ALTER SEQUENCE public.ocipushrule_id_seq OWNED BY public.ocipushrule.id;
 
 
-CREATE TABLE public.mirrordistroseriessource (
+CREATE TABLE public.ocirecipe (
     id integer NOT NULL,
-    distribution_mirror integer NOT NULL,
-    distroseries integer NOT NULL,
-    freshness integer NOT NULL,
-    pocket integer NOT NULL,
-    component integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_last_modified timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    registrant integer NOT NULL,
+    owner integer NOT NULL,
+    oci_project integer NOT NULL,
+    name text NOT NULL,
+    description text,
+    official boolean DEFAULT false NOT NULL,
+    git_repository integer,
+    git_path text,
+    build_file text NOT NULL,
+    require_virtualized boolean DEFAULT true NOT NULL,
+    build_daily boolean DEFAULT false NOT NULL,
+    allow_internet boolean DEFAULT true NOT NULL,
+    build_path text DEFAULT '.'::text NOT NULL,
+    build_args jsonb,
+    image_name text,
+    information_type integer,
+    access_policy integer,
+    access_grants integer[],
+    CONSTRAINT consistent_git_ref CHECK (((git_repository IS NULL) = (git_path IS NULL)))
 );
 
 
-COMMENT ON TABLE public.mirrordistroseriessource IS 'The mirror of a given Distro Release';
+COMMENT ON TABLE public.ocirecipe IS 'A recipe for building Open Container Initiative images.';
 
 
-COMMENT ON COLUMN public.mirrordistroseriessource.distribution_mirror IS 'The distribution mirror.';
+COMMENT ON COLUMN public.ocirecipe.date_created IS 'The date on which this recipe was created in Launchpad.';
 
 
-COMMENT ON COLUMN public.mirrordistroseriessource.distroseries IS 'The Distribution Release.';
+COMMENT ON COLUMN public.ocirecipe.date_last_modified IS 'The date on which this recipe was last modified in Launchpad.';
 
 
-COMMENT ON COLUMN public.mirrordistroseriessource.freshness IS 'The freshness of the mirror, that is, how up-to-date it is.';
+COMMENT ON COLUMN public.ocirecipe.registrant IS 'The user who registered this recipe.';
+
+
+COMMENT ON COLUMN public.ocirecipe.owner IS 'The owner of the recipe.';
+
+
+COMMENT ON COLUMN public.ocirecipe.oci_project IS 'The OCI project that this recipe is for.';
+
+
+COMMENT ON COLUMN public.ocirecipe.name IS 'The name of this recipe.';
+
+
+COMMENT ON COLUMN public.ocirecipe.description IS 'A short description of this recipe.';
+
+
+COMMENT ON COLUMN public.ocirecipe.official IS 'True if this recipe is official for its OCI project.';
+
+
+COMMENT ON COLUMN public.ocirecipe.git_repository IS 'A Git repository with a branch containing an OCI recipe.';
+
+
+COMMENT ON COLUMN public.ocirecipe.git_path IS 'The branch within this recipe''s Git repository where its build files are maintained.';
+
+
+COMMENT ON COLUMN public.ocirecipe.build_file IS 'The relative path to the file within this recipe''s branch that defines how to build the recipe.';
 
 
-CREATE SEQUENCE public.mirrordistroseriessource_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON COLUMN public.ocirecipe.require_virtualized IS 'If True, this recipe must be built only on a virtual machine.';
 
 
-ALTER SEQUENCE public.mirrordistroseriessource_id_seq OWNED BY public.mirrordistroseriessource.id;
+COMMENT ON COLUMN public.ocirecipe.build_daily IS 'If True, this recipe should be built daily.';
 
 
-CREATE TABLE public.mirrorproberecord (
-    id integer NOT NULL,
-    distribution_mirror integer NOT NULL,
-    log_file integer,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL
-);
+COMMENT ON COLUMN public.ocirecipe.allow_internet IS 'If True, builds of this OCIRecipe may allow access to external network resources.';
 
 
-COMMENT ON TABLE public.mirrorproberecord IS 'Records stored when a mirror is probed.';
+COMMENT ON COLUMN public.ocirecipe.build_path IS 'Directory to use for build context and OCIRecipe.build_file location.';
 
 
-COMMENT ON COLUMN public.mirrorproberecord.distribution_mirror IS 'The DistributionMirror.';
+COMMENT ON COLUMN public.ocirecipe.build_args IS 'ARGs to be used when building the OCI Recipe.';
 
 
-COMMENT ON COLUMN public.mirrorproberecord.log_file IS 'The log file of the probe.';
+COMMENT ON COLUMN public.ocirecipe.image_name IS 'Image name to use on upload to registry.';
 
 
-COMMENT ON COLUMN public.mirrorproberecord.date_created IS 'The date and time the probe was performed.';
+COMMENT ON COLUMN public.ocirecipe.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine to apply an access policy.';
 
 
-CREATE SEQUENCE public.mirrorproberecord_id_seq
+CREATE SEQUENCE public.ocirecipe_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10535,97 +11831,98 @@ CREATE SEQUENCE public.mirrorproberecord_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.mirrorproberecord_id_seq OWNED BY public.mirrorproberecord.id;
+ALTER SEQUENCE public.ocirecipe_id_seq OWNED BY public.ocirecipe.id;
 
 
-CREATE TABLE public.nameblacklist (
-    id integer NOT NULL,
-    regexp text NOT NULL,
-    comment text,
-    admin integer,
-    CONSTRAINT valid_regexp CHECK (public.valid_regexp(regexp))
+CREATE TABLE public.ocirecipearch (
+    recipe integer NOT NULL,
+    processor integer NOT NULL
 );
 
 
-COMMENT ON TABLE public.nameblacklist IS 'A list of regular expressions used to blacklist names.';
+COMMENT ON TABLE public.ocirecipearch IS 'The architectures an OCI recipe should be built for.';
 
 
-COMMENT ON COLUMN public.nameblacklist.regexp IS 'A Python regular expression. It will be compiled with the IGNORECASE, UNICODE and VERBOSE flags. The Python search method will be used rather than match, so ^ markers should be used to indicate the start of a string.';
+COMMENT ON COLUMN public.ocirecipearch.recipe IS 'The OCI recipe for which an architecture is specified.';
 
 
-COMMENT ON COLUMN public.nameblacklist.comment IS 'An optional comment on why this regexp was entered. It should not be displayed to non-admins and its only purpose is documentation.';
+COMMENT ON COLUMN public.ocirecipearch.processor IS 'The architecture for which the OCI recipe should be built.';
 
 
-COMMENT ON COLUMN public.nameblacklist.admin IS 'The person who can override the blacklisted name.';
+CREATE TABLE public.ocirecipebuild (
+    id integer NOT NULL,
+    requester integer NOT NULL,
+    recipe integer NOT NULL,
+    processor integer NOT NULL,
+    virtualized boolean NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    date_started timestamp without time zone,
+    date_finished timestamp without time zone,
+    date_first_dispatched timestamp without time zone,
+    builder integer,
+    status integer NOT NULL,
+    log integer,
+    upload_log integer,
+    dependencies text,
+    failure_count integer DEFAULT 0 NOT NULL,
+    build_farm_job integer NOT NULL,
+    build_request integer
+);
 
 
-CREATE SEQUENCE public.nameblacklist_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON TABLE public.ocirecipebuild IS 'A build record for an OCI recipe.';
 
 
-ALTER SEQUENCE public.nameblacklist_id_seq OWNED BY public.nameblacklist.id;
+COMMENT ON COLUMN public.ocirecipebuild.requester IS 'The person who requested this OCI recipe build.';
 
 
-CREATE TABLE public.oauthaccesstoken (
-    id integer NOT NULL,
-    consumer integer NOT NULL,
-    person integer NOT NULL,
-    permission integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_expires timestamp without time zone,
-    key text NOT NULL,
-    secret text NOT NULL,
-    product integer,
-    project integer,
-    distribution integer,
-    sourcepackagename integer,
-    CONSTRAINT just_one_context CHECK ((public.null_count(ARRAY[product, project, distribution]) >= 2)),
-    CONSTRAINT sourcepackagename_needs_distro CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
-);
+COMMENT ON COLUMN public.ocirecipebuild.recipe IS 'The OCI recipe to build.';
 
 
-COMMENT ON TABLE public.oauthaccesstoken IS 'An access token used by the consumer to act on behalf of one of our users.';
+COMMENT ON COLUMN public.ocirecipebuild.processor IS 'The processor that the OCI recipe should be built for.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.consumer IS 'The consumer which is going to access the protected resources.';
+COMMENT ON COLUMN public.ocirecipebuild.virtualized IS 'The virtualization setting required by this build farm job.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.person IS 'The person on whose behalf the
-consumer will access Launchpad.';
+COMMENT ON COLUMN public.ocirecipebuild.date_created IS 'When the build farm job record was created.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.permission IS 'The permission given by that person to the consumer.';
+COMMENT ON COLUMN public.ocirecipebuild.date_started IS 'When the build farm job started being processed.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.date_created IS 'The date/time in which the token was created.';
+COMMENT ON COLUMN public.ocirecipebuild.date_finished IS 'When the build farm job finished being processed.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.date_expires IS 'The date/time in which this token will stop being accepted by Launchpad.';
+COMMENT ON COLUMN public.ocirecipebuild.date_first_dispatched IS 'The instant the build was dispatched the first time.  This value will not get overridden if the build is retried.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.key IS 'This token''s unique key.';
+COMMENT ON COLUMN public.ocirecipebuild.builder IS 'The builder which processed this build farm job.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.secret IS 'The secret used by the consumer (together with the token''s key) to access Launchpad on behalf of the person.';
+COMMENT ON COLUMN public.ocirecipebuild.status IS 'The current build status.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.product IS 'The product associated with this token.';
+COMMENT ON COLUMN public.ocirecipebuild.log IS 'The log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.project IS 'The project associated with this token.';
+COMMENT ON COLUMN public.ocirecipebuild.upload_log IS 'The upload log file for this build farm job stored in the librarian.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.distribution IS 'The distribution associated with this token.';
+COMMENT ON COLUMN public.ocirecipebuild.dependencies IS 'A Debian-like dependency line specifying the current missing dependencies for this build.';
 
 
-COMMENT ON COLUMN public.oauthaccesstoken.sourcepackagename IS 'The sourcepackagename associated with this token.';
+COMMENT ON COLUMN public.ocirecipebuild.failure_count IS 'The number of consecutive failures on this job.  If excessive, the job may be terminated.';
 
 
-CREATE SEQUENCE public.oauthaccesstoken_id_seq
+COMMENT ON COLUMN public.ocirecipebuild.build_farm_job IS 'The build farm job with the base information.';
+
+
+COMMENT ON COLUMN public.ocirecipebuild.build_request IS 'The build request that caused this build to be created.';
+
+
+CREATE SEQUENCE public.ocirecipebuild_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10633,105 +11930,113 @@ CREATE SEQUENCE public.oauthaccesstoken_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.oauthaccesstoken_id_seq OWNED BY public.oauthaccesstoken.id;
+ALTER SEQUENCE public.ocirecipebuild_id_seq OWNED BY public.ocirecipebuild.id;
 
 
-CREATE TABLE public.oauthconsumer (
-    id integer NOT NULL,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    disabled boolean DEFAULT false NOT NULL,
-    key text NOT NULL,
-    secret text
+CREATE TABLE public.ocirecipebuildjob (
+    job integer NOT NULL,
+    build integer NOT NULL,
+    job_type integer NOT NULL,
+    json_data jsonb NOT NULL
 );
 
 
-COMMENT ON TABLE public.oauthconsumer IS 'A third part application that will access Launchpad on behalf of one of our users.';
+COMMENT ON TABLE public.ocirecipebuildjob IS 'Contains references to jobs that are executed for a build of an OCI recipe.';
 
 
-COMMENT ON COLUMN public.oauthconsumer.date_created IS 'The creation date.';
+COMMENT ON COLUMN public.ocirecipebuildjob.job IS 'A reference to a Job row that has all the common job details.';
 
 
-COMMENT ON COLUMN public.oauthconsumer.disabled IS 'Is this consumer disabled?';
+COMMENT ON COLUMN public.ocirecipebuildjob.build IS 'The OCI recipe build that this job is for.';
 
 
-COMMENT ON COLUMN public.oauthconsumer.key IS 'The unique key for this consumer.';
+COMMENT ON COLUMN public.ocirecipebuildjob.job_type IS 'The type of a job, such as a registry push.';
 
 
-COMMENT ON COLUMN public.oauthconsumer.secret IS 'The secret used by this consumer (together with its key) to identify itself with Launchpad.';
+COMMENT ON COLUMN public.ocirecipebuildjob.json_data IS 'Data that is specific to a particular job type.';
 
 
-CREATE SEQUENCE public.oauthconsumer_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+CREATE TABLE public.ocirecipejob (
+    job integer NOT NULL,
+    recipe integer NOT NULL,
+    job_type integer NOT NULL,
+    json_data jsonb NOT NULL
+);
 
 
-ALTER SEQUENCE public.oauthconsumer_id_seq OWNED BY public.oauthconsumer.id;
+COMMENT ON TABLE public.ocirecipejob IS 'Contains references to jobs that are executed for an OCI Recipe.';
 
 
-CREATE TABLE public.oauthrequesttoken (
-    id integer NOT NULL,
-    consumer integer NOT NULL,
-    person integer,
-    permission integer,
-    date_expires timestamp without time zone,
-    date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    date_reviewed timestamp without time zone,
-    key text NOT NULL,
-    secret text NOT NULL,
-    product integer,
-    project integer,
-    distribution integer,
-    sourcepackagename integer,
-    CONSTRAINT just_one_context CHECK ((public.null_count(ARRAY[product, project, distribution]) >= 2)),
-    CONSTRAINT reviewed_request CHECK ((((date_reviewed IS NULL) = (person IS NULL)) AND ((date_reviewed IS NULL) = (permission IS NULL)))),
-    CONSTRAINT sourcepackagename_needs_distro CHECK (((sourcepackagename IS NULL) OR (distribution IS NOT NULL)))
-);
+COMMENT ON COLUMN public.ocirecipejob.job IS 'A reference to a Job row that has all the common job details.';
 
 
-COMMENT ON TABLE public.oauthrequesttoken IS 'A request token which, once authorized by the user, is exchanged for an access token.';
+COMMENT ON COLUMN public.ocirecipejob.recipe IS 'The OCI recipe that this job is for.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.consumer IS 'The consumer which is going to access the protected resources.';
+COMMENT ON COLUMN public.ocirecipejob.job_type IS 'The type of a job, such as a build request.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.person IS 'The person who authorized this token.';
+COMMENT ON COLUMN public.ocirecipejob.json_data IS 'Data that is specific to a particular job type.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.permission IS 'The permission given by the
-person to the consumer.';
+CREATE TABLE public.ocirecipesubscription (
+    id integer NOT NULL,
+    recipe integer NOT NULL,
+    person integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    subscribed_by integer NOT NULL
+);
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.date_expires IS 'When the authorization is to expire.';
+COMMENT ON TABLE public.ocirecipesubscription IS 'Person subscription for OCI recipe.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.date_created IS 'The date/time in which the token was created.';
+COMMENT ON COLUMN public.ocirecipesubscription.recipe IS 'The OCI recipe to which the person subscribed.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.date_reviewed IS 'When the authorization request was authorized or rejected by the person.';
+COMMENT ON COLUMN public.ocirecipesubscription.person IS 'The person who subscribed to the OCI recipe.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.key IS 'This token''s unique key.';
+COMMENT ON COLUMN public.ocirecipesubscription.date_created IS 'When the subscription was created.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.secret IS 'The secret used by the consumer (together with the token''s key) to get an access token once the user has authorized its use.';
+COMMENT ON COLUMN public.ocirecipesubscription.subscribed_by IS 'The person performing the action of subscribing someone to the OCI recipe.';
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.product IS 'The product associated with this token.';
+CREATE SEQUENCE public.ocirecipesubscription_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.project IS 'The project associated with this token.';
+ALTER SEQUENCE public.ocirecipesubscription_id_seq OWNED BY public.ocirecipesubscription.id;
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.distribution IS 'The distribution associated with this token.';
+CREATE TABLE public.ociregistrycredentials (
+    id integer NOT NULL,
+    owner integer NOT NULL,
+    url text NOT NULL,
+    credentials jsonb NOT NULL
+);
 
 
-COMMENT ON COLUMN public.oauthrequesttoken.sourcepackagename IS 'The sourcepackagename associated with this token.';
+COMMENT ON TABLE public.ociregistrycredentials IS 'Credentials for pushing to an OCI registry.';
 
 
-CREATE SEQUENCE public.oauthrequesttoken_id_seq
+COMMENT ON COLUMN public.ociregistrycredentials.owner IS 'The owner of these credentials.  Only the owner is entitled to create push rules using them.';
+
+
+COMMENT ON COLUMN public.ociregistrycredentials.url IS 'The registry URL.';
+
+
+COMMENT ON COLUMN public.ociregistrycredentials.credentials IS 'Encrypted credentials for pushing to the registry.';
+
+
+CREATE SEQUENCE public.ociregistrycredentials_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -10739,7 +12044,7 @@ CREATE SEQUENCE public.oauthrequesttoken_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.oauthrequesttoken_id_seq OWNED BY public.oauthrequesttoken.id;
+ALTER SEQUENCE public.ociregistrycredentials_id_seq OWNED BY public.ociregistrycredentials.id;
 
 
 CREATE TABLE public.officialbugtag (
@@ -11094,7 +12399,6 @@ CREATE TABLE public.packageupload (
     pocket integer NOT NULL,
     changesfile integer,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
-    signing_key integer,
     archive integer NOT NULL,
     package_copy_job integer,
     searchable_names text NOT NULL,
@@ -11194,6 +12498,29 @@ CREATE SEQUENCE public.packageuploadcustom_id_seq
 ALTER SEQUENCE public.packageuploadcustom_id_seq OWNED BY public.packageuploadcustom.id;
 
 
+CREATE TABLE public.packageuploadlog (
+    id integer NOT NULL,
+    package_upload integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    reviewer integer NOT NULL,
+    old_status integer NOT NULL,
+    new_status integer NOT NULL,
+    comment text
+);
+
+
+CREATE SEQUENCE public.packageuploadlog_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.packageuploadlog_id_seq OWNED BY public.packageuploadlog.id;
+
+
 CREATE TABLE public.packageuploadsource (
     id integer NOT NULL,
     packageupload integer NOT NULL,
@@ -11299,7 +12626,7 @@ CREATE TABLE public.packagingjob (
     sourcepackagename integer,
     distroseries integer,
     potemplate integer,
-    CONSTRAINT translationtemplatejob_valid_link CHECK ((((((potemplate IS NOT NULL) AND (productseries IS NULL)) AND (distroseries IS NULL)) AND (sourcepackagename IS NULL)) OR ((((potemplate IS NULL) AND (productseries IS NOT NULL)) AND (distroseries IS NOT NULL)) AND (sourcepackagename IS NOT NULL))))
+    CONSTRAINT translationtemplatejob_valid_link CHECK ((((potemplate IS NOT NULL) AND (productseries IS NULL) AND (distroseries IS NULL) AND (sourcepackagename IS NULL)) OR ((potemplate IS NULL) AND (productseries IS NOT NULL) AND (distroseries IS NOT NULL) AND (sourcepackagename IS NOT NULL))))
 );
 
 
@@ -12981,7 +14308,6 @@ CREATE TABLE public.revision (
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
     log_body text NOT NULL,
     revision_author integer NOT NULL,
-    gpgkey integer,
     revision_id text NOT NULL,
     revision_date timestamp without time zone,
     karma_allocated boolean DEFAULT false,
@@ -13058,19 +14384,102 @@ COMMENT ON COLUMN public.revisioncache.revision_author IS 'A refernce to the rev
 COMMENT ON COLUMN public.revisioncache.revision_date IS 'The date the revision was made.  Should be within 30 days of today (or the cleanup code is not cleaning up).';
 
 
-COMMENT ON COLUMN public.revisioncache.product IS 'The product that the revision is found in (if it is indeed in a particular product).';
+COMMENT ON COLUMN public.revisioncache.product IS 'The product that the revision is found in (if it is indeed in a particular product).';
+
+
+COMMENT ON COLUMN public.revisioncache.distroseries IS 'The distroseries for which a source package branch contains the revision.';
+
+
+COMMENT ON COLUMN public.revisioncache.sourcepackagename IS 'The sourcepackagename for which a source package branch contains the revision.';
+
+
+COMMENT ON COLUMN public.revisioncache.private IS 'True if the revision is only found in private branches, False if it can be found in a non-private branch.';
+
+
+CREATE SEQUENCE public.revisioncache_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.revisioncache_id_seq OWNED BY public.revisioncache.id;
+
+
+CREATE TABLE public.revisionparent (
+    id integer NOT NULL,
+    sequence integer NOT NULL,
+    revision integer NOT NULL,
+    parent_id text NOT NULL
+);
+
+
+CREATE SEQUENCE public.revisionparent_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.revisionparent_id_seq OWNED BY public.revisionparent.id;
+
+
+CREATE TABLE public.revisionproperty (
+    id integer NOT NULL,
+    revision integer NOT NULL,
+    name text NOT NULL,
+    value text NOT NULL
+);
+
+
+COMMENT ON TABLE public.revisionproperty IS 'A collection of name and value pairs that appear on a revision.';
+
+
+COMMENT ON COLUMN public.revisionproperty.revision IS 'The revision which has properties.';
+
+
+COMMENT ON COLUMN public.revisionproperty.name IS 'The name of the property.';
+
+
+COMMENT ON COLUMN public.revisionproperty.value IS 'The value of the property.';
+
+
+CREATE SEQUENCE public.revisionproperty_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.revisionproperty_id_seq OWNED BY public.revisionproperty.id;
+
+
+CREATE TABLE public.revisionstatusartifact (
+    id integer NOT NULL,
+    report integer NOT NULL,
+    type integer NOT NULL,
+    library_file integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL
+);
+
+
+COMMENT ON TABLE public.revisionstatusartifact IS 'An artifact produced by a status check for a code revision.';
 
 
-COMMENT ON COLUMN public.revisioncache.distroseries IS 'The distroseries for which a source package branch contains the revision.';
+COMMENT ON COLUMN public.revisionstatusartifact.report IS 'A link back to the report that the artifact was produced by.';
 
 
-COMMENT ON COLUMN public.revisioncache.sourcepackagename IS 'The sourcepackagename for which a source package branch contains the revision.';
+COMMENT ON COLUMN public.revisionstatusartifact.type IS 'The artifact type produced by the check job.';
 
 
-COMMENT ON COLUMN public.revisioncache.private IS 'True if the revision is only found in private branches, False if it can be found in a non-private branch.';
+COMMENT ON COLUMN public.revisionstatusartifact.library_file IS 'LibraryFileAlias storing the contents of the artifact.';
 
 
-CREATE SEQUENCE public.revisioncache_id_seq
+CREATE SEQUENCE public.revisionstatusartifact_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -13078,49 +14487,63 @@ CREATE SEQUENCE public.revisioncache_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.revisioncache_id_seq OWNED BY public.revisioncache.id;
+ALTER SEQUENCE public.revisionstatusartifact_id_seq OWNED BY public.revisionstatusartifact.id;
 
 
-CREATE TABLE public.revisionparent (
+CREATE TABLE public.revisionstatusreport (
     id integer NOT NULL,
-    sequence integer NOT NULL,
-    revision integer NOT NULL,
-    parent_id text NOT NULL
+    git_repository integer NOT NULL,
+    commit_sha1 character(40) NOT NULL,
+    name text NOT NULL,
+    url text,
+    description text,
+    result integer,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    creator integer NOT NULL,
+    date_started timestamp without time zone,
+    date_finished timestamp without time zone,
+    ci_build integer
 );
 
 
-CREATE SEQUENCE public.revisionparent_id_seq
-    START WITH 1
-    INCREMENT BY 1
-    NO MINVALUE
-    NO MAXVALUE
-    CACHE 1;
+COMMENT ON TABLE public.revisionstatusreport IS 'A status check for a code revision.';
 
 
-ALTER SEQUENCE public.revisionparent_id_seq OWNED BY public.revisionparent.id;
+COMMENT ON COLUMN public.revisionstatusreport.git_repository IS 'The Git repository for this report..';
 
 
-CREATE TABLE public.revisionproperty (
-    id integer NOT NULL,
-    revision integer NOT NULL,
-    name text NOT NULL,
-    value text NOT NULL
-);
+COMMENT ON COLUMN public.revisionstatusreport.commit_sha1 IS 'The commit sha1 for the report.';
 
 
-COMMENT ON TABLE public.revisionproperty IS 'A collection of name and value pairs that appear on a revision.';
+COMMENT ON COLUMN public.revisionstatusreport.name IS 'Name of the report.';
 
 
-COMMENT ON COLUMN public.revisionproperty.revision IS 'The revision which has properties.';
+COMMENT ON COLUMN public.revisionstatusreport.url IS 'External URL to view result of report.';
 
 
-COMMENT ON COLUMN public.revisionproperty.name IS 'The name of the property.';
+COMMENT ON COLUMN public.revisionstatusreport.description IS 'Text description of the result.';
 
 
-COMMENT ON COLUMN public.revisionproperty.value IS 'The value of the property.';
+COMMENT ON COLUMN public.revisionstatusreport.result IS 'The result of the check job for this revision.';
 
 
-CREATE SEQUENCE public.revisionproperty_id_seq
+COMMENT ON COLUMN public.revisionstatusreport.date_created IS 'DateTime that report was created.';
+
+
+COMMENT ON COLUMN public.revisionstatusreport.creator IS 'The person that created the report.';
+
+
+COMMENT ON COLUMN public.revisionstatusreport.date_started IS 'DateTime that report was started.';
+
+
+COMMENT ON COLUMN public.revisionstatusreport.date_finished IS 'DateTime that report was completed.';
+
+
+COMMENT ON COLUMN public.revisionstatusreport.ci_build IS 'The CI build that produced this report.';
+
+
+CREATE SEQUENCE public.revisionstatusreport_id_seq
+    AS integer
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
@@ -13128,7 +14551,7 @@ CREATE SEQUENCE public.revisionproperty_id_seq
     CACHE 1;
 
 
-ALTER SEQUENCE public.revisionproperty_id_seq OWNED BY public.revisionproperty.id;
+ALTER SEQUENCE public.revisionstatusreport_id_seq OWNED BY public.revisionstatusreport.id;
 
 
 CREATE TABLE public.scriptactivity (
@@ -13306,17 +14729,25 @@ ALTER SEQUENCE public.sharingjob_id_seq OWNED BY public.sharingjob.id;
 CREATE TABLE public.signedcodeofconduct (
     id integer NOT NULL,
     owner integer NOT NULL,
-    signingkey integer,
     datecreated timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
     signedcode text,
     recipient integer,
     active boolean DEFAULT false NOT NULL,
     admincomment text,
     signing_key_fingerprint text,
+    affirmed boolean DEFAULT false NOT NULL,
+    version text,
+    CONSTRAINT only_one_method CHECK (((NOT affirmed) OR (signing_key_fingerprint IS NULL))),
     CONSTRAINT valid_signing_key_fingerprint CHECK (((signing_key_fingerprint IS NULL) OR public.valid_fingerprint(signing_key_fingerprint)))
 );
 
 
+COMMENT ON COLUMN public.signedcodeofconduct.affirmed IS 'Code of conduct was affirmed via website interaction.';
+
+
+COMMENT ON COLUMN public.signedcodeofconduct.version IS 'Version of the Code of Conduct that was signed.';
+
+
 CREATE SEQUENCE public.signedcodeofconduct_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -13328,6 +14759,28 @@ CREATE SEQUENCE public.signedcodeofconduct_id_seq
 ALTER SEQUENCE public.signedcodeofconduct_id_seq OWNED BY public.signedcodeofconduct.id;
 
 
+CREATE TABLE public.signingkey (
+    id integer NOT NULL,
+    key_type integer NOT NULL,
+    description text,
+    fingerprint text NOT NULL,
+    public_key bytea NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL
+);
+
+
+CREATE SEQUENCE public.signingkey_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.signingkey_id_seq OWNED BY public.signingkey.id;
+
+
 CREATE TABLE public.snap (
     id integer NOT NULL,
     date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
@@ -13355,6 +14808,10 @@ CREATE TABLE public.snap (
     auto_build_channels text,
     allow_internet boolean DEFAULT true NOT NULL,
     build_source_tarball boolean DEFAULT false NOT NULL,
+    information_type integer,
+    project integer,
+    access_policy integer,
+    access_grants integer[],
     CONSTRAINT consistent_auto_build CHECK (((NOT auto_build) OR ((auto_build_archive IS NOT NULL) AND (auto_build_pocket IS NOT NULL)))),
     CONSTRAINT consistent_git_ref CHECK ((((git_repository IS NULL) AND (git_repository_url IS NULL)) = (git_path IS NULL))),
     CONSTRAINT consistent_store_upload CHECK (((NOT store_upload) OR ((store_series IS NOT NULL) AND (store_name IS NOT NULL)))),
@@ -13394,7 +14851,7 @@ COMMENT ON COLUMN public.snap.git_path IS 'The path of the Git branch containing
 COMMENT ON COLUMN public.snap.require_virtualized IS 'If True, this snap package must be built only on a virtual machine.';
 
 
-COMMENT ON COLUMN public.snap.private IS 'Whether or not this snap is private.';
+COMMENT ON COLUMN public.snap.private IS '(DEPRECATED; use Snap.information_type) Whether or not this snap is private.';
 
 
 COMMENT ON COLUMN public.snap.store_upload IS 'Whether builds of this snap package are automatically uploaded to the store.';
@@ -13436,6 +14893,12 @@ COMMENT ON COLUMN public.snap.allow_internet IS 'If True, builds of this snap ma
 COMMENT ON COLUMN public.snap.build_source_tarball IS 'If true, builds of this snap should also build a tarball containing all source code, including external dependencies.';
 
 
+COMMENT ON COLUMN public.snap.information_type IS 'Enum describing what type of information is stored, such as type of private or security related data, and used to determine to apply an access policy.';
+
+
+COMMENT ON COLUMN public.snap.project IS 'The project which is the pillar for this Snap';
+
+
 CREATE SEQUENCE public.snap_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -13510,6 +14973,21 @@ CREATE SEQUENCE public.snapbase_id_seq
 ALTER SEQUENCE public.snapbase_id_seq OWNED BY public.snapbase.id;
 
 
+CREATE TABLE public.snapbasearch (
+    snap_base integer NOT NULL,
+    processor integer NOT NULL
+);
+
+
+COMMENT ON TABLE public.snapbasearch IS 'The architectures that a snap base supports.';
+
+
+COMMENT ON COLUMN public.snapbasearch.snap_base IS 'The snap base for which a supported architecture is specified.';
+
+
+COMMENT ON COLUMN public.snapbasearch.processor IS 'A supported architecture for this snap base.';
+
+
 CREATE TABLE public.snapbuild (
     id integer NOT NULL,
     requester integer NOT NULL,
@@ -13533,7 +15011,10 @@ CREATE TABLE public.snapbuild (
     revision_id text,
     channels text,
     build_request integer,
-    store_upload_json_data text
+    store_upload_json_data text,
+    snap_base integer,
+    store_upload_revision integer,
+    target_architectures text[]
 );
 
 
@@ -13603,6 +15084,15 @@ COMMENT ON COLUMN public.snapbuild.build_request IS 'The build request that caus
 COMMENT ON COLUMN public.snapbuild.store_upload_json_data IS 'Data that is related to the process of uploading a build to the store.';
 
 
+COMMENT ON COLUMN public.snapbuild.snap_base IS 'The snap base to use for this build.';
+
+
+COMMENT ON COLUMN public.snapbuild.store_upload_revision IS 'The revision number assigned to this build on the last store upload.';
+
+
+COMMENT ON COLUMN public.snapbuild.target_architectures IS 'A list of target architectures for a snap build.';
+
+
 CREATE SEQUENCE public.snapbuild_id_seq
     START WITH 1
     INCREMENT BY 1
@@ -13757,6 +15247,42 @@ CREATE SEQUENCE public.snappyseries_id_seq
 ALTER SEQUENCE public.snappyseries_id_seq OWNED BY public.snappyseries.id;
 
 
+CREATE TABLE public.snapsubscription (
+    id integer NOT NULL,
+    snap integer NOT NULL,
+    person integer NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    subscribed_by integer NOT NULL
+);
+
+
+COMMENT ON TABLE public.snapsubscription IS 'Person subscription for Snap recipes.';
+
+
+COMMENT ON COLUMN public.snapsubscription.snap IS 'The Snap recipe to which the person subscribed.';
+
+
+COMMENT ON COLUMN public.snapsubscription.person IS 'The person who subscribed to the Snap.';
+
+
+COMMENT ON COLUMN public.snapsubscription.date_created IS 'When the subscription was created.';
+
+
+COMMENT ON COLUMN public.snapsubscription.subscribed_by IS 'The person performing the action of subscribing someone to the Snap.';
+
+
+CREATE SEQUENCE public.snapsubscription_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.snapsubscription_id_seq OWNED BY public.snapsubscription.id;
+
+
 CREATE TABLE public.sourcepackageformatselection (
     id integer NOT NULL,
     distroseries integer NOT NULL,
@@ -13800,8 +15326,8 @@ CREATE TABLE public.sourcepackagepublishinghistory (
     sourcepackagerelease integer NOT NULL,
     distroseries integer NOT NULL,
     status integer NOT NULL,
-    component integer NOT NULL,
-    section integer NOT NULL,
+    component integer,
+    section integer,
     datecreated timestamp without time zone NOT NULL,
     datepublished timestamp without time zone,
     datesuperseded timestamp without time zone,
@@ -13817,7 +15343,12 @@ CREATE TABLE public.sourcepackagepublishinghistory (
     sourcepackagename integer NOT NULL,
     creator integer,
     sponsor integer,
-    packageupload integer
+    packageupload integer,
+    copied_from_archive integer,
+    format integer,
+    channel jsonb,
+    CONSTRAINT debian_columns CHECK (((COALESCE(format, 1) <> 1) OR ((component IS NOT NULL) AND (section IS NOT NULL)))),
+    CONSTRAINT no_debian_channel CHECK (((COALESCE(format, 1) <> 1) OR (channel IS NULL)))
 );
 
 
@@ -14051,7 +15582,7 @@ CREATE TABLE public.sourcepackagerecipedatainstruction (
     source_directory text,
     git_repository integer,
     CONSTRAINT one_vcs CHECK (((branch IS NOT NULL) <> (git_repository IS NOT NULL))),
-    CONSTRAINT sourcepackagerecipedatainstruction__directory_not_null CHECK ((((type = 3) OR ((type = 1) AND (directory IS NULL))) OR ((type = 2) AND (directory IS NOT NULL)))),
+    CONSTRAINT sourcepackagerecipedatainstruction__directory_not_null CHECK (((type = 3) OR ((type = 1) AND (directory IS NULL)) OR ((type = 2) AND (directory IS NOT NULL)))),
     CONSTRAINT sourcepackagerecipedatainstruction__source_directory_null CHECK ((((type = ANY (ARRAY[1, 2])) AND (source_directory IS NULL)) OR ((type = 3) AND (source_directory IS NOT NULL))))
 );
 
@@ -14135,22 +15666,21 @@ CREATE TABLE public.sourcepackagerelease (
     creator integer NOT NULL,
     version public.debversion NOT NULL,
     dateuploaded timestamp without time zone DEFAULT timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) NOT NULL,
-    urgency integer NOT NULL,
-    dscsigningkey integer,
-    component integer NOT NULL,
+    urgency integer,
+    component integer,
     changelog_entry text,
     builddepends text,
     builddependsindep text,
     architecturehintlist text NOT NULL,
     dsc text,
-    section integer NOT NULL,
-    maintainer integer NOT NULL,
+    section integer,
+    maintainer integer,
     sourcepackagename integer NOT NULL,
     upload_distroseries integer NOT NULL,
     format integer NOT NULL,
     dsc_maintainer_rfc822 text,
     dsc_standards_version text,
-    dsc_format text NOT NULL,
+    dsc_format text,
     dsc_binaries text,
     upload_archive integer,
     copyright text,
@@ -14163,6 +15693,9 @@ CREATE TABLE public.sourcepackagerelease (
     signing_key_owner integer,
     signing_key_fingerprint text,
     buildinfo integer,
+    ci_build integer,
+    CONSTRAINT at_most_one_build CHECK ((public.null_count(ARRAY[sourcepackage_recipe_build, ci_build]) >= 1)),
+    CONSTRAINT debian_columns CHECK (((format <> 1) OR ((component IS NOT NULL) AND (section IS NOT NULL) AND (urgency IS NOT NULL) AND (dsc_format IS NOT NULL)))),
     CONSTRAINT valid_signing_key_fingerprint CHECK (((signing_key_fingerprint IS NULL) OR public.valid_fingerprint(signing_key_fingerprint))),
     CONSTRAINT valid_version CHECK (public.valid_debian_version((version)::text))
 );
@@ -14200,12 +15733,6 @@ used for "testing" systems or security work in the future. The "urgency" is
 set by the uploader, in the DSC file.';
 
 
-COMMENT ON COLUMN public.sourcepackagerelease.dscsigningkey IS 'The GPG key used to
-sign the DSC. This is not necessarily the maintainer''s key, or the
-creator''s key. For example, it''s possible to produce a package, then ask a
-sponsor to upload it.';
-
-
 COMMENT ON COLUMN public.sourcepackagerelease.component IS 'The component in which
 this sourcepackagerelease is intended (by the uploader) to reside. E.g.
 main, universe, restricted. Note that the distribution managers will often
@@ -14375,7 +15902,7 @@ CREATE TABLE public.specification (
     CONSTRAINT product_and_productseries CHECK (((productseries IS NULL) OR (product IS NOT NULL))),
     CONSTRAINT product_xor_distribution CHECK (((product IS NULL) <> (distribution IS NULL))),
     CONSTRAINT specification_completion_fully_recorded_chk CHECK (((date_completed IS NULL) = (completer IS NULL))),
-    CONSTRAINT specification_completion_recorded_chk CHECK (((date_completed IS NULL) <> (((implementation_status = 90) OR (definition_status = ANY (ARRAY[60, 70]))) OR ((implementation_status = 95) AND (definition_status = 10))))),
+    CONSTRAINT specification_completion_recorded_chk CHECK (((date_completed IS NULL) <> ((implementation_status = 90) OR (definition_status = ANY (ARRAY[60, 70])) OR ((implementation_status = 95) AND (definition_status = 10))))),
     CONSTRAINT specification_decision_recorded CHECK (((goalstatus = 30) OR ((goal_decider IS NOT NULL) AND (date_goal_decided IS NOT NULL)))),
     CONSTRAINT specification_goal_nomination_chk CHECK ((((productseries IS NULL) AND (distroseries IS NULL)) OR ((goal_proposer IS NOT NULL) AND (date_goal_proposed IS NOT NULL)))),
     CONSTRAINT specification_not_self_superseding CHECK ((superseded_by <> id)),
@@ -15420,7 +16947,7 @@ CREATE VIEW public.validpersoncache AS
    FROM public.emailaddress,
     public.person,
     public.account
-  WHERE ((((emailaddress.person = person.id) AND (person.account = account.id)) AND (emailaddress.status = 4)) AND (account.status = 20));
+  WHERE ((emailaddress.person = person.id) AND (person.account = account.id) AND (emailaddress.status = 4) AND (account.status = 20));
 
 
 COMMENT ON VIEW public.validpersoncache IS 'A materialized view listing the Person.ids of all valid people (but not teams).';
@@ -15431,7 +16958,7 @@ CREATE VIEW public.validpersonorteamcache AS
    FROM ((public.person
      LEFT JOIN public.emailaddress ON ((person.id = emailaddress.person)))
      LEFT JOIN public.account ON ((person.account = account.id)))
-  WHERE (((person.teamowner IS NOT NULL) AND (person.merged IS NULL)) OR (((person.teamowner IS NULL) AND (account.status = 20)) AND (emailaddress.status = 4)));
+  WHERE (((person.teamowner IS NOT NULL) AND (person.merged IS NULL)) OR ((person.teamowner IS NULL) AND (account.status = 20) AND (emailaddress.status = 4)));
 
 
 CREATE TABLE public.vote (
@@ -15500,6 +17027,118 @@ CREATE SEQUENCE public.votecast_id_seq
 ALTER SEQUENCE public.votecast_id_seq OWNED BY public.votecast.id;
 
 
+CREATE TABLE public.vulnerability (
+    id integer NOT NULL,
+    distribution integer NOT NULL,
+    cve integer,
+    status integer NOT NULL,
+    description text,
+    notes text,
+    mitigation text,
+    importance integer NOT NULL,
+    importance_explanation text,
+    information_type integer DEFAULT 1 NOT NULL,
+    date_created timestamp without time zone DEFAULT timezone('UTC'::text, CURRENT_TIMESTAMP) NOT NULL,
+    creator integer NOT NULL,
+    date_made_public timestamp without time zone
+);
+
+
+COMMENT ON TABLE public.vulnerability IS 'Expresses the notion of whether a CVE affects a distribution.';
+
+
+COMMENT ON COLUMN public.vulnerability.distribution IS 'The distribution affected by this vulnerability.';
+
+
+COMMENT ON COLUMN public.vulnerability.cve IS 'The external CVE reference corresponding to this vulnerability, if any.';
+
+
+COMMENT ON COLUMN public.vulnerability.status IS 'Indicates current status of the vulnerability.';
+
+
+COMMENT ON COLUMN public.vulnerability.description IS 'Overrides the Cve.description.';
+
+
+COMMENT ON COLUMN public.vulnerability.notes IS 'Free-form notes.';
+
+
+COMMENT ON COLUMN public.vulnerability.mitigation IS 'Explain why we''re ignoring something.';
+
+
+COMMENT ON COLUMN public.vulnerability.importance IS 'Indicates work priority, not severity.';
+
+
+COMMENT ON COLUMN public.vulnerability.importance_explanation IS 'Used to explain why our importance differs from somebody else''s CVSS score.';
+
+
+COMMENT ON COLUMN public.vulnerability.information_type IS 'Indicates privacy of the vulnerability.';
+
+
+COMMENT ON COLUMN public.vulnerability.date_created IS 'The date when the vulnerability was created.';
+
+
+COMMENT ON COLUMN public.vulnerability.creator IS 'The person that created the vulnerability.';
+
+
+COMMENT ON COLUMN public.vulnerability.date_made_public IS 'The date this vulnerability was made public.';
+
+
+CREATE SEQUENCE public.vulnerability_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.vulnerability_id_seq OWNED BY public.vulnerability.id;
+
+
+CREATE TABLE public.vulnerabilityactivity (
+    id integer NOT NULL,
+    vulnerability integer NOT NULL,
+    changer integer NOT NULL,
+    date_changed timestamp without time zone NOT NULL,
+    what_changed integer NOT NULL,
+    old_value text,
+    new_value text
+);
+
+
+COMMENT ON TABLE public.vulnerabilityactivity IS 'Tracks changes to vulnerability rows.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.vulnerability IS 'The vulnerability that the changes refer to.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.changer IS 'The person that made the changes.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.date_changed IS 'The date when the vulnerability details last changed.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.what_changed IS 'Indicates what field changed for the vulnerability by means of an enum.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.old_value IS 'The value prior to the change.';
+
+
+COMMENT ON COLUMN public.vulnerabilityactivity.new_value IS 'The current value.';
+
+
+CREATE SEQUENCE public.vulnerabilityactivity_id_seq
+    AS integer
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+
+ALTER SEQUENCE public.vulnerabilityactivity_id_seq OWNED BY public.vulnerabilityactivity.id;
+
+
 CREATE TABLE public.webhook (
     id integer NOT NULL,
     registrant integer NOT NULL,
@@ -15512,7 +17151,10 @@ CREATE TABLE public.webhook (
     git_repository integer,
     branch integer,
     snap integer,
-    CONSTRAINT one_target CHECK ((public.null_count(ARRAY[git_repository, branch, snap]) = 2))
+    livefs integer,
+    oci_recipe integer,
+    charm_recipe integer,
+    CONSTRAINT one_target CHECK ((public.null_count(ARRAY[git_repository, branch, snap, livefs, oci_recipe, charm_recipe]) = 5))
 );
 
 
@@ -15576,6 +17218,9 @@ ALTER TABLE ONLY public.accesspolicy ALTER COLUMN id SET DEFAULT nextval('public
 ALTER TABLE ONLY public.accesspolicygrantflat ALTER COLUMN id SET DEFAULT nextval('public.accesspolicygrantflat_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.accesstoken ALTER COLUMN id SET DEFAULT nextval('public.accesstoken_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.account ALTER COLUMN id SET DEFAULT nextval('public.account_id_seq'::regclass);
 
 
@@ -15609,6 +17254,9 @@ ALTER TABLE ONLY public.archivejob ALTER COLUMN id SET DEFAULT nextval('public.a
 ALTER TABLE ONLY public.archivepermission ALTER COLUMN id SET DEFAULT nextval('public.archivepermission_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.archivesigningkey ALTER COLUMN id SET DEFAULT nextval('public.archivesigningkey_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.archivesubscriber ALTER COLUMN id SET DEFAULT nextval('public.archivesubscriber_id_seq'::regclass);
 
 
@@ -15627,6 +17275,9 @@ ALTER TABLE ONLY public.binarypackagerelease ALTER COLUMN id SET DEFAULT nextval
 ALTER TABLE ONLY public.binarypackagereleasedownloadcount ALTER COLUMN id SET DEFAULT nextval('public.binarypackagereleasedownloadcount_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.binarysourcereference ALTER COLUMN id SET DEFAULT nextval('public.binarysourcereference_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.branch ALTER COLUMN id SET DEFAULT nextval('public.branch_id_seq'::regclass);
 
 
@@ -15723,6 +17374,21 @@ ALTER TABLE ONLY public.buildfarmjob ALTER COLUMN id SET DEFAULT nextval('public
 ALTER TABLE ONLY public.buildqueue ALTER COLUMN id SET DEFAULT nextval('public.buildqueue_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.charmbase ALTER COLUMN id SET DEFAULT nextval('public.charmbase_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.charmfile ALTER COLUMN id SET DEFAULT nextval('public.charmfile_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.charmrecipe ALTER COLUMN id SET DEFAULT nextval('public.charmrecipe_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.charmrecipebuild ALTER COLUMN id SET DEFAULT nextval('public.charmrecipebuild_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.cibuild ALTER COLUMN id SET DEFAULT nextval('public.cibuild_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.codeimport ALTER COLUMN id SET DEFAULT nextval('public.codeimport_id_seq'::regclass);
 
 
@@ -15792,6 +17458,9 @@ ALTER TABLE ONLY public.distributionsourcepackagecache ALTER COLUMN id SET DEFAU
 ALTER TABLE ONLY public.distroarchseries ALTER COLUMN id SET DEFAULT nextval('public.distroarchseries_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.distroarchseriesfilter ALTER COLUMN id SET DEFAULT nextval('public.distroarchseriesfilter_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.distroseries ALTER COLUMN id SET DEFAULT nextval('public.distroseries_id_seq'::regclass);
 
 
@@ -15981,6 +17650,12 @@ ALTER TABLE ONLY public.messageapproval ALTER COLUMN id SET DEFAULT nextval('pub
 ALTER TABLE ONLY public.messagechunk ALTER COLUMN id SET DEFAULT nextval('public.messagechunk_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.messagerevision ALTER COLUMN id SET DEFAULT nextval('public.messagerevision_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.messagerevisionchunk ALTER COLUMN id SET DEFAULT nextval('public.messagerevisionchunk_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.milestone ALTER COLUMN id SET DEFAULT nextval('public.milestone_id_seq'::regclass);
 
 
@@ -16011,6 +17686,33 @@ ALTER TABLE ONLY public.oauthconsumer ALTER COLUMN id SET DEFAULT nextval('publi
 ALTER TABLE ONLY public.oauthrequesttoken ALTER COLUMN id SET DEFAULT nextval('public.oauthrequesttoken_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.ocifile ALTER COLUMN id SET DEFAULT nextval('public.ocifile_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ociproject ALTER COLUMN id SET DEFAULT nextval('public.ociproject_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ociprojectname ALTER COLUMN id SET DEFAULT nextval('public.ociprojectname_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ociprojectseries ALTER COLUMN id SET DEFAULT nextval('public.ociprojectseries_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ocipushrule ALTER COLUMN id SET DEFAULT nextval('public.ocipushrule_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ocirecipe ALTER COLUMN id SET DEFAULT nextval('public.ocirecipe_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ocirecipebuild ALTER COLUMN id SET DEFAULT nextval('public.ocirecipebuild_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ocirecipesubscription ALTER COLUMN id SET DEFAULT nextval('public.ocirecipesubscription_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.ociregistrycredentials ALTER COLUMN id SET DEFAULT nextval('public.ociregistrycredentials_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.officialbugtag ALTER COLUMN id SET DEFAULT nextval('public.officialbugtag_id_seq'::regclass);
 
 
@@ -16044,6 +17746,9 @@ ALTER TABLE ONLY public.packageuploadbuild ALTER COLUMN id SET DEFAULT nextval('
 ALTER TABLE ONLY public.packageuploadcustom ALTER COLUMN id SET DEFAULT nextval('public.packageuploadcustom_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.packageuploadlog ALTER COLUMN id SET DEFAULT nextval('public.packageuploadlog_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.packageuploadsource ALTER COLUMN id SET DEFAULT nextval('public.packageuploadsource_id_seq'::regclass);
 
 
@@ -16158,6 +17863,12 @@ ALTER TABLE ONLY public.revisionparent ALTER COLUMN id SET DEFAULT nextval('publ
 ALTER TABLE ONLY public.revisionproperty ALTER COLUMN id SET DEFAULT nextval('public.revisionproperty_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.revisionstatusartifact ALTER COLUMN id SET DEFAULT nextval('public.revisionstatusartifact_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.revisionstatusreport ALTER COLUMN id SET DEFAULT nextval('public.revisionstatusreport_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.scriptactivity ALTER COLUMN id SET DEFAULT nextval('public.scriptactivity_id_seq'::regclass);
 
 
@@ -16176,6 +17887,9 @@ ALTER TABLE ONLY public.sharingjob ALTER COLUMN id SET DEFAULT nextval('public.s
 ALTER TABLE ONLY public.signedcodeofconduct ALTER COLUMN id SET DEFAULT nextval('public.signedcodeofconduct_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.signingkey ALTER COLUMN id SET DEFAULT nextval('public.signingkey_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.snap ALTER COLUMN id SET DEFAULT nextval('public.snap_id_seq'::regclass);
 
 
@@ -16194,6 +17908,9 @@ ALTER TABLE ONLY public.snappydistroseries ALTER COLUMN id SET DEFAULT nextval('
 ALTER TABLE ONLY public.snappyseries ALTER COLUMN id SET DEFAULT nextval('public.snappyseries_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.snapsubscription ALTER COLUMN id SET DEFAULT nextval('public.snapsubscription_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.sourcepackageformatselection ALTER COLUMN id SET DEFAULT nextval('public.sourcepackageformatselection_id_seq'::regclass);
 
 
@@ -16293,6 +18010,12 @@ ALTER TABLE ONLY public.vote ALTER COLUMN id SET DEFAULT nextval('public.vote_id
 ALTER TABLE ONLY public.votecast ALTER COLUMN id SET DEFAULT nextval('public.votecast_id_seq'::regclass);
 
 
+ALTER TABLE ONLY public.vulnerability ALTER COLUMN id SET DEFAULT nextval('public.vulnerability_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.vulnerabilityactivity ALTER COLUMN id SET DEFAULT nextval('public.vulnerabilityactivity_id_seq'::regclass);
+
+
 ALTER TABLE ONLY public.webhook ALTER COLUMN id SET DEFAULT nextval('public.webhook_id_seq'::regclass);
 
 
@@ -16323,6 +18046,10 @@ ALTER TABLE ONLY public.accesspolicygrantflat
     ADD CONSTRAINT accesspolicygrantflat_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.accesstoken
+    ADD CONSTRAINT accesstoken_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.account
     ADD CONSTRAINT account_pkey PRIMARY KEY (id);
 
@@ -16385,6 +18112,14 @@ ALTER TABLE ONLY public.archivepermission
     ADD CONSTRAINT archivepermission_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.archivesigningkey
+    ADD CONSTRAINT archivesigningkey__archive__key_type__earliest_distro_series__k UNIQUE (archive, key_type, earliest_distro_series);
+
+
+ALTER TABLE ONLY public.archivesigningkey
+    ADD CONSTRAINT archivesigningkey_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.archivesubscriber
     ADD CONSTRAINT archivesubscriber_pkey PRIMARY KEY (id);
 
@@ -16417,14 +18152,6 @@ ALTER TABLE ONLY public.binarypackagename
     ADD CONSTRAINT binarypackagename_pkey PRIMARY KEY (id);
 
 
-ALTER TABLE ONLY public.binarypackagerelease
-    ADD CONSTRAINT binarypackagerelease_binarypackagename_key UNIQUE (binarypackagename, build, version);
-
-
-ALTER TABLE ONLY public.binarypackagerelease
-    ADD CONSTRAINT binarypackagerelease_build_name_uniq UNIQUE (build, binarypackagename);
-
-
 ALTER TABLE ONLY public.binarypackagereleasedownloadcount
     ADD CONSTRAINT binarypackagereleasedownloadcount__archive__binary_package_rele UNIQUE (archive, binary_package_release, day, country);
 
@@ -16433,6 +18160,10 @@ ALTER TABLE ONLY public.binarypackagereleasedownloadcount
     ADD CONSTRAINT binarypackagereleasedownloadcount_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.binarysourcereference
+    ADD CONSTRAINT binarysourcereference_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.branch
     ADD CONSTRAINT branch__unique_name__key UNIQUE (unique_name);
 
@@ -16687,6 +18418,38 @@ ALTER TABLE ONLY public.revision
     ADD CONSTRAINT changeset_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.charmbase
+    ADD CONSTRAINT charmbase_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.charmbasearch
+    ADD CONSTRAINT charmbasearch_pkey PRIMARY KEY (charm_base, processor);
+
+
+ALTER TABLE ONLY public.charmfile
+    ADD CONSTRAINT charmfile_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.charmrecipe
+    ADD CONSTRAINT charmrecipe_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.charmrecipebuild
+    ADD CONSTRAINT charmrecipebuild_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.charmrecipebuildjob
+    ADD CONSTRAINT charmrecipebuildjob_pkey PRIMARY KEY (job);
+
+
+ALTER TABLE ONLY public.charmrecipejob
+    ADD CONSTRAINT charmrecipejob_pkey PRIMARY KEY (job);
+
+
+ALTER TABLE ONLY public.cibuild
+    ADD CONSTRAINT cibuild_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.codeimport
     ADD CONSTRAINT codeimport_pkey PRIMARY KEY (id);
 
@@ -16862,6 +18625,10 @@ ALTER TABLE ONLY public.distributionmirror
 
 
 ALTER TABLE ONLY public.distributionmirror
+    ADD CONSTRAINT distributionmirror_https_base_url_key UNIQUE (https_base_url);
+
+
+ALTER TABLE ONLY public.distributionmirror
     ADD CONSTRAINT distributionmirror_name_key UNIQUE (name);
 
 
@@ -16903,6 +18670,14 @@ ALTER TABLE ONLY public.distroarchseries
     ADD CONSTRAINT distroarchseries__processor__distroseries__key UNIQUE (processor, distroseries);
 
 
+ALTER TABLE ONLY public.distroarchseriesfilter
+    ADD CONSTRAINT distroarchseriesfilter__distroarchseries__key UNIQUE (distroarchseries);
+
+
+ALTER TABLE ONLY public.distroarchseriesfilter
+    ADD CONSTRAINT distroarchseriesfilter_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.distroseries
     ADD CONSTRAINT distrorelease__distribution__name__key UNIQUE (distribution, name);
 
@@ -17397,6 +19172,14 @@ ALTER TABLE ONLY public.messagechunk
     ADD CONSTRAINT messagechunk_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.messagerevision
+    ADD CONSTRAINT messagerevision_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.messagerevisionchunk
+    ADD CONSTRAINT messagerevisionchunk_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.milestone
     ADD CONSTRAINT milestone_distribution_id_key UNIQUE (distribution, id);
 
@@ -17479,6 +19262,54 @@ ALTER TABLE ONLY public.oauthrequesttoken
     ADD CONSTRAINT oauthrequesttoken_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.ocifile
+    ADD CONSTRAINT ocifile_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ociproject
+    ADD CONSTRAINT ociproject_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ociprojectname
+    ADD CONSTRAINT ociprojectname_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ociprojectseries
+    ADD CONSTRAINT ociprojectseries_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ocipushrule
+    ADD CONSTRAINT ocipushrule_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ocirecipe
+    ADD CONSTRAINT ocirecipe_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ocirecipearch
+    ADD CONSTRAINT ocirecipearch_pkey PRIMARY KEY (recipe, processor);
+
+
+ALTER TABLE ONLY public.ocirecipebuild
+    ADD CONSTRAINT ocirecipebuild_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ocirecipebuildjob
+    ADD CONSTRAINT ocirecipebuildjob_pkey PRIMARY KEY (job);
+
+
+ALTER TABLE ONLY public.ocirecipejob
+    ADD CONSTRAINT ocirecipejob_pkey PRIMARY KEY (job);
+
+
+ALTER TABLE ONLY public.ocirecipesubscription
+    ADD CONSTRAINT ocirecipesubscription_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.ociregistrycredentials
+    ADD CONSTRAINT ociregistrycredentials_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.officialbugtag
     ADD CONSTRAINT officialbugtag_pkey PRIMARY KEY (id);
 
@@ -17543,6 +19374,10 @@ ALTER TABLE ONLY public.packagesetsources
     ADD CONSTRAINT packagesetsources_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.packageuploadlog
+    ADD CONSTRAINT packageuploadlog_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.packageuploadsource
     ADD CONSTRAINT packageuploadsource__packageupload__key UNIQUE (packageupload);
 
@@ -17809,6 +19644,14 @@ ALTER TABLE ONLY public.revisionproperty
     ADD CONSTRAINT revisionproperty_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.revisionstatusartifact
+    ADD CONSTRAINT revisionstatusartifact_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.revisionstatusreport
+    ADD CONSTRAINT revisionstatusreport_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.scriptactivity
     ADD CONSTRAINT scriptactivity_pkey PRIMARY KEY (id);
 
@@ -17845,6 +19688,18 @@ ALTER TABLE ONLY public.signedcodeofconduct
     ADD CONSTRAINT signedcodeofconduct_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.signingkey
+    ADD CONSTRAINT signingkey__id__key_type__key UNIQUE (id, key_type);
+
+
+ALTER TABLE ONLY public.signingkey
+    ADD CONSTRAINT signingkey__key_type__fingerprint__key UNIQUE (key_type, fingerprint);
+
+
+ALTER TABLE ONLY public.signingkey
+    ADD CONSTRAINT signingkey_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.snap
     ADD CONSTRAINT snap__owner__name__key UNIQUE (owner, name);
 
@@ -17861,6 +19716,10 @@ ALTER TABLE ONLY public.snapbase
     ADD CONSTRAINT snapbase_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.snapbasearch
+    ADD CONSTRAINT snapbasearch_pkey PRIMARY KEY (snap_base, processor);
+
+
 ALTER TABLE ONLY public.snapbuild
     ADD CONSTRAINT snapbuild_pkey PRIMARY KEY (id);
 
@@ -17885,6 +19744,10 @@ ALTER TABLE ONLY public.snappyseries
     ADD CONSTRAINT snappyseries_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.snapsubscription
+    ADD CONSTRAINT snapsubscription_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.sourcepackageformatselection
     ADD CONSTRAINT sourceformatselection__distroseries__format__key UNIQUE (distroseries, format);
 
@@ -18159,6 +20022,14 @@ ALTER TABLE ONLY public.votecast
     ADD CONSTRAINT votecast_pkey PRIMARY KEY (id);
 
 
+ALTER TABLE ONLY public.vulnerability
+    ADD CONSTRAINT vulnerability_pkey PRIMARY KEY (id);
+
+
+ALTER TABLE ONLY public.vulnerabilityactivity
+    ADD CONSTRAINT vulnerabilityactivity_pkey PRIMARY KEY (id);
+
+
 ALTER TABLE ONLY public.webhook
     ADD CONSTRAINT webhook_pkey PRIMARY KEY (id);
 
@@ -18188,6 +20059,12 @@ CREATE UNIQUE INDEX accessartifact__bug__key ON public.accessartifact USING btre
 CREATE UNIQUE INDEX accessartifact__gitrepository__key ON public.accessartifact USING btree (gitrepository) WHERE (gitrepository IS NOT NULL);
 
 
+CREATE UNIQUE INDEX accessartifact__ocirecipe__key ON public.accessartifact USING btree (ocirecipe) WHERE (ocirecipe IS NOT NULL);
+
+
+CREATE UNIQUE INDEX accessartifact__snap__key ON public.accessartifact USING btree (snap) WHERE (snap IS NOT NULL);
+
+
 CREATE UNIQUE INDEX accessartifact__specification__key ON public.accessartifact USING btree (specification) WHERE (specification IS NOT NULL);
 
 
@@ -18227,6 +20104,21 @@ CREATE UNIQUE INDEX accesspolicygrantflat__policy__grantee__artifact__key ON pub
 CREATE UNIQUE INDEX accesspolicygrantflat__policy__grantee__key ON public.accesspolicygrantflat USING btree (policy, grantee) WHERE (artifact IS NULL);
 
 
+CREATE INDEX accesstoken__date_expires__idx ON public.accesstoken USING btree (date_expires) WHERE (date_expires IS NOT NULL);
+
+
+CREATE INDEX accesstoken__git_repository__idx ON public.accesstoken USING btree (git_repository);
+
+
+CREATE INDEX accesstoken__owner__idx ON public.accesstoken USING btree (owner);
+
+
+CREATE INDEX accesstoken__revoked_by__idx ON public.accesstoken USING btree (revoked_by);
+
+
+CREATE UNIQUE INDEX accesstoken__token_sha256__key ON public.accesstoken USING btree (token_sha256);
+
+
 CREATE INDEX announcement__distribution__active__idx ON public.announcement USING btree (distribution, active) WHERE (distribution IS NOT NULL);
 
 
@@ -18293,6 +20185,9 @@ CREATE INDEX archivedependency__archive__idx ON public.archivedependency USING b
 CREATE INDEX archivedependency__dependency__idx ON public.archivedependency USING btree (dependency);
 
 
+CREATE INDEX archivedependency__snap_base__idx ON public.archivedependency USING btree (snap_base);
+
+
 CREATE INDEX archivefile__archive__container__idx ON public.archivefile USING btree (archive, container);
 
 
@@ -18410,6 +20305,9 @@ CREATE INDEX binarypackagename__name__trgm ON public.binarypackagename USING gin
 CREATE INDEX binarypackagepublishinghistory__archive__bpn__status__idx ON public.binarypackagepublishinghistory USING btree (archive, binarypackagename, status);
 
 
+CREATE INDEX binarypackagepublishinghistory__archive__bpr__idx ON public.binarypackagepublishinghistory USING btree (archive, binarypackagerelease);
+
+
 CREATE INDEX binarypackagepublishinghistory__archive__bpr__status__idx ON public.binarypackagepublishinghistory USING btree (archive, binarypackagerelease, status);
 
 
@@ -18422,18 +20320,36 @@ CREATE INDEX binarypackagepublishinghistory__archive__datecreated__id__idx ON pu
 CREATE INDEX binarypackagepublishinghistory__archive__distroarchseries__stat ON public.binarypackagepublishinghistory USING btree (archive, distroarchseries, status, binarypackagename);
 
 
+CREATE INDEX binarypackagepublishinghistory__archive__status__datepublished_ ON public.binarypackagepublishinghistory USING btree (archive, status) WHERE (datepublished IS NULL);
+
+
 CREATE INDEX binarypackagepublishinghistory__archive__status__scheduleddelet ON public.binarypackagepublishinghistory USING btree (archive, status) WHERE (scheduleddeletiondate IS NULL);
 
 
 CREATE INDEX binarypackagepublishinghistory__binarypackagename__idx ON public.binarypackagepublishinghistory USING btree (binarypackagename);
 
 
+CREATE INDEX binarypackagepublishinghistory__copied_from_archive__idx ON public.binarypackagepublishinghistory USING btree (copied_from_archive) WHERE (copied_from_archive IS NOT NULL);
+
+
+CREATE INDEX binarypackagepublishinghistory__creator__idx ON public.binarypackagepublishinghistory USING btree (creator) WHERE (creator IS NOT NULL);
+
+
 CREATE INDEX binarypackagepublishinghistory__supersededby__idx ON public.binarypackagepublishinghistory USING btree (supersededby);
 
 
 CREATE INDEX binarypackagerelease__binarypackagename__version__idx ON public.binarypackagerelease USING btree (binarypackagename, version);
 
 
+CREATE INDEX binarypackagerelease__binarypackagename__version_text__idx ON public.binarypackagerelease USING btree (binarypackagename, ((version)::text));
+
+
+CREATE UNIQUE INDEX binarypackagerelease__build__bpn__key ON public.binarypackagerelease USING btree (build, binarypackagename) WHERE (build IS NOT NULL);
+
+
+CREATE UNIQUE INDEX binarypackagerelease__ci_build__bpn__format__key ON public.binarypackagerelease USING btree (ci_build, binarypackagename, binpackageformat) WHERE (ci_build IS NOT NULL);
+
+
 CREATE UNIQUE INDEX binarypackagerelease__debug_package__key ON public.binarypackagerelease USING btree (debug_package);
 
 
@@ -18443,6 +20359,18 @@ CREATE INDEX binarypackagerelease_build_idx ON public.binarypackagerelease USING
 CREATE INDEX binarypackagereleasedownloadcount__binary_package_release__idx ON public.binarypackagereleasedownloadcount USING btree (binary_package_release);
 
 
+CREATE INDEX binarypackagereleasedownloadcount__index_only_scan__idx ON public.binarypackagereleasedownloadcount USING btree (archive, binary_package_release, day, country, count);
+
+
+CREATE UNIQUE INDEX binarysourcereference__bpr__spr__type__key ON public.binarysourcereference USING btree (binary_package_release, source_package_release, reference_type);
+
+
+CREATE INDEX binarysourcereference__bpr__type__idx ON public.binarysourcereference USING btree (binary_package_release, reference_type);
+
+
+CREATE INDEX binarysourcereference__spr__type__idx ON public.binarysourcereference USING btree (source_package_release, reference_type);
+
+
 CREATE UNIQUE INDEX branch__ds__spn__owner__name__key ON public.branch USING btree (distroseries, sourcepackagename, owner, name) WHERE (distroseries IS NOT NULL);
 
 
@@ -18490,6 +20418,9 @@ CREATE INDEX branchjob__branch__idx ON public.branchjob USING btree (branch);
 CREATE INDEX branchmergeproposal__dependent_branch__idx ON public.branchmergeproposal USING btree (dependent_branch);
 
 
+CREATE INDEX branchmergeproposal__dependent_git_repository__dependent_git_pa ON public.branchmergeproposal USING btree (dependent_git_repository, dependent_git_path);
+
+
 CREATE INDEX branchmergeproposal__merge_log_file__idx ON public.branchmergeproposal USING btree (merge_log_file);
 
 
@@ -18511,12 +20442,18 @@ CREATE INDEX branchmergeproposal__reviewer__idx ON public.branchmergeproposal US
 CREATE INDEX branchmergeproposal__source_branch__idx ON public.branchmergeproposal USING btree (source_branch);
 
 
+CREATE INDEX branchmergeproposal__source_git_repository__source_git_path__id ON public.branchmergeproposal USING btree (source_git_repository, source_git_path);
+
+
 CREATE INDEX branchmergeproposal__superseded_by__idx ON public.branchmergeproposal USING btree (superseded_by) WHERE (superseded_by IS NOT NULL);
 
 
 CREATE INDEX branchmergeproposal__target_branch__idx ON public.branchmergeproposal USING btree (target_branch);
 
 
+CREATE INDEX branchmergeproposal__target_git_repository__target_git_path__id ON public.branchmergeproposal USING btree (target_git_repository, target_git_path);
+
+
 CREATE INDEX branchmergeproposaljob__branch_merge_proposal__idx ON public.branchmergeproposaljob USING btree (branch_merge_proposal);
 
 
@@ -18688,6 +20625,12 @@ CREATE INDEX bugsummary__milestone__idx ON public.bugsummary USING btree (milest
 CREATE INDEX bugsummary__nocount__idx ON public.bugsummary USING btree (count) WHERE (count = 0);
 
 
+CREATE INDEX bugsummary__ociproject__idx ON public.bugsummary USING btree (ociproject) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugsummary__ociprojectseries__idx ON public.bugsummary USING btree (ociprojectseries) WHERE (ociprojectseries IS NOT NULL);
+
+
 CREATE INDEX bugsummary__product__idx ON public.bugsummary USING btree (product) WHERE (product IS NOT NULL);
 
 
@@ -18697,13 +20640,13 @@ CREATE INDEX bugsummary__productseries__idx ON public.bugsummary USING btree (pr
 CREATE INDEX bugsummary__status_count__idx ON public.bugsummary USING btree (status) WHERE ((sourcepackagename IS NULL) AND (tag IS NULL));
 
 
-CREATE UNIQUE INDEX bugsummary__unique ON public.bugsummary USING btree ((COALESCE(product, (-1))), (COALESCE(productseries, (-1))), (COALESCE(distribution, (-1))), (COALESCE(distroseries, (-1))), (COALESCE(sourcepackagename, (-1))), status, importance, has_patch, (COALESCE(tag, ''::text)), (COALESCE(milestone, (-1))), (COALESCE(viewed_by, (-1))), (COALESCE(access_policy, (-1))));
+CREATE UNIQUE INDEX bugsummary__unique ON public.bugsummary USING btree (COALESCE(product, '-1'::integer), COALESCE(productseries, '-1'::integer), COALESCE(distribution, '-1'::integer), COALESCE(distroseries, '-1'::integer), COALESCE(sourcepackagename, '-1'::integer), COALESCE(ociproject, '-1'::integer), COALESCE(ociprojectseries, '-1'::integer), status, importance, has_patch, COALESCE(tag, ''::text), COALESCE(milestone, '-1'::integer), COALESCE(viewed_by, '-1'::integer), COALESCE(access_policy, '-1'::integer));
 
 
 CREATE INDEX bugsummary__viewed_by__idx ON public.bugsummary USING btree (viewed_by) WHERE (viewed_by IS NOT NULL);
 
 
-CREATE INDEX bugsummaryjournal__full__idx ON public.bugsummaryjournal USING btree (status, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, milestone, tag);
+CREATE INDEX bugsummaryjournal__full__idx ON public.bugsummaryjournal USING btree (status, product, productseries, distribution, distroseries, sourcepackagename, ociproject, ociprojectseries, viewed_by, milestone, tag);
 
 
 CREATE INDEX bugsummaryjournal__milestone__idx ON public.bugsummaryjournal USING btree (milestone) WHERE (milestone IS NOT NULL);
@@ -18744,10 +20687,16 @@ CREATE INDEX bugtask__distroseries__sourcepackagename__idx ON public.bugtask USI
 CREATE INDEX bugtask__milestone__idx ON public.bugtask USING btree (milestone);
 
 
+CREATE UNIQUE INDEX bugtask__ociproject__bug__key ON public.bugtask USING btree (ociproject, bug) WHERE (ociproject IS NOT NULL);
+
+
+CREATE UNIQUE INDEX bugtask__ociprojectseries__bug__key ON public.bugtask USING btree (ociprojectseries, bug) WHERE (ociprojectseries IS NOT NULL);
+
+
 CREATE INDEX bugtask__owner__idx ON public.bugtask USING btree (owner);
 
 
-CREATE UNIQUE INDEX bugtask__product__bug__key ON public.bugtask USING btree (product, bug) WHERE (product IS NOT NULL);
+CREATE UNIQUE INDEX bugtask__product__bug__key ON public.bugtask USING btree (product, bug) WHERE ((product IS NOT NULL) AND (ociproject IS NULL) AND (ociprojectseries IS NULL));
 
 
 CREATE UNIQUE INDEX bugtask__productseries__bug__key ON public.bugtask USING btree (productseries, bug) WHERE (productseries IS NOT NULL);
@@ -18759,7 +20708,7 @@ CREATE INDEX bugtask__sourcepackagename__idx ON public.bugtask USING btree (sour
 CREATE INDEX bugtask__status__idx ON public.bugtask USING btree (status);
 
 
-CREATE UNIQUE INDEX bugtask_distinct_sourcepackage_assignment ON public.bugtask USING btree (bug, (COALESCE(sourcepackagename, (-1))), (COALESCE(distroseries, (-1))), (COALESCE(distribution, (-1)))) WHERE ((product IS NULL) AND (productseries IS NULL));
+CREATE UNIQUE INDEX bugtask_distinct_sourcepackage_assignment ON public.bugtask USING btree (bug, COALESCE(sourcepackagename, '-1'::integer), COALESCE(distroseries, '-1'::integer), COALESCE(distribution, '-1'::integer)) WHERE ((product IS NULL) AND (productseries IS NULL) AND (ociproject IS NULL) AND (ociprojectseries IS NULL));
 
 
 CREATE INDEX bugtask_importance_idx ON public.bugtask USING btree (importance, id DESC);
@@ -18897,6 +20846,54 @@ CREATE INDEX bugtaskflat__latest_patch_uploaded__bugtask__idx ON public.bugtaskf
 CREATE INDEX bugtaskflat__milestone__idx ON public.bugtaskflat USING btree (milestone);
 
 
+CREATE INDEX bugtaskflat__ociproject__bug__idx ON public.bugtaskflat USING btree (ociproject, bug) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__date_closed__bug__idx ON public.bugtaskflat USING btree (ociproject, date_closed, bug DESC) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__date_last_updated__idx ON public.bugtaskflat USING btree (ociproject, date_last_updated) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__datecreated__idx ON public.bugtaskflat USING btree (ociproject, datecreated) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__heat__bug__idx ON public.bugtaskflat USING btree (ociproject, heat, bug DESC) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__importance__bug__idx ON public.bugtaskflat USING btree (ociproject, importance, bug DESC) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (ociproject, latest_patch_uploaded, bug DESC) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociproject__status__bug__idx ON public.bugtaskflat USING btree (ociproject, status, bug DESC) WHERE (ociproject IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, bug) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__date_closed__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, date_closed, bug DESC) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__date_last_updated__idx ON public.bugtaskflat USING btree (ociprojectseries, date_last_updated) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__datecreated__idx ON public.bugtaskflat USING btree (ociprojectseries, datecreated) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__heat__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, heat, bug DESC) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__importance__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, importance, bug DESC) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, latest_patch_uploaded, bug DESC) WHERE (ociprojectseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__ociprojectseries__status__bug__idx ON public.bugtaskflat USING btree (ociprojectseries, status, bug DESC) WHERE (ociprojectseries IS NOT NULL);
+
+
 CREATE INDEX bugtaskflat__owner__idx ON public.bugtaskflat USING btree (owner);
 
 
@@ -18912,122 +20909,209 @@ CREATE INDEX bugtaskflat__product__date_last_updated__idx ON public.bugtaskflat 
 CREATE INDEX bugtaskflat__product__datecreated__idx ON public.bugtaskflat USING btree (product, datecreated) WHERE (product IS NOT NULL);
 
 
-CREATE INDEX bugtaskflat__product__heat__bug__idx ON public.bugtaskflat USING btree (product, heat, bug DESC) WHERE (product IS NOT NULL);
+CREATE INDEX bugtaskflat__product__heat__bug__idx ON public.bugtaskflat USING btree (product, heat, bug DESC) WHERE (product IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__product__importance__bug__idx ON public.bugtaskflat USING btree (product, importance, bug DESC) WHERE (product IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__product__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (product, latest_patch_uploaded, bug DESC) WHERE (product IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__product__status__bug__idx ON public.bugtaskflat USING btree (product, status, bug DESC) WHERE (product IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__bug__idx ON public.bugtaskflat USING btree (productseries, bug) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__date_closed__bug__idx ON public.bugtaskflat USING btree (productseries, date_closed, bug DESC) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__date_last_updated__idx ON public.bugtaskflat USING btree (productseries, date_last_updated) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__datecreated__idx ON public.bugtaskflat USING btree (productseries, datecreated) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__heat__bug__idx ON public.bugtaskflat USING btree (productseries, heat, bug DESC) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__importance__bug__idx ON public.bugtaskflat USING btree (productseries, importance, bug DESC) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (productseries, latest_patch_uploaded, bug DESC) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__productseries__status__bug__idx ON public.bugtaskflat USING btree (productseries, status, bug DESC) WHERE (productseries IS NOT NULL);
+
+
+CREATE INDEX bugtaskflat__status__bugtask__idx ON public.bugtaskflat USING btree (status, bugtask DESC);
+
+
+CREATE UNIQUE INDEX bugtracker_name_key ON public.bugtracker USING btree (name);
+
+
+CREATE INDEX bugtracker_owner_idx ON public.bugtracker USING btree (owner);
+
+
+CREATE INDEX bugtrackeralias__bugtracker__idx ON public.bugtrackeralias USING btree (bugtracker);
+
+
+CREATE INDEX bugtrackerperson__person__idx ON public.bugtrackerperson USING btree (person);
+
+
+CREATE INDEX bugwatch__lastchecked__idx ON public.bugwatch USING btree (lastchecked);
+
+
+CREATE INDEX bugwatch__next_check__idx ON public.bugwatch USING btree (next_check);
+
+
+CREATE INDEX bugwatch__remote_lp_bug_id__idx ON public.bugwatch USING btree (remote_lp_bug_id) WHERE (remote_lp_bug_id IS NOT NULL);
+
+
+CREATE INDEX bugwatch__remotebug__idx ON public.bugwatch USING btree (remotebug);
+
+
+CREATE INDEX bugwatch_bug_idx ON public.bugwatch USING btree (bug);
+
+
+CREATE INDEX bugwatch_bugtracker_idx ON public.bugwatch USING btree (bugtracker);
+
+
+CREATE INDEX bugwatch_datecreated_idx ON public.bugwatch USING btree (datecreated);
+
+
+CREATE INDEX bugwatch_owner_idx ON public.bugwatch USING btree (owner);
+
+
+CREATE INDEX bugwatchactivity__bug_watch__idx ON public.bugwatchactivity USING btree (bug_watch);
+
+ALTER TABLE public.bugwatchactivity CLUSTER ON bugwatchactivity__bug_watch__idx;
+
+
+CREATE INDEX builder__owner__idx ON public.builder USING btree (owner);
+
+
+CREATE INDEX builderprocessor__processor__idx ON public.builderprocessor USING btree (processor);
+
+
+CREATE INDEX buildfarmjob__archive__date_created__id__idx ON public.buildfarmjob USING btree (archive, date_created DESC, id) WHERE (archive IS NOT NULL);
+
 
+CREATE INDEX buildfarmjob__archive__status__date_created__id__idx ON public.buildfarmjob USING btree (archive, status, date_created DESC, id) WHERE (archive IS NOT NULL);
 
-CREATE INDEX bugtaskflat__product__importance__bug__idx ON public.bugtaskflat USING btree (product, importance, bug DESC) WHERE (product IS NOT NULL);
 
+CREATE INDEX buildfarmjob__archive__status__date_finished__id__idx ON public.buildfarmjob USING btree (archive, status, date_finished DESC, id) WHERE (archive IS NOT NULL);
 
-CREATE INDEX bugtaskflat__product__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (product, latest_patch_uploaded, bug DESC) WHERE (product IS NOT NULL);
 
+CREATE INDEX buildfarmjob__builder__date_finished__id__idx ON public.buildfarmjob USING btree (builder, date_finished DESC, id) WHERE (builder IS NOT NULL);
 
-CREATE INDEX bugtaskflat__product__status__bug__idx ON public.bugtaskflat USING btree (product, status, bug DESC) WHERE (product IS NOT NULL);
 
+CREATE INDEX buildfarmjob__builder__status__date_finished__id__idx ON public.buildfarmjob USING btree (builder, status, date_finished DESC, id) WHERE (builder IS NOT NULL);
 
-CREATE INDEX bugtaskflat__productseries__bug__idx ON public.bugtaskflat USING btree (productseries, bug) WHERE (productseries IS NOT NULL);
 
+CREATE UNIQUE INDEX buildqueue__build_farm_job__key ON public.buildqueue USING btree (build_farm_job);
 
-CREATE INDEX bugtaskflat__productseries__date_closed__bug__idx ON public.bugtaskflat USING btree (productseries, date_closed, bug DESC) WHERE (productseries IS NOT NULL);
 
+CREATE UNIQUE INDEX buildqueue__builder__id__idx ON public.buildqueue USING btree (builder, id);
 
-CREATE INDEX bugtaskflat__productseries__date_last_updated__idx ON public.bugtaskflat USING btree (productseries, date_last_updated) WHERE (productseries IS NOT NULL);
+ALTER TABLE public.buildqueue CLUSTER ON buildqueue__builder__id__idx;
 
 
-CREATE INDEX bugtaskflat__productseries__datecreated__idx ON public.bugtaskflat USING btree (productseries, datecreated) WHERE (productseries IS NOT NULL);
+CREATE UNIQUE INDEX buildqueue__builder__unq ON public.buildqueue USING btree (builder) WHERE (builder IS NOT NULL);
 
 
-CREATE INDEX bugtaskflat__productseries__heat__bug__idx ON public.bugtaskflat USING btree (productseries, heat, bug DESC) WHERE (productseries IS NOT NULL);
+CREATE INDEX buildqueue__status__lastscore__id__idx ON public.buildqueue USING btree (status, lastscore DESC, id);
 
 
-CREATE INDEX bugtaskflat__productseries__importance__bug__idx ON public.bugtaskflat USING btree (productseries, importance, bug DESC) WHERE (productseries IS NOT NULL);
+CREATE INDEX buildqueue__status__virtualized__processor__lastscore__id__idx ON public.buildqueue USING btree (status, virtualized, processor, lastscore DESC, id);
 
 
-CREATE INDEX bugtaskflat__productseries__latest_patch_uploaded__bug__idx ON public.bugtaskflat USING btree (productseries, latest_patch_uploaded, bug DESC) WHERE (productseries IS NOT NULL);
+CREATE UNIQUE INDEX charmbase__distro_series__key ON public.charmbase USING btree (distro_series);
 
 
-CREATE INDEX bugtaskflat__productseries__status__bug__idx ON public.bugtaskflat USING btree (productseries, status, bug DESC) WHERE (productseries IS NOT NULL);
+CREATE INDEX charmbase__registrant__idx ON public.charmbase USING btree (registrant);
 
 
-CREATE INDEX bugtaskflat__status__bugtask__idx ON public.bugtaskflat USING btree (status, bugtask DESC);
+CREATE INDEX charmfile__build__idx ON public.charmfile USING btree (build);
 
 
-CREATE UNIQUE INDEX bugtracker_name_key ON public.bugtracker USING btree (name);
+CREATE INDEX charmfile__library_file__idx ON public.charmfile USING btree (library_file);
 
 
-CREATE INDEX bugtracker_owner_idx ON public.bugtracker USING btree (owner);
+CREATE INDEX charmrecipe__git_repository__idx ON public.charmrecipe USING btree (git_repository);
 
 
-CREATE INDEX bugtrackeralias__bugtracker__idx ON public.bugtrackeralias USING btree (bugtracker);
+CREATE INDEX charmrecipe__is_stale__auto_build__idx ON public.charmrecipe USING btree (is_stale, auto_build);
 
 
-CREATE INDEX bugtrackerperson__person__idx ON public.bugtrackerperson USING btree (person);
+CREATE UNIQUE INDEX charmrecipe__owner__project__name__key ON public.charmrecipe USING btree (owner, project, name);
 
 
-CREATE INDEX bugwatch__lastchecked__idx ON public.bugwatch USING btree (lastchecked);
+CREATE INDEX charmrecipe__project__idx ON public.charmrecipe USING btree (project);
 
 
-CREATE INDEX bugwatch__next_check__idx ON public.bugwatch USING btree (next_check);
+CREATE INDEX charmrecipe__registrant__idx ON public.charmrecipe USING btree (registrant);
 
 
-CREATE INDEX bugwatch__remote_lp_bug_id__idx ON public.bugwatch USING btree (remote_lp_bug_id) WHERE (remote_lp_bug_id IS NOT NULL);
+CREATE INDEX charmrecipe__store_name__idx ON public.charmrecipe USING btree (store_name);
 
 
-CREATE INDEX bugwatch__remotebug__idx ON public.bugwatch USING btree (remotebug);
+CREATE INDEX charmrecipebuild__build_farm_job__idx ON public.charmrecipebuild USING btree (build_farm_job);
 
 
-CREATE INDEX bugwatch_bug_idx ON public.bugwatch USING btree (bug);
+CREATE INDEX charmrecipebuild__build_request__idx ON public.charmrecipebuild USING btree (build_request);
 
 
-CREATE INDEX bugwatch_bugtracker_idx ON public.bugwatch USING btree (bugtracker);
+CREATE INDEX charmrecipebuild__distro_arch_series__idx ON public.charmrecipebuild USING btree (distro_arch_series);
 
 
-CREATE INDEX bugwatch_datecreated_idx ON public.bugwatch USING btree (datecreated);
+CREATE INDEX charmrecipebuild__log__idx ON public.charmrecipebuild USING btree (log);
 
 
-CREATE INDEX bugwatch_owner_idx ON public.bugwatch USING btree (owner);
+CREATE INDEX charmrecipebuild__recipe__das__status__finished__idx ON public.charmrecipebuild USING btree (recipe, distro_arch_series, status, date_finished DESC) WHERE (status = 1);
 
 
-CREATE INDEX bugwatchactivity__bug_watch__idx ON public.bugwatchactivity USING btree (bug_watch);
+CREATE INDEX charmrecipebuild__recipe__das__status__idx ON public.charmrecipebuild USING btree (recipe, distro_arch_series, status);
 
-ALTER TABLE public.bugwatchactivity CLUSTER ON bugwatchactivity__bug_watch__idx;
 
+CREATE INDEX charmrecipebuild__recipe__idx ON public.charmrecipebuild USING btree (recipe);
 
-CREATE INDEX builder__owner__idx ON public.builder USING btree (owner);
 
+CREATE INDEX charmrecipebuild__recipe__status__started__finished__created__i ON public.charmrecipebuild USING btree (recipe, status, GREATEST(date_started, date_finished) DESC NULLS LAST, date_created DESC, id DESC);
 
-CREATE INDEX builderprocessor__processor__idx ON public.builderprocessor USING btree (processor);
 
+CREATE INDEX charmrecipebuild__requester__idx ON public.charmrecipebuild USING btree (requester);
 
-CREATE INDEX buildfarmjob__archive__date_created__id__idx ON public.buildfarmjob USING btree (archive, date_created DESC, id) WHERE (archive IS NOT NULL);
 
+CREATE INDEX charmrecipebuild__upload_log__idx ON public.charmrecipebuild USING btree (upload_log);
 
-CREATE INDEX buildfarmjob__archive__status__date_created__id__idx ON public.buildfarmjob USING btree (archive, status, date_created DESC, id) WHERE (archive IS NOT NULL);
 
+CREATE INDEX charmrecipebuildjob__build__job_type__job__idx ON public.charmrecipebuildjob USING btree (build, job_type, job);
 
-CREATE INDEX buildfarmjob__archive__status__date_finished__id__idx ON public.buildfarmjob USING btree (archive, status, date_finished DESC, id) WHERE (archive IS NOT NULL);
 
+CREATE INDEX charmrecipejob__recipe__job_type__job__idx ON public.charmrecipejob USING btree (recipe, job_type, job);
 
-CREATE INDEX buildfarmjob__builder__date_finished__id__idx ON public.buildfarmjob USING btree (builder, date_finished DESC, id) WHERE (builder IS NOT NULL);
 
+CREATE INDEX cibuild__build_farm_job__idx ON public.cibuild USING btree (build_farm_job);
 
-CREATE INDEX buildfarmjob__builder__status__date_finished__id__idx ON public.buildfarmjob USING btree (builder, status, date_finished DESC, id) WHERE (builder IS NOT NULL);
 
+CREATE INDEX cibuild__commit__das__status__idx ON public.cibuild USING btree (git_repository, commit_sha1, distro_arch_series, status);
 
-CREATE UNIQUE INDEX buildqueue__build_farm_job__key ON public.buildqueue USING btree (build_farm_job);
 
+CREATE INDEX cibuild__commit__status__started__finished__created__id__idx ON public.cibuild USING btree (git_repository, commit_sha1, status, GREATEST(date_started, date_finished) DESC NULLS LAST, date_created DESC, id DESC);
 
-CREATE UNIQUE INDEX buildqueue__builder__id__idx ON public.buildqueue USING btree (builder, id);
 
-ALTER TABLE public.buildqueue CLUSTER ON buildqueue__builder__id__idx;
+CREATE INDEX cibuild__distro_arch_series__idx ON public.cibuild USING btree (distro_arch_series);
 
 
-CREATE UNIQUE INDEX buildqueue__builder__unq ON public.buildqueue USING btree (builder) WHERE (builder IS NOT NULL);
+CREATE INDEX cibuild__git_repository__das__status__finished__idx ON public.cibuild USING btree (git_repository, distro_arch_series, status, date_finished DESC) WHERE (status = 1);
 
 
-CREATE INDEX buildqueue__status__lastscore__id__idx ON public.buildqueue USING btree (status, lastscore DESC, id);
+CREATE INDEX cibuild__log__idx ON public.cibuild USING btree (log);
 
 
-CREATE INDEX buildqueue__status__virtualized__processor__lastscore__id__idx ON public.buildqueue USING btree (status, virtualized, processor, lastscore DESC, id);
+CREATE INDEX cibuild__upload_log__idx ON public.cibuild USING btree (upload_log);
 
 
 CREATE INDEX codeimport__assignee__idx ON public.codeimport USING btree (assignee);
@@ -19102,7 +21186,10 @@ CREATE INDEX codereviewvote__reviewer__idx ON public.codereviewvote USING btree 
 CREATE INDEX codereviewvote__vote_message__idx ON public.codereviewvote USING btree (vote_message);
 
 
-CREATE INDEX commercialsubscription__product__idx ON public.commercialsubscription USING btree (product);
+CREATE UNIQUE INDEX commercialsubscription__distribution__idx ON public.commercialsubscription USING btree (distribution) WHERE (distribution IS NOT NULL);
+
+
+CREATE UNIQUE INDEX commercialsubscription__product__idx ON public.commercialsubscription USING btree (product) WHERE (product IS NOT NULL);
 
 
 CREATE INDEX commercialsubscription__purchaser__idx ON public.commercialsubscription USING btree (purchaser);
@@ -19120,6 +21207,9 @@ CREATE UNIQUE INDEX customlanguagecode__distribution__sourcepackagename__code__k
 CREATE UNIQUE INDEX customlanguagecode__product__code__key ON public.customlanguagecode USING btree (product, language_code) WHERE (product IS NOT NULL);
 
 
+CREATE INDEX cve__discoverer__idx ON public.cve USING btree (discoverer);
+
+
 CREATE INDEX cve__fti__idx ON public.cve USING gin (fti);
 
 
@@ -19159,12 +21249,18 @@ CREATE INDEX distribution__mirror_admin__idx ON public.distribution USING btree 
 CREATE INDEX distribution__mugshot__idx ON public.distribution USING btree (mugshot) WHERE (mugshot IS NOT NULL);
 
 
+CREATE INDEX distribution__oci_project_admin__idx ON public.distribution USING btree (oci_project_admin);
+
+
 CREATE INDEX distribution__owner__idx ON public.distribution USING btree (owner);
 
 
 CREATE INDEX distribution__registrant__idx ON public.distribution USING btree (registrant);
 
 
+CREATE INDEX distribution__security_admin__idx ON public.distribution USING btree (security_admin);
+
+
 CREATE UNIQUE INDEX distribution_job__initialize_series__distroseries ON public.distributionjob USING btree (distroseries) WHERE (job_type = 1);
 
 
@@ -19210,6 +21306,9 @@ CREATE INDEX distroarchseries__distroseries__idx ON public.distroarchseries USIN
 CREATE INDEX distroarchseries__owner__idx ON public.distroarchseries USING btree (owner);
 
 
+CREATE INDEX distroarchseriesfilter__packageset__idx ON public.distroarchseriesfilter USING btree (packageset);
+
+
 CREATE INDEX distroseries__driver__idx ON public.distroseries USING btree (driver) WHERE (driver IS NOT NULL);
 
 
@@ -19300,28 +21399,64 @@ CREATE INDEX flatpackagesetinclusion__child__idx ON public.flatpackagesetinclusi
 CREATE INDEX gitactivity__repository__date_changed__id__idx ON public.gitactivity USING btree (repository, date_changed DESC, id DESC);
 
 
-CREATE INDEX gitrepository__distribution__spn__date_last_modified__idx ON public.gitrepository USING btree (distribution, sourcepackagename, date_last_modified) WHERE (distribution IS NOT NULL);
+CREATE INDEX gitrepository__date_created__status__idx ON public.gitrepository USING btree (date_created) WHERE (status = 1);
+
+
+CREATE INDEX gitrepository__distribution__ocipn__date_last_modified__idx ON public.gitrepository USING btree (distribution, ociprojectname, date_last_modified) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL));
+
 
+CREATE INDEX gitrepository__distribution__ocipn__id__idx ON public.gitrepository USING btree (distribution, ociprojectname, id) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL));
 
-CREATE INDEX gitrepository__distribution__spn__id__idx ON public.gitrepository USING btree (distribution, sourcepackagename, id) WHERE (distribution IS NOT NULL);
 
+CREATE UNIQUE INDEX gitrepository__distribution__ocipn__target_default__key ON public.gitrepository USING btree (distribution, ociprojectname) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL) AND target_default);
 
-CREATE UNIQUE INDEX gitrepository__distribution__spn__target_default__key ON public.gitrepository USING btree (distribution, sourcepackagename) WHERE ((distribution IS NOT NULL) AND target_default);
+
+CREATE INDEX gitrepository__distribution__spn__date_last_modified__idx ON public.gitrepository USING btree (distribution, sourcepackagename, date_last_modified) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL));
+
+
+CREATE INDEX gitrepository__distribution__spn__id__idx ON public.gitrepository USING btree (distribution, sourcepackagename, id) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL));
+
+
+CREATE UNIQUE INDEX gitrepository__distribution__spn__target_default__key ON public.gitrepository USING btree (distribution, sourcepackagename) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL) AND target_default);
+
+
+CREATE INDEX gitrepository__loose_object_count__pack_count__idx ON public.gitrepository USING btree (loose_object_count, pack_count);
+
+
+CREATE INDEX gitrepository__oci_project__date_last_modified__idx ON public.gitrepository USING btree (oci_project, date_last_modified) WHERE (oci_project IS NOT NULL);
+
+
+CREATE INDEX gitrepository__oci_project__id__idx ON public.gitrepository USING btree (oci_project, id) WHERE (oci_project IS NOT NULL);
+
+
+CREATE UNIQUE INDEX gitrepository__oci_project__target_default__key ON public.gitrepository USING btree (oci_project) WHERE ((oci_project IS NOT NULL) AND target_default);
 
 
 CREATE INDEX gitrepository__owner__date_last_modified__idx ON public.gitrepository USING btree (owner, date_last_modified);
 
 
-CREATE UNIQUE INDEX gitrepository__owner__distribution__sourcepackagename__name__ke ON public.gitrepository USING btree (owner, distribution, sourcepackagename, name) WHERE (distribution IS NOT NULL);
+CREATE INDEX gitrepository__owner__distribution__ocipn__date_last_modified__ ON public.gitrepository USING btree (owner, distribution, ociprojectname, date_last_modified) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL));
+
+
+CREATE INDEX gitrepository__owner__distribution__ocipn__id__idx ON public.gitrepository USING btree (owner, distribution, ociprojectname, id) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL));
+
 
+CREATE UNIQUE INDEX gitrepository__owner__distribution__ocipn__name__key ON public.gitrepository USING btree (owner, distribution, ociprojectname, name) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL));
 
-CREATE INDEX gitrepository__owner__distribution__spn__date_last_modified__id ON public.gitrepository USING btree (owner, distribution, sourcepackagename, date_last_modified) WHERE (distribution IS NOT NULL);
 
+CREATE UNIQUE INDEX gitrepository__owner__distribution__ocipn__owner_default__key ON public.gitrepository USING btree (owner, distribution, ociprojectname) WHERE ((distribution IS NOT NULL) AND (ociprojectname IS NOT NULL) AND owner_default);
 
-CREATE INDEX gitrepository__owner__distribution__spn__id__idx ON public.gitrepository USING btree (owner, distribution, sourcepackagename, id) WHERE (distribution IS NOT NULL);
 
+CREATE INDEX gitrepository__owner__distribution__spn__date_last_modified__id ON public.gitrepository USING btree (owner, distribution, sourcepackagename, date_last_modified) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL));
 
-CREATE UNIQUE INDEX gitrepository__owner__distribution__spn__owner_default__key ON public.gitrepository USING btree (owner, distribution, sourcepackagename) WHERE ((distribution IS NOT NULL) AND owner_default);
+
+CREATE INDEX gitrepository__owner__distribution__spn__id__idx ON public.gitrepository USING btree (owner, distribution, sourcepackagename, id) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL));
+
+
+CREATE UNIQUE INDEX gitrepository__owner__distribution__spn__name__key ON public.gitrepository USING btree (owner, distribution, sourcepackagename, name) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL));
+
+
+CREATE UNIQUE INDEX gitrepository__owner__distribution__spn__owner_default__key ON public.gitrepository USING btree (owner, distribution, sourcepackagename) WHERE ((distribution IS NOT NULL) AND (sourcepackagename IS NOT NULL) AND owner_default);
 
 
 CREATE INDEX gitrepository__owner__id__idx ON public.gitrepository USING btree (owner, id);
@@ -19330,6 +21465,18 @@ CREATE INDEX gitrepository__owner__id__idx ON public.gitrepository USING btree (
 CREATE UNIQUE INDEX gitrepository__owner__name__key ON public.gitrepository USING btree (owner, name) WHERE ((project IS NULL) AND (distribution IS NULL));
 
 
+CREATE INDEX gitrepository__owner__oci_project__date_last_modified__idx ON public.gitrepository USING btree (owner, oci_project, date_last_modified) WHERE (oci_project IS NOT NULL);
+
+
+CREATE INDEX gitrepository__owner__oci_project__id__idx ON public.gitrepository USING btree (owner, oci_project, id) WHERE (oci_project IS NOT NULL);
+
+
+CREATE UNIQUE INDEX gitrepository__owner__oci_project__name__key ON public.gitrepository USING btree (owner, oci_project, name) WHERE (oci_project IS NOT NULL);
+
+
+CREATE UNIQUE INDEX gitrepository__owner__oci_project__owner_default__key ON public.gitrepository USING btree (owner, oci_project) WHERE ((oci_project IS NOT NULL) AND owner_default);
+
+
 CREATE INDEX gitrepository__owner__project__date_last_modified__idx ON public.gitrepository USING btree (owner, project, date_last_modified) WHERE (project IS NOT NULL);
 
 
@@ -19524,10 +21671,10 @@ CREATE INDEX karma_person_datecreated_idx ON public.karma USING btree (person, d
 ALTER TABLE public.karma CLUSTER ON karma_person_datecreated_idx;
 
 
-CREATE INDEX karmacache__category__karmavalue__idx ON public.karmacache USING btree (category, karmavalue) WHERE ((((category IS NOT NULL) AND (product IS NULL)) AND (project IS NULL)) AND (distribution IS NULL));
+CREATE INDEX karmacache__category__karmavalue__idx ON public.karmacache USING btree (category, karmavalue) WHERE ((category IS NOT NULL) AND (product IS NULL) AND (project IS NULL) AND (distribution IS NULL));
 
 
-CREATE INDEX karmacache__distribution__category__karmavalue__idx ON public.karmacache USING btree (distribution, category, karmavalue) WHERE (((category IS NOT NULL) AND (distribution IS NOT NULL)) AND (sourcepackagename IS NULL));
+CREATE INDEX karmacache__distribution__category__karmavalue__idx ON public.karmacache USING btree (distribution, category, karmavalue) WHERE ((category IS NOT NULL) AND (distribution IS NOT NULL) AND (sourcepackagename IS NULL));
 
 
 CREATE INDEX karmacache__person__category__idx ON public.karmacache USING btree (person, category);
@@ -19545,13 +21692,13 @@ CREATE INDEX karmacache__project__category__karmavalue__idx ON public.karmacache
 CREATE INDEX karmacache__project__karmavalue__idx ON public.karmacache USING btree (project, karmavalue) WHERE ((category IS NULL) AND (project IS NOT NULL));
 
 
-CREATE UNIQUE INDEX karmacache__unq ON public.karmacache USING btree (person, (COALESCE(product, (-1))), (COALESCE(sourcepackagename, (-1))), (COALESCE(project, (-1))), (COALESCE(category, (-1))), (COALESCE(distribution, (-1))));
+CREATE UNIQUE INDEX karmacache__unq ON public.karmacache USING btree (person, COALESCE(product, '-1'::integer), COALESCE(sourcepackagename, '-1'::integer), COALESCE(project, '-1'::integer), COALESCE(category, '-1'::integer), COALESCE(distribution, '-1'::integer));
 
 
 CREATE INDEX karmacache_person_idx ON public.karmacache USING btree (person);
 
 
-CREATE INDEX karmacache_top_in_category_idx ON public.karmacache USING btree (person, category, karmavalue) WHERE ((((product IS NULL) AND (project IS NULL)) AND (sourcepackagename IS NULL)) AND (distribution IS NULL));
+CREATE INDEX karmacache_top_in_category_idx ON public.karmacache USING btree (person, category, karmavalue) WHERE ((product IS NULL) AND (project IS NULL) AND (sourcepackagename IS NULL) AND (distribution IS NULL));
 
 
 CREATE UNIQUE INDEX karmatotalcache_karma_total_person_idx ON public.karmatotalcache USING btree (karma_total, person);
@@ -19635,7 +21782,7 @@ CREATE INDEX livefsbuild__livefs__das__status__finished__idx ON public.livefsbui
 CREATE INDEX livefsbuild__livefs__idx ON public.livefsbuild USING btree (livefs);
 
 
-CREATE INDEX livefsbuild__livefs__status__started__finished__created__id__id ON public.livefsbuild USING btree (livefs, status, (GREATEST(date_started, date_finished)) DESC NULLS LAST, date_created DESC, id DESC);
+CREATE INDEX livefsbuild__livefs__status__started__finished__created__id__id ON public.livefsbuild USING btree (livefs, status, GREATEST(date_started, date_finished) DESC NULLS LAST, date_created DESC, id DESC);
 
 
 CREATE INDEX livefsbuild__log__idx ON public.livefsbuild USING btree (log);
@@ -19713,6 +21860,12 @@ CREATE INDEX messageapproval__posted_message__idx ON public.messageapproval USIN
 CREATE INDEX messagechunk_blob_idx ON public.messagechunk USING btree (blob) WHERE (blob IS NOT NULL);
 
 
+CREATE UNIQUE INDEX messagerevision__message__revision__key ON public.messagerevision USING btree (message, revision);
+
+
+CREATE UNIQUE INDEX messagerevisionchunk__messagerevision__sequence__key ON public.messagerevisionchunk USING btree (messagerevision, sequence);
+
+
 CREATE INDEX milestone__distroseries__idx ON public.milestone USING btree (distroseries);
 
 
@@ -19743,6 +21896,108 @@ CREATE INDEX oauthaccesstoken__person__idx ON public.oauthaccesstoken USING btre
 CREATE INDEX oauthrequesttoken__person__idx ON public.oauthrequesttoken USING btree (person) WHERE (person IS NOT NULL);
 
 
+CREATE UNIQUE INDEX ocifile__build__layer_file_digest__key ON public.ocifile USING btree (build, layer_file_digest);
+
+
+CREATE INDEX ocifile__date_last_used__idx ON public.ocifile USING btree (date_last_used);
+
+
+CREATE INDEX ocifile__layer_file_digest__idx ON public.ocifile USING btree (layer_file_digest);
+
+
+CREATE INDEX ocifile__library_file__idx ON public.ocifile USING btree (library_file);
+
+
+CREATE UNIQUE INDEX ociproject__distribution__ociprojectname__key ON public.ociproject USING btree (distribution, ociprojectname) WHERE (distribution IS NOT NULL);
+
+
+CREATE UNIQUE INDEX ociproject__project__ociprojectname__key ON public.ociproject USING btree (project, ociprojectname) WHERE (project IS NOT NULL);
+
+
+CREATE INDEX ociproject__registrant__idx ON public.ociproject USING btree (registrant);
+
+
+CREATE UNIQUE INDEX ociprojectname__name__key ON public.ociprojectname USING btree (name);
+
+
+CREATE INDEX ociprojectname__name__trgm ON public.ociprojectname USING gin (name trgm.gin_trgm_ops);
+
+
+CREATE UNIQUE INDEX ociprojectseries__ociproject__name__key ON public.ociprojectseries USING btree (ociproject, name);
+
+
+CREATE INDEX ociprojectseries__registrant__idx ON public.ociprojectseries USING btree (registrant);
+
+
+CREATE UNIQUE INDEX ocipushrule__recipe__registry_credentials__image_name__key ON public.ocipushrule USING btree (recipe, registry_credentials, image_name);
+
+
+CREATE INDEX ocipushrule__registry_credentials__idx ON public.ocipushrule USING btree (registry_credentials);
+
+
+CREATE INDEX ocirecipe__git_repository__idx ON public.ocirecipe USING btree (git_repository);
+
+
+CREATE INDEX ocirecipe__oci_project__idx ON public.ocirecipe USING btree (oci_project);
+
+
+CREATE UNIQUE INDEX ocirecipe__oci_project__name__official__key ON public.ocirecipe USING btree (oci_project, name) WHERE official;
+
+
+CREATE UNIQUE INDEX ocirecipe__owner__oci_project__name__key ON public.ocirecipe USING btree (owner, oci_project, name);
+
+
+CREATE INDEX ocirecipe__registrant__idx ON public.ocirecipe USING btree (registrant);
+
+
+CREATE INDEX ocirecipebuild__build_farm_job__idx ON public.ocirecipebuild USING btree (build_farm_job);
+
+
+CREATE INDEX ocirecipebuild__build_request__idx ON public.ocirecipebuild USING btree (build_request);
+
+
+CREATE INDEX ocirecipebuild__log__idx ON public.ocirecipebuild USING btree (log);
+
+
+CREATE INDEX ocirecipebuild__recipe__idx ON public.ocirecipebuild USING btree (recipe);
+
+
+CREATE INDEX ocirecipebuild__recipe__processor__status__finished__idx ON public.ocirecipebuild USING btree (recipe, processor, status, date_finished DESC) WHERE (status = 1);
+
+
+CREATE INDEX ocirecipebuild__recipe__processor__status__idx ON public.ocirecipebuild USING btree (recipe, processor, status);
+
+
+CREATE INDEX ocirecipebuild__recipe__status__started__finished__created__id_ ON public.ocirecipebuild USING btree (recipe, status, GREATEST(date_started, date_finished) DESC NULLS LAST, date_created DESC, id DESC);
+
+
+CREATE INDEX ocirecipebuild__requester__idx ON public.ocirecipebuild USING btree (requester);
+
+
+CREATE INDEX ocirecipebuild__upload_log__idx ON public.ocirecipebuild USING btree (upload_log);
+
+
+CREATE INDEX ocirecipebuildjob__build__job_type__job__idx ON public.ocirecipebuildjob USING btree (build, job_type, job);
+
+
+CREATE INDEX ocirecipebuildjob__job__job_type__idx ON public.ocirecipebuildjob USING btree (job, job_type);
+
+
+CREATE INDEX ocirecipejob__recipe__job_type__job__idx ON public.ocirecipejob USING btree (recipe, job_type, job);
+
+
+CREATE INDEX ocirecipesubscription__person__idx ON public.ocirecipesubscription USING btree (person);
+
+
+CREATE UNIQUE INDEX ocirecipesubscription__recipe__person__key ON public.ocirecipesubscription USING btree (recipe, person);
+
+
+CREATE INDEX ocirecipesubscription__subscribed_by__idx ON public.ocirecipesubscription USING btree (subscribed_by);
+
+
+CREATE INDEX ociregistrycredentials__owner__idx ON public.ociregistrycredentials USING btree (owner);
+
+
 CREATE UNIQUE INDEX officialbugtag__distribution__tag__key ON public.officialbugtag USING btree (distribution, tag) WHERE (distribution IS NOT NULL);
 
 
@@ -19758,6 +22013,9 @@ CREATE INDEX openididentifier__account__idx ON public.openididentifier USING btr
 CREATE UNIQUE INDEX packagecopyjob__job_type__target_ds__id__key ON public.packagecopyjob USING btree (job_type, target_distroseries, id);
 
 
+CREATE INDEX packagecopyjob__source_archive__idx ON public.packagecopyjob USING btree (source_archive);
+
+
 CREATE INDEX packagecopyjob__target ON public.packagecopyjob USING btree (target_archive, target_distroseries);
 
 
@@ -19767,6 +22025,9 @@ CREATE INDEX packagecopyrequest__datecreated__idx ON public.packagecopyrequest U
 CREATE INDEX packagecopyrequest__requester__idx ON public.packagecopyrequest USING btree (requester);
 
 
+CREATE INDEX packagecopyrequest__source_archive_