From 64f33955b5c193cf52dba86f5a21e92b65612de2 Mon Sep 17 00:00:00 2001
From: Nick Rolfe <nickrolfe@github.com>
Date: Fri, 17 Jan 2025 15:18:07 +0000
Subject: [PATCH] Java: add databaseMetadata to dbscheme

---
 .../old.dbscheme                              | 1232 +++++++++++++++++
 .../semmlecode.dbscheme                       | 1227 ++++++++++++++++
 .../upgrade.properties                        |    3 +
 java/ql/lib/config/semmlecode.dbscheme        |    5 +
 java/ql/lib/config/semmlecode.dbscheme.stats  |   15 +
 .../old.dbscheme                              | 1227 ++++++++++++++++
 .../semmlecode.dbscheme                       | 1232 +++++++++++++++++
 .../upgrade.properties                        |    2 +
 8 files changed, 4943 insertions(+)
 create mode 100644 java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/old.dbscheme
 create mode 100644 java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/semmlecode.dbscheme
 create mode 100644 java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/upgrade.properties
 create mode 100644 java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/old.dbscheme
 create mode 100644 java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/semmlecode.dbscheme
 create mode 100644 java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/upgrade.properties

diff --git a/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/old.dbscheme b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/old.dbscheme
new file mode 100644
index 000000000000..38d02c063878
--- /dev/null
+++ b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/old.dbscheme
@@ -0,0 +1,1232 @@
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ *   javac A.java B.java C.java
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+    /**
+     * An invocation of the compiler. Note that more than one file may
+     * be compiled per invocation. For example, this command compiles
+     * three source files:
+     *
+     *   javac A.java B.java C.java
+     */
+    unique int id : @compilation,
+    int kind: int ref,
+    string cwd : string ref,
+    string name : string ref
+);
+
+case @compilation.kind of
+   1  = @javacompilation
+|  2  = @kotlincompilation
+;
+
+compilation_started(
+    int id : @compilation ref
+)
+
+compilation_info(
+    int id : @compilation ref,
+    string info_key: string ref,
+    string info_value: string ref
+)
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | *path to extractor*
+ * 1   | `--javac-args`
+ * 2   | A.java
+ * 3   | B.java
+ * 4   | C.java
+ */
+#keyset[id, num]
+compilation_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@@@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | A.java
+ * 1   | B.java
+ * 2   | C.java
+ */
+#keyset[id, num]
+compilation_compiling_files(
+    int id : @compilation ref,
+    int num : int ref,
+    int file : @file ref
+);
+
+/**
+ * For each file recorded in `compilation_compiling_files`,
+ * there will be a corresponding row in
+ * `compilation_compiling_files_completed` once extraction
+ * of that file is complete. The `result` will indicate the
+ * extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+#keyset[id, num]
+compilation_compiling_files_completed(
+    int id : @compilation ref,
+    int num : int ref,
+    int result : int ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1    | CPU seconds used by the extractor frontend
+ * 2    | Elapsed seconds during the extractor frontend
+ * 3    | CPU seconds used by the extractor backend
+ * 4    | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+    int id : @compilation ref,
+    int num : int ref,
+    /* kind:
+       1 = frontend_cpu_seconds
+       2 = frontend_elapsed_seconds
+       3 = extractor_cpu_seconds
+       4 = extractor_elapsed_seconds
+    */
+    int kind : int ref,
+    float seconds : float ref
+);
+
+/**
+ * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed
+ * time (respectively) that the original compilation (not the extraction)
+ * took for compiler invocation `id`.
+ */
+compilation_compiler_times(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ * The `result` will indicate the extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+compilation_finished(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref,
+    int result : int ref
+);
+
+diagnostics(
+    unique int id: @diagnostic,
+    string generated_by: string ref, // TODO: Sync this with the other languages?
+    int severity: int ref,
+    string error_tag: string ref,
+    string error_message: string ref,
+    string full_error_message: string ref,
+    int location: @location_default ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+    unique int diagnostic : @diagnostic ref,
+    int compilation : @compilation ref,
+    int file_number : int ref,
+    int file_number_diagnostic_number : int ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalData(
+  int id : @externalDataElement,
+  string path : string ref,
+  int column: int ref,
+  string value : string ref
+);
+
+sourceLocationPrefix(
+  string prefix : string ref
+);
+
+databaseMetadata(
+  string metadataKey : string ref,
+  string value : string ref
+);
+
+/*
+ * SMAP
+ */
+
+smap_header(
+  int outputFileId: @file ref,
+  string outputFilename: string ref,
+  string defaultStratum: string ref
+);
+
+smap_files(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  string inputFileName: string ref,
+  int inputFileId: @file ref
+);
+
+smap_lines(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  int inputStartLine: int ref,
+  int inputLineCount: int ref,
+  int outputStartLine: int ref,
+  int outputLineIncrement: int ref
+);
+
+/*
+ * Locations and files
+ */
+
+@location = @location_default ;
+
+locations_default(
+  unique int id: @location_default,
+  int file: @file ref,
+  int beginLine: int ref,
+  int beginColumn: int ref,
+  int endLine: int ref,
+  int endColumn: int ref
+);
+
+hasLocation(
+  int locatableid: @locatable ref,
+  int id: @location ref
+);
+
+@sourceline = @locatable ;
+
+#keyset[element_id]
+numlines(
+  int element_id: @sourceline ref,
+  int num_lines: int ref,
+  int num_code: int ref,
+  int num_comment: int ref
+);
+
+files(
+  unique int id: @file,
+  string name: string ref
+);
+
+folders(
+  unique int id: @folder,
+  string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+  int parent: @container ref,
+  unique int child: @container ref
+);
+
+/*
+ * Java
+ */
+
+cupackage(
+  unique int id: @file ref,
+  int packageid: @package ref
+);
+
+#keyset[fileid,keyName]
+jarManifestMain(
+  int fileid: @file ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+#keyset[fileid,entryName,keyName]
+jarManifestEntries(
+  int fileid: @file ref,
+  string entryName: string ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+packages(
+  unique int id: @package,
+  string nodeName: string ref
+);
+
+primitives(
+  unique int id: @primitive,
+  string nodeName: string ref
+);
+
+modifiers(
+  unique int id: @modifier,
+  string nodeName: string ref
+);
+
+/**
+ * An errortype is used when the extractor is unable to extract a type
+ * correctly for some reason.
+ */
+error_type(
+  unique int id: @errortype
+);
+
+classes_or_interfaces(
+  unique int id: @classorinterface,
+  string nodeName: string ref,
+  int parentid: @package ref,
+  int sourceid: @classorinterface ref
+);
+
+file_class(
+  int id: @classorinterface ref
+);
+
+class_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref
+);
+
+type_companion_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref,
+  unique int companion_object: @classorinterface ref
+);
+
+kt_nullable_types(
+  unique int id: @kt_nullable_type,
+  int classid: @reftype ref
+)
+
+kt_notnull_types(
+  unique int id: @kt_notnull_type,
+  int classid: @reftype ref
+)
+
+kt_type_alias(
+  unique int id: @kt_type_alias,
+  string name: string ref,
+  int kttypeid: @kt_type ref
+)
+
+@kt_type = @kt_nullable_type | @kt_notnull_type
+
+isInterface(
+  unique int id: @classorinterface ref
+);
+
+isRecord(
+  unique int id: @classorinterface ref
+);
+
+fielddecls(
+  unique int id: @fielddecl,
+  int parentid: @reftype ref
+);
+
+#keyset[fieldId] #keyset[fieldDeclId,pos]
+fieldDeclaredIn(
+  int fieldId: @field ref,
+  int fieldDeclId: @fielddecl ref,
+  int pos: int ref
+);
+
+fields(
+  unique int id: @field,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref
+);
+
+fieldsKotlinType(
+  unique int id: @field ref,
+  int kttypeid: @kt_type ref
+);
+
+constrs(
+  unique int id: @constructor,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @constructor ref
+);
+
+constrsKotlinType(
+  unique int id: @constructor ref,
+  int kttypeid: @kt_type ref
+);
+
+methods(
+  unique int id: @method,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @method ref
+);
+
+methodsKotlinType(
+  unique int id: @method ref,
+  int kttypeid: @kt_type ref
+);
+
+#keyset[parentid,pos]
+params(
+  unique int id: @param,
+  int typeid: @type ref,
+  int pos: int ref,
+  int parentid: @callable ref,
+  int sourceid: @param ref
+);
+
+paramsKotlinType(
+  unique int id: @param ref,
+  int kttypeid: @kt_type ref
+);
+
+paramName(
+  unique int id: @param ref,
+  string nodeName: string ref
+);
+
+isVarargsParam(
+  int param: @param ref
+);
+
+exceptions(
+  unique int id: @exception,
+  int typeid: @type ref,
+  int parentid: @callable ref
+);
+
+isAnnotType(
+  int interfaceid: @classorinterface ref
+);
+
+isAnnotElem(
+  int methodid: @method ref
+);
+
+annotValue(
+  int parentid: @annotation ref,
+  int id2: @method ref,
+  unique int value: @expr ref
+);
+
+isEnumType(
+  int classid: @classorinterface ref
+);
+
+isEnumConst(
+  int fieldid: @field ref
+);
+
+#keyset[parentid,pos]
+typeVars(
+  unique int id: @typevariable,
+  string nodeName: string ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+wildcards(
+  unique int id: @wildcard,
+  string nodeName: string ref,
+  int kind: int ref
+);
+
+#keyset[parentid,pos]
+typeBounds(
+  unique int id: @typebound,
+  int typeid: @reftype ref,
+  int pos: int ref,
+  int parentid: @boundedtype ref
+);
+
+#keyset[parentid,pos]
+typeArgs(
+  int argumentid: @reftype ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+isParameterized(
+  int memberid: @member ref
+);
+
+isRaw(
+  int memberid: @member ref
+);
+
+#keyset[classid] #keyset[parent]
+isAnonymClass(
+  int classid: @classorinterface ref,
+  int parent: @classinstancexpr ref
+);
+
+#keyset[typeid] #keyset[parent]
+isLocalClassOrInterface(
+  int typeid: @classorinterface ref,
+  int parent: @localtypedeclstmt ref
+);
+
+isDefConstr(
+  int constructorid: @constructor ref
+);
+
+#keyset[exprId]
+lambdaKind(
+  int exprId: @lambdaexpr ref,
+  int bodyKind: int ref
+);
+
+isCanonicalConstr(
+  int constructorid: @constructor ref
+);
+
+arrays(
+  unique int id: @array,
+  string nodeName: string ref,
+  int elementtypeid: @type ref,
+  int dimension: int ref,
+  int componenttypeid: @type ref
+);
+
+enclInReftype(
+  unique int child: @reftype ref,
+  int parent: @reftype ref
+);
+
+extendsReftype(
+  int id1: @reftype ref,
+  int id2: @classorinterface ref
+);
+
+implInterface(
+  int id1: @classorarray ref,
+  int id2: @classorinterface ref
+);
+
+permits(
+  int id1: @classorinterface ref,
+  int id2: @classorinterface ref
+);
+
+hasModifier(
+  int id1: @modifiable ref,
+  int id2: @modifier ref
+);
+
+imports(
+  unique int id: @import,
+  int holder: @classorinterfaceorpackage ref,
+  string name: string ref,
+  int kind: int ref
+);
+
+#keyset[parent,idx]
+stmts(
+  unique int id: @stmt,
+  int kind: int ref,
+  int parent: @stmtparent ref,
+  int idx: int ref,
+  int bodydecl: @callable ref
+);
+
+@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr;
+
+case @stmt.kind of
+  0 = @block
+| 1 = @ifstmt
+| 2 = @forstmt
+| 3 = @enhancedforstmt
+| 4 = @whilestmt
+| 5 = @dostmt
+| 6 = @trystmt
+| 7 = @switchstmt
+| 8 = @synchronizedstmt
+| 9 = @returnstmt
+| 10 = @throwstmt
+| 11 = @breakstmt
+| 12 = @continuestmt
+| 13 = @emptystmt
+| 14 = @exprstmt
+| 15 = @labeledstmt
+| 16 = @assertstmt
+| 17 = @localvariabledeclstmt
+| 18 = @localtypedeclstmt
+| 19 = @constructorinvocationstmt
+| 20 = @superconstructorinvocationstmt
+| 21 = @case
+| 22 = @catchclause
+| 23 = @yieldstmt
+| 24 = @errorstmt
+| 25 = @whenbranch
+;
+
+#keyset[parent,idx]
+exprs(
+  unique int id: @expr,
+  int kind: int ref,
+  int typeid: @type ref,
+  int parent: @exprparent ref,
+  int idx: int ref
+);
+
+exprsKotlinType(
+  unique int id: @expr ref,
+  int kttypeid: @kt_type ref
+);
+
+callableEnclosingExpr(
+  unique int id: @expr ref,
+  int callable_id: @callable ref
+);
+
+statementEnclosingExpr(
+  unique int id: @expr ref,
+  int statement_id: @stmt ref
+);
+
+isParenthesized(
+  unique int id: @expr ref,
+  int parentheses: int ref
+);
+
+case @expr.kind of
+   1  = @arrayaccess
+|  2  = @arraycreationexpr
+|  3  = @arrayinit
+|  4  = @assignexpr
+|  5  = @assignaddexpr
+|  6  = @assignsubexpr
+|  7  = @assignmulexpr
+|  8  = @assigndivexpr
+|  9  = @assignremexpr
+| 10  = @assignandexpr
+| 11  = @assignorexpr
+| 12  = @assignxorexpr
+| 13  = @assignlshiftexpr
+| 14  = @assignrshiftexpr
+| 15  = @assignurshiftexpr
+| 16  = @booleanliteral
+| 17  = @integerliteral
+| 18  = @longliteral
+| 19  = @floatingpointliteral
+| 20  = @doubleliteral
+| 21  = @characterliteral
+| 22  = @stringliteral
+| 23  = @nullliteral
+| 24  = @mulexpr
+| 25  = @divexpr
+| 26  = @remexpr
+| 27  = @addexpr
+| 28  = @subexpr
+| 29  = @lshiftexpr
+| 30  = @rshiftexpr
+| 31  = @urshiftexpr
+| 32  = @andbitexpr
+| 33  = @orbitexpr
+| 34  = @xorbitexpr
+| 35  = @andlogicalexpr
+| 36  = @orlogicalexpr
+| 37  = @ltexpr
+| 38  = @gtexpr
+| 39  = @leexpr
+| 40  = @geexpr
+| 41  = @eqexpr
+| 42  = @neexpr
+| 43  = @postincexpr
+| 44  = @postdecexpr
+| 45  = @preincexpr
+| 46  = @predecexpr
+| 47  = @minusexpr
+| 48  = @plusexpr
+| 49  = @bitnotexpr
+| 50  = @lognotexpr
+| 51  = @castexpr
+| 52  = @newexpr
+| 53  = @conditionalexpr
+| 54  = @parexpr         // deprecated
+| 55  = @instanceofexpr
+| 56  = @localvariabledeclexpr
+| 57  = @typeliteral
+| 58  = @thisaccess
+| 59  = @superaccess
+| 60  = @varaccess
+| 61  = @methodaccess
+| 62  = @unannotatedtypeaccess
+| 63  = @arraytypeaccess
+| 64  = @packageaccess
+| 65  = @wildcardtypeaccess
+| 66  = @declannotation
+| 67  = @uniontypeaccess
+| 68  = @lambdaexpr
+| 69  = @memberref
+| 70  = @annotatedtypeaccess
+| 71  = @typeannotation
+| 72  = @intersectiontypeaccess
+| 73  = @switchexpr
+| 74  = @errorexpr
+| 75  = @whenexpr
+| 76  = @getclassexpr
+| 77  = @safecastexpr
+| 78  = @implicitcastexpr
+| 79  = @implicitnotnullexpr
+| 80  = @implicitcoerciontounitexpr
+| 81  = @notinstanceofexpr
+| 82  = @stmtexpr
+| 83  = @stringtemplateexpr
+| 84  = @notnullexpr
+| 85  = @unsafecoerceexpr
+| 86  = @valueeqexpr
+| 87  = @valueneexpr
+| 88  = @propertyref
+| 89  = @recordpatternexpr
+;
+
+/** Holds if this `when` expression was written as an `if` expression. */
+when_if(unique int id: @whenexpr ref);
+
+/** Holds if this `when` branch was written as an `else` branch. */
+when_branch_else(unique int id: @whenbranch ref);
+
+@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref
+
+@annotation = @declannotation | @typeannotation
+@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess
+
+@assignment = @assignexpr
+             | @assignop;
+
+@unaryassignment = @postincexpr
+                 | @postdecexpr
+                 | @preincexpr
+                 | @predecexpr;
+
+@assignop = @assignaddexpr
+             | @assignsubexpr
+             | @assignmulexpr
+             | @assigndivexpr
+             | @assignremexpr
+             | @assignandexpr
+             | @assignorexpr
+             | @assignxorexpr
+             | @assignlshiftexpr
+             | @assignrshiftexpr
+             | @assignurshiftexpr;
+
+@literal = @booleanliteral
+             | @integerliteral
+             | @longliteral
+             | @floatingpointliteral
+             | @doubleliteral
+             | @characterliteral
+             | @stringliteral
+             | @nullliteral;
+
+@binaryexpr = @mulexpr
+             | @divexpr
+             | @remexpr
+             | @addexpr
+             | @subexpr
+             | @lshiftexpr
+             | @rshiftexpr
+             | @urshiftexpr
+             | @andbitexpr
+             | @orbitexpr
+             | @xorbitexpr
+             | @andlogicalexpr
+             | @orlogicalexpr
+             | @ltexpr
+             | @gtexpr
+             | @leexpr
+             | @geexpr
+             | @eqexpr
+             | @neexpr
+             | @valueeqexpr
+             | @valueneexpr;
+
+@unaryexpr =   @postincexpr
+             | @postdecexpr
+             | @preincexpr
+             | @predecexpr
+             | @minusexpr
+             | @plusexpr
+             | @bitnotexpr
+             | @lognotexpr
+             | @notnullexpr;
+
+@caller =  @classinstancexpr
+         | @methodaccess
+         | @constructorinvocationstmt
+         | @superconstructorinvocationstmt;
+
+callableBinding(
+  unique int callerid: @caller ref,
+  int callee: @callable ref
+);
+
+memberRefBinding(
+  unique int id: @expr ref,
+  int callable: @callable ref
+);
+
+propertyRefGetBinding(
+  unique int id: @expr ref,
+  int getter: @callable ref
+);
+
+propertyRefFieldBinding(
+  unique int id: @expr ref,
+  int field: @field ref
+);
+
+propertyRefSetBinding(
+  unique int id: @expr ref,
+  int setter: @callable ref
+);
+
+@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable;
+
+variableBinding(
+  unique int expr: @varaccess ref,
+  int variable: @variable ref
+);
+
+@variable = @localscopevariable | @field;
+
+@localscopevariable = @localvar | @param;
+
+localvars(
+  unique int id: @localvar,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @localvariabledeclexpr ref
+);
+
+localvarsKotlinType(
+  unique int id: @localvar ref,
+  int kttypeid: @kt_type ref
+);
+
+@namedexprorstmt = @breakstmt
+                 | @continuestmt
+                 | @labeledstmt
+                 | @literal;
+
+namestrings(
+  string name: string ref,
+  string value: string ref,
+  unique int parent: @namedexprorstmt ref
+);
+
+/*
+ * Modules
+ */
+
+#keyset[name]
+modules(
+  unique int id: @module,
+  string name: string ref
+);
+
+isOpen(
+  int id: @module ref
+);
+
+#keyset[fileId]
+cumodule(
+  int fileId: @file ref,
+  int moduleId: @module ref
+);
+
+@directive = @requires
+           | @exports
+           | @opens
+           | @uses
+           | @provides
+
+#keyset[directive]
+directives(
+  int id: @module ref,
+  int directive: @directive ref
+);
+
+requires(
+  unique int id: @requires,
+  int target: @module ref
+);
+
+isTransitive(
+  int id: @requires ref
+);
+
+isStatic(
+  int id: @requires ref
+);
+
+exports(
+  unique int id: @exports,
+  int target: @package ref
+);
+
+exportsTo(
+  int id: @exports ref,
+  int target: @module ref
+);
+
+opens(
+  unique int id: @opens,
+  int target: @package ref
+);
+
+opensTo(
+  int id: @opens ref,
+  int target: @module ref
+);
+
+uses(
+  unique int id: @uses,
+  string serviceInterface: string ref
+);
+
+provides(
+  unique int id: @provides,
+  string serviceInterface: string ref
+);
+
+providesWith(
+  int id: @provides ref,
+  string serviceImpl: string ref
+);
+
+isNullDefaultCase(
+  int id: @case ref
+);
+
+/*
+ * Javadoc
+ */
+
+javadoc(
+  unique int id: @javadoc
+);
+
+isNormalComment(
+  int commentid : @javadoc ref
+);
+
+isEolComment(
+  int commentid : @javadoc ref
+);
+
+hasJavadoc(
+  int documentableid: @member ref,
+  int javadocid: @javadoc ref
+);
+
+#keyset[parentid,idx]
+javadocTag(
+  unique int id: @javadocTag,
+  string name: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+#keyset[parentid,idx]
+javadocText(
+  unique int id: @javadocText,
+  string text: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+@javadocParent = @javadoc | @javadocTag;
+@javadocElement = @javadocTag | @javadocText;
+
+@classorinterfaceorpackage = @classorinterface | @package;
+@classorinterfaceorcallable = @classorinterface | @callable;
+@boundedtype = @typevariable | @wildcard;
+@reftype = @classorinterface | @array | @boundedtype | @errortype;
+@classorarray = @classorinterface | @array;
+@type = @primitive | @reftype;
+@callable = @method | @constructor;
+
+/** A program element that has a name. */
+@element = @package | @modifier | @annotation | @errortype |
+           @locatableElement;
+
+@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field |
+                    @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
+                    @kt_property;
+
+@modifiable = @member_modifiable| @param | @localvar | @typevariable;
+
+@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property;
+
+@member = @method | @constructor | @field | @reftype ;
+
+/** A program element that has a location. */
+@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment |
+             @locatableElement;
+
+@top = @element | @locatable | @folder;
+
+/*
+ * XML Files
+ */
+
+xmlEncoding(
+  unique int id: @file ref,
+  string encoding: string ref
+);
+
+xmlDTDs(
+  unique int id: @xmldtd,
+  string root: string ref,
+  string publicId: string ref,
+  string systemId: string ref,
+  int fileid: @file ref
+);
+
+xmlElements(
+  unique int id: @xmlelement,
+  string name: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlAttrs(
+  unique int id: @xmlattribute,
+  int elementid: @xmlelement ref,
+  string name: string ref,
+  string value: string ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlNs(
+  int id: @xmlnamespace,
+  string prefixName: string ref,
+  string URI: string ref,
+  int fileid: @file ref
+);
+
+xmlHasNs(
+  int elementId: @xmlnamespaceable ref,
+  int nsId: @xmlnamespace ref,
+  int fileid: @file ref
+);
+
+xmlComments(
+  unique int id: @xmlcomment,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int fileid: @file ref
+);
+
+xmlChars(
+  unique int id: @xmlcharacters,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int isCDATA: int ref,
+  int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+  int xmlElement: @xmllocatable ref,
+  int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*
+ * configuration files with key value pairs
+ */
+
+configs(
+  unique int id: @config
+);
+
+configNames(
+  unique int id: @configName,
+  int config: @config ref,
+  string name: string ref
+);
+
+configValues(
+  unique int id: @configValue,
+  int config: @config ref,
+  string value: string ref
+);
+
+configLocations(
+  int locatable: @configLocatable ref,
+  int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
+
+ktComments(
+  unique int id: @ktcomment,
+  int kind: int ref,
+  string text : string ref
+)
+
+ktCommentSections(
+  unique int id: @ktcommentsection,
+  int comment: @ktcomment ref,
+  string content : string ref
+)
+
+ktCommentSectionNames(
+  unique int id: @ktcommentsection ref,
+  string name : string ref
+)
+
+ktCommentSectionSubjectNames(
+  unique int id: @ktcommentsection ref,
+  string subjectname : string ref
+)
+
+#keyset[id, owner]
+ktCommentOwners(
+  int id: @ktcomment ref,
+  int owner: @top ref
+)
+
+ktExtensionFunctions(
+  unique int id: @method ref,
+  int typeid: @type ref,
+  int kttypeid: @kt_type ref
+)
+
+ktProperties(
+  unique int id: @kt_property,
+  string nodeName: string ref
+)
+
+ktPropertyGetters(
+  unique int id: @kt_property ref,
+  int getter: @method ref
+)
+
+ktPropertySetters(
+  unique int id: @kt_property ref,
+  int setter: @method ref
+)
+
+ktPropertyBackingFields(
+  unique int id: @kt_property ref,
+  int backingField: @field ref
+)
+
+ktSyntheticBody(
+  unique int id: @callable ref,
+  int kind: int ref
+  // 1: ENUM_VALUES
+  // 2: ENUM_VALUEOF
+  // 3: ENUM_ENTRIES
+)
+
+ktLocalFunction(
+  unique int id: @method ref
+)
+
+ktInitializerAssignment(
+  unique int id: @assignexpr ref
+)
+
+ktPropertyDelegates(
+  unique int id: @kt_property ref,
+  unique int variableId: @variable ref
+)
+
+/**
+ * If `id` is a compiler generated element, then the kind indicates the
+ * reason that the compiler generated it.
+ * See `Element.compilerGeneratedReason()` for an explanation of what
+ * each `kind` means.
+ */
+compiler_generated(
+  unique int id: @element ref,
+  int kind: int ref
+)
+
+ktFunctionOriginalNames(
+  unique int id: @method ref,
+  string name: string ref
+)
+
+ktDataClasses(
+  unique int id: @classorinterface ref
+)
diff --git a/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/semmlecode.dbscheme b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/semmlecode.dbscheme
new file mode 100644
index 000000000000..1fd1afa7862b
--- /dev/null
+++ b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/semmlecode.dbscheme
@@ -0,0 +1,1227 @@
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ *   javac A.java B.java C.java
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+    /**
+     * An invocation of the compiler. Note that more than one file may
+     * be compiled per invocation. For example, this command compiles
+     * three source files:
+     *
+     *   javac A.java B.java C.java
+     */
+    unique int id : @compilation,
+    int kind: int ref,
+    string cwd : string ref,
+    string name : string ref
+);
+
+case @compilation.kind of
+   1  = @javacompilation
+|  2  = @kotlincompilation
+;
+
+compilation_started(
+    int id : @compilation ref
+)
+
+compilation_info(
+    int id : @compilation ref,
+    string info_key: string ref,
+    string info_value: string ref
+)
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | *path to extractor*
+ * 1   | `--javac-args`
+ * 2   | A.java
+ * 3   | B.java
+ * 4   | C.java
+ */
+#keyset[id, num]
+compilation_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@@@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | A.java
+ * 1   | B.java
+ * 2   | C.java
+ */
+#keyset[id, num]
+compilation_compiling_files(
+    int id : @compilation ref,
+    int num : int ref,
+    int file : @file ref
+);
+
+/**
+ * For each file recorded in `compilation_compiling_files`,
+ * there will be a corresponding row in
+ * `compilation_compiling_files_completed` once extraction
+ * of that file is complete. The `result` will indicate the
+ * extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+#keyset[id, num]
+compilation_compiling_files_completed(
+    int id : @compilation ref,
+    int num : int ref,
+    int result : int ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1    | CPU seconds used by the extractor frontend
+ * 2    | Elapsed seconds during the extractor frontend
+ * 3    | CPU seconds used by the extractor backend
+ * 4    | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+    int id : @compilation ref,
+    int num : int ref,
+    /* kind:
+       1 = frontend_cpu_seconds
+       2 = frontend_elapsed_seconds
+       3 = extractor_cpu_seconds
+       4 = extractor_elapsed_seconds
+    */
+    int kind : int ref,
+    float seconds : float ref
+);
+
+/**
+ * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed
+ * time (respectively) that the original compilation (not the extraction)
+ * took for compiler invocation `id`.
+ */
+compilation_compiler_times(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ * The `result` will indicate the extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+compilation_finished(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref,
+    int result : int ref
+);
+
+diagnostics(
+    unique int id: @diagnostic,
+    string generated_by: string ref, // TODO: Sync this with the other languages?
+    int severity: int ref,
+    string error_tag: string ref,
+    string error_message: string ref,
+    string full_error_message: string ref,
+    int location: @location_default ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+    unique int diagnostic : @diagnostic ref,
+    int compilation : @compilation ref,
+    int file_number : int ref,
+    int file_number_diagnostic_number : int ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalData(
+  int id : @externalDataElement,
+  string path : string ref,
+  int column: int ref,
+  string value : string ref
+);
+
+sourceLocationPrefix(
+  string prefix : string ref
+);
+
+/*
+ * SMAP
+ */
+
+smap_header(
+  int outputFileId: @file ref,
+  string outputFilename: string ref,
+  string defaultStratum: string ref
+);
+
+smap_files(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  string inputFileName: string ref,
+  int inputFileId: @file ref
+);
+
+smap_lines(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  int inputStartLine: int ref,
+  int inputLineCount: int ref,
+  int outputStartLine: int ref,
+  int outputLineIncrement: int ref
+);
+
+/*
+ * Locations and files
+ */
+
+@location = @location_default ;
+
+locations_default(
+  unique int id: @location_default,
+  int file: @file ref,
+  int beginLine: int ref,
+  int beginColumn: int ref,
+  int endLine: int ref,
+  int endColumn: int ref
+);
+
+hasLocation(
+  int locatableid: @locatable ref,
+  int id: @location ref
+);
+
+@sourceline = @locatable ;
+
+#keyset[element_id]
+numlines(
+  int element_id: @sourceline ref,
+  int num_lines: int ref,
+  int num_code: int ref,
+  int num_comment: int ref
+);
+
+files(
+  unique int id: @file,
+  string name: string ref
+);
+
+folders(
+  unique int id: @folder,
+  string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+  int parent: @container ref,
+  unique int child: @container ref
+);
+
+/*
+ * Java
+ */
+
+cupackage(
+  unique int id: @file ref,
+  int packageid: @package ref
+);
+
+#keyset[fileid,keyName]
+jarManifestMain(
+  int fileid: @file ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+#keyset[fileid,entryName,keyName]
+jarManifestEntries(
+  int fileid: @file ref,
+  string entryName: string ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+packages(
+  unique int id: @package,
+  string nodeName: string ref
+);
+
+primitives(
+  unique int id: @primitive,
+  string nodeName: string ref
+);
+
+modifiers(
+  unique int id: @modifier,
+  string nodeName: string ref
+);
+
+/**
+ * An errortype is used when the extractor is unable to extract a type
+ * correctly for some reason.
+ */
+error_type(
+  unique int id: @errortype
+);
+
+classes_or_interfaces(
+  unique int id: @classorinterface,
+  string nodeName: string ref,
+  int parentid: @package ref,
+  int sourceid: @classorinterface ref
+);
+
+file_class(
+  int id: @classorinterface ref
+);
+
+class_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref
+);
+
+type_companion_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref,
+  unique int companion_object: @classorinterface ref
+);
+
+kt_nullable_types(
+  unique int id: @kt_nullable_type,
+  int classid: @reftype ref
+)
+
+kt_notnull_types(
+  unique int id: @kt_notnull_type,
+  int classid: @reftype ref
+)
+
+kt_type_alias(
+  unique int id: @kt_type_alias,
+  string name: string ref,
+  int kttypeid: @kt_type ref
+)
+
+@kt_type = @kt_nullable_type | @kt_notnull_type
+
+isInterface(
+  unique int id: @classorinterface ref
+);
+
+isRecord(
+  unique int id: @classorinterface ref
+);
+
+fielddecls(
+  unique int id: @fielddecl,
+  int parentid: @reftype ref
+);
+
+#keyset[fieldId] #keyset[fieldDeclId,pos]
+fieldDeclaredIn(
+  int fieldId: @field ref,
+  int fieldDeclId: @fielddecl ref,
+  int pos: int ref
+);
+
+fields(
+  unique int id: @field,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref
+);
+
+fieldsKotlinType(
+  unique int id: @field ref,
+  int kttypeid: @kt_type ref
+);
+
+constrs(
+  unique int id: @constructor,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @constructor ref
+);
+
+constrsKotlinType(
+  unique int id: @constructor ref,
+  int kttypeid: @kt_type ref
+);
+
+methods(
+  unique int id: @method,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @method ref
+);
+
+methodsKotlinType(
+  unique int id: @method ref,
+  int kttypeid: @kt_type ref
+);
+
+#keyset[parentid,pos]
+params(
+  unique int id: @param,
+  int typeid: @type ref,
+  int pos: int ref,
+  int parentid: @callable ref,
+  int sourceid: @param ref
+);
+
+paramsKotlinType(
+  unique int id: @param ref,
+  int kttypeid: @kt_type ref
+);
+
+paramName(
+  unique int id: @param ref,
+  string nodeName: string ref
+);
+
+isVarargsParam(
+  int param: @param ref
+);
+
+exceptions(
+  unique int id: @exception,
+  int typeid: @type ref,
+  int parentid: @callable ref
+);
+
+isAnnotType(
+  int interfaceid: @classorinterface ref
+);
+
+isAnnotElem(
+  int methodid: @method ref
+);
+
+annotValue(
+  int parentid: @annotation ref,
+  int id2: @method ref,
+  unique int value: @expr ref
+);
+
+isEnumType(
+  int classid: @classorinterface ref
+);
+
+isEnumConst(
+  int fieldid: @field ref
+);
+
+#keyset[parentid,pos]
+typeVars(
+  unique int id: @typevariable,
+  string nodeName: string ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+wildcards(
+  unique int id: @wildcard,
+  string nodeName: string ref,
+  int kind: int ref
+);
+
+#keyset[parentid,pos]
+typeBounds(
+  unique int id: @typebound,
+  int typeid: @reftype ref,
+  int pos: int ref,
+  int parentid: @boundedtype ref
+);
+
+#keyset[parentid,pos]
+typeArgs(
+  int argumentid: @reftype ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+isParameterized(
+  int memberid: @member ref
+);
+
+isRaw(
+  int memberid: @member ref
+);
+
+#keyset[classid] #keyset[parent]
+isAnonymClass(
+  int classid: @classorinterface ref,
+  int parent: @classinstancexpr ref
+);
+
+#keyset[typeid] #keyset[parent]
+isLocalClassOrInterface(
+  int typeid: @classorinterface ref,
+  int parent: @localtypedeclstmt ref
+);
+
+isDefConstr(
+  int constructorid: @constructor ref
+);
+
+#keyset[exprId]
+lambdaKind(
+  int exprId: @lambdaexpr ref,
+  int bodyKind: int ref
+);
+
+isCanonicalConstr(
+  int constructorid: @constructor ref
+);
+
+arrays(
+  unique int id: @array,
+  string nodeName: string ref,
+  int elementtypeid: @type ref,
+  int dimension: int ref,
+  int componenttypeid: @type ref
+);
+
+enclInReftype(
+  unique int child: @reftype ref,
+  int parent: @reftype ref
+);
+
+extendsReftype(
+  int id1: @reftype ref,
+  int id2: @classorinterface ref
+);
+
+implInterface(
+  int id1: @classorarray ref,
+  int id2: @classorinterface ref
+);
+
+permits(
+  int id1: @classorinterface ref,
+  int id2: @classorinterface ref
+);
+
+hasModifier(
+  int id1: @modifiable ref,
+  int id2: @modifier ref
+);
+
+imports(
+  unique int id: @import,
+  int holder: @classorinterfaceorpackage ref,
+  string name: string ref,
+  int kind: int ref
+);
+
+#keyset[parent,idx]
+stmts(
+  unique int id: @stmt,
+  int kind: int ref,
+  int parent: @stmtparent ref,
+  int idx: int ref,
+  int bodydecl: @callable ref
+);
+
+@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr;
+
+case @stmt.kind of
+  0 = @block
+| 1 = @ifstmt
+| 2 = @forstmt
+| 3 = @enhancedforstmt
+| 4 = @whilestmt
+| 5 = @dostmt
+| 6 = @trystmt
+| 7 = @switchstmt
+| 8 = @synchronizedstmt
+| 9 = @returnstmt
+| 10 = @throwstmt
+| 11 = @breakstmt
+| 12 = @continuestmt
+| 13 = @emptystmt
+| 14 = @exprstmt
+| 15 = @labeledstmt
+| 16 = @assertstmt
+| 17 = @localvariabledeclstmt
+| 18 = @localtypedeclstmt
+| 19 = @constructorinvocationstmt
+| 20 = @superconstructorinvocationstmt
+| 21 = @case
+| 22 = @catchclause
+| 23 = @yieldstmt
+| 24 = @errorstmt
+| 25 = @whenbranch
+;
+
+#keyset[parent,idx]
+exprs(
+  unique int id: @expr,
+  int kind: int ref,
+  int typeid: @type ref,
+  int parent: @exprparent ref,
+  int idx: int ref
+);
+
+exprsKotlinType(
+  unique int id: @expr ref,
+  int kttypeid: @kt_type ref
+);
+
+callableEnclosingExpr(
+  unique int id: @expr ref,
+  int callable_id: @callable ref
+);
+
+statementEnclosingExpr(
+  unique int id: @expr ref,
+  int statement_id: @stmt ref
+);
+
+isParenthesized(
+  unique int id: @expr ref,
+  int parentheses: int ref
+);
+
+case @expr.kind of
+   1  = @arrayaccess
+|  2  = @arraycreationexpr
+|  3  = @arrayinit
+|  4  = @assignexpr
+|  5  = @assignaddexpr
+|  6  = @assignsubexpr
+|  7  = @assignmulexpr
+|  8  = @assigndivexpr
+|  9  = @assignremexpr
+| 10  = @assignandexpr
+| 11  = @assignorexpr
+| 12  = @assignxorexpr
+| 13  = @assignlshiftexpr
+| 14  = @assignrshiftexpr
+| 15  = @assignurshiftexpr
+| 16  = @booleanliteral
+| 17  = @integerliteral
+| 18  = @longliteral
+| 19  = @floatingpointliteral
+| 20  = @doubleliteral
+| 21  = @characterliteral
+| 22  = @stringliteral
+| 23  = @nullliteral
+| 24  = @mulexpr
+| 25  = @divexpr
+| 26  = @remexpr
+| 27  = @addexpr
+| 28  = @subexpr
+| 29  = @lshiftexpr
+| 30  = @rshiftexpr
+| 31  = @urshiftexpr
+| 32  = @andbitexpr
+| 33  = @orbitexpr
+| 34  = @xorbitexpr
+| 35  = @andlogicalexpr
+| 36  = @orlogicalexpr
+| 37  = @ltexpr
+| 38  = @gtexpr
+| 39  = @leexpr
+| 40  = @geexpr
+| 41  = @eqexpr
+| 42  = @neexpr
+| 43  = @postincexpr
+| 44  = @postdecexpr
+| 45  = @preincexpr
+| 46  = @predecexpr
+| 47  = @minusexpr
+| 48  = @plusexpr
+| 49  = @bitnotexpr
+| 50  = @lognotexpr
+| 51  = @castexpr
+| 52  = @newexpr
+| 53  = @conditionalexpr
+| 54  = @parexpr         // deprecated
+| 55  = @instanceofexpr
+| 56  = @localvariabledeclexpr
+| 57  = @typeliteral
+| 58  = @thisaccess
+| 59  = @superaccess
+| 60  = @varaccess
+| 61  = @methodaccess
+| 62  = @unannotatedtypeaccess
+| 63  = @arraytypeaccess
+| 64  = @packageaccess
+| 65  = @wildcardtypeaccess
+| 66  = @declannotation
+| 67  = @uniontypeaccess
+| 68  = @lambdaexpr
+| 69  = @memberref
+| 70  = @annotatedtypeaccess
+| 71  = @typeannotation
+| 72  = @intersectiontypeaccess
+| 73  = @switchexpr
+| 74  = @errorexpr
+| 75  = @whenexpr
+| 76  = @getclassexpr
+| 77  = @safecastexpr
+| 78  = @implicitcastexpr
+| 79  = @implicitnotnullexpr
+| 80  = @implicitcoerciontounitexpr
+| 81  = @notinstanceofexpr
+| 82  = @stmtexpr
+| 83  = @stringtemplateexpr
+| 84  = @notnullexpr
+| 85  = @unsafecoerceexpr
+| 86  = @valueeqexpr
+| 87  = @valueneexpr
+| 88  = @propertyref
+| 89  = @recordpatternexpr
+;
+
+/** Holds if this `when` expression was written as an `if` expression. */
+when_if(unique int id: @whenexpr ref);
+
+/** Holds if this `when` branch was written as an `else` branch. */
+when_branch_else(unique int id: @whenbranch ref);
+
+@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref
+
+@annotation = @declannotation | @typeannotation
+@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess
+
+@assignment = @assignexpr
+             | @assignop;
+
+@unaryassignment = @postincexpr
+                 | @postdecexpr
+                 | @preincexpr
+                 | @predecexpr;
+
+@assignop = @assignaddexpr
+             | @assignsubexpr
+             | @assignmulexpr
+             | @assigndivexpr
+             | @assignremexpr
+             | @assignandexpr
+             | @assignorexpr
+             | @assignxorexpr
+             | @assignlshiftexpr
+             | @assignrshiftexpr
+             | @assignurshiftexpr;
+
+@literal = @booleanliteral
+             | @integerliteral
+             | @longliteral
+             | @floatingpointliteral
+             | @doubleliteral
+             | @characterliteral
+             | @stringliteral
+             | @nullliteral;
+
+@binaryexpr = @mulexpr
+             | @divexpr
+             | @remexpr
+             | @addexpr
+             | @subexpr
+             | @lshiftexpr
+             | @rshiftexpr
+             | @urshiftexpr
+             | @andbitexpr
+             | @orbitexpr
+             | @xorbitexpr
+             | @andlogicalexpr
+             | @orlogicalexpr
+             | @ltexpr
+             | @gtexpr
+             | @leexpr
+             | @geexpr
+             | @eqexpr
+             | @neexpr
+             | @valueeqexpr
+             | @valueneexpr;
+
+@unaryexpr =   @postincexpr
+             | @postdecexpr
+             | @preincexpr
+             | @predecexpr
+             | @minusexpr
+             | @plusexpr
+             | @bitnotexpr
+             | @lognotexpr
+             | @notnullexpr;
+
+@caller =  @classinstancexpr
+         | @methodaccess
+         | @constructorinvocationstmt
+         | @superconstructorinvocationstmt;
+
+callableBinding(
+  unique int callerid: @caller ref,
+  int callee: @callable ref
+);
+
+memberRefBinding(
+  unique int id: @expr ref,
+  int callable: @callable ref
+);
+
+propertyRefGetBinding(
+  unique int id: @expr ref,
+  int getter: @callable ref
+);
+
+propertyRefFieldBinding(
+  unique int id: @expr ref,
+  int field: @field ref
+);
+
+propertyRefSetBinding(
+  unique int id: @expr ref,
+  int setter: @callable ref
+);
+
+@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable;
+
+variableBinding(
+  unique int expr: @varaccess ref,
+  int variable: @variable ref
+);
+
+@variable = @localscopevariable | @field;
+
+@localscopevariable = @localvar | @param;
+
+localvars(
+  unique int id: @localvar,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @localvariabledeclexpr ref
+);
+
+localvarsKotlinType(
+  unique int id: @localvar ref,
+  int kttypeid: @kt_type ref
+);
+
+@namedexprorstmt = @breakstmt
+                 | @continuestmt
+                 | @labeledstmt
+                 | @literal;
+
+namestrings(
+  string name: string ref,
+  string value: string ref,
+  unique int parent: @namedexprorstmt ref
+);
+
+/*
+ * Modules
+ */
+
+#keyset[name]
+modules(
+  unique int id: @module,
+  string name: string ref
+);
+
+isOpen(
+  int id: @module ref
+);
+
+#keyset[fileId]
+cumodule(
+  int fileId: @file ref,
+  int moduleId: @module ref
+);
+
+@directive = @requires
+           | @exports
+           | @opens
+           | @uses
+           | @provides
+
+#keyset[directive]
+directives(
+  int id: @module ref,
+  int directive: @directive ref
+);
+
+requires(
+  unique int id: @requires,
+  int target: @module ref
+);
+
+isTransitive(
+  int id: @requires ref
+);
+
+isStatic(
+  int id: @requires ref
+);
+
+exports(
+  unique int id: @exports,
+  int target: @package ref
+);
+
+exportsTo(
+  int id: @exports ref,
+  int target: @module ref
+);
+
+opens(
+  unique int id: @opens,
+  int target: @package ref
+);
+
+opensTo(
+  int id: @opens ref,
+  int target: @module ref
+);
+
+uses(
+  unique int id: @uses,
+  string serviceInterface: string ref
+);
+
+provides(
+  unique int id: @provides,
+  string serviceInterface: string ref
+);
+
+providesWith(
+  int id: @provides ref,
+  string serviceImpl: string ref
+);
+
+isNullDefaultCase(
+  int id: @case ref
+);
+
+/*
+ * Javadoc
+ */
+
+javadoc(
+  unique int id: @javadoc
+);
+
+isNormalComment(
+  int commentid : @javadoc ref
+);
+
+isEolComment(
+  int commentid : @javadoc ref
+);
+
+hasJavadoc(
+  int documentableid: @member ref,
+  int javadocid: @javadoc ref
+);
+
+#keyset[parentid,idx]
+javadocTag(
+  unique int id: @javadocTag,
+  string name: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+#keyset[parentid,idx]
+javadocText(
+  unique int id: @javadocText,
+  string text: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+@javadocParent = @javadoc | @javadocTag;
+@javadocElement = @javadocTag | @javadocText;
+
+@classorinterfaceorpackage = @classorinterface | @package;
+@classorinterfaceorcallable = @classorinterface | @callable;
+@boundedtype = @typevariable | @wildcard;
+@reftype = @classorinterface | @array | @boundedtype | @errortype;
+@classorarray = @classorinterface | @array;
+@type = @primitive | @reftype;
+@callable = @method | @constructor;
+
+/** A program element that has a name. */
+@element = @package | @modifier | @annotation | @errortype |
+           @locatableElement;
+
+@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field |
+                    @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
+                    @kt_property;
+
+@modifiable = @member_modifiable| @param | @localvar | @typevariable;
+
+@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property;
+
+@member = @method | @constructor | @field | @reftype ;
+
+/** A program element that has a location. */
+@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment |
+             @locatableElement;
+
+@top = @element | @locatable | @folder;
+
+/*
+ * XML Files
+ */
+
+xmlEncoding(
+  unique int id: @file ref,
+  string encoding: string ref
+);
+
+xmlDTDs(
+  unique int id: @xmldtd,
+  string root: string ref,
+  string publicId: string ref,
+  string systemId: string ref,
+  int fileid: @file ref
+);
+
+xmlElements(
+  unique int id: @xmlelement,
+  string name: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlAttrs(
+  unique int id: @xmlattribute,
+  int elementid: @xmlelement ref,
+  string name: string ref,
+  string value: string ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlNs(
+  int id: @xmlnamespace,
+  string prefixName: string ref,
+  string URI: string ref,
+  int fileid: @file ref
+);
+
+xmlHasNs(
+  int elementId: @xmlnamespaceable ref,
+  int nsId: @xmlnamespace ref,
+  int fileid: @file ref
+);
+
+xmlComments(
+  unique int id: @xmlcomment,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int fileid: @file ref
+);
+
+xmlChars(
+  unique int id: @xmlcharacters,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int isCDATA: int ref,
+  int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+  int xmlElement: @xmllocatable ref,
+  int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*
+ * configuration files with key value pairs
+ */
+
+configs(
+  unique int id: @config
+);
+
+configNames(
+  unique int id: @configName,
+  int config: @config ref,
+  string name: string ref
+);
+
+configValues(
+  unique int id: @configValue,
+  int config: @config ref,
+  string value: string ref
+);
+
+configLocations(
+  int locatable: @configLocatable ref,
+  int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
+
+ktComments(
+  unique int id: @ktcomment,
+  int kind: int ref,
+  string text : string ref
+)
+
+ktCommentSections(
+  unique int id: @ktcommentsection,
+  int comment: @ktcomment ref,
+  string content : string ref
+)
+
+ktCommentSectionNames(
+  unique int id: @ktcommentsection ref,
+  string name : string ref
+)
+
+ktCommentSectionSubjectNames(
+  unique int id: @ktcommentsection ref,
+  string subjectname : string ref
+)
+
+#keyset[id, owner]
+ktCommentOwners(
+  int id: @ktcomment ref,
+  int owner: @top ref
+)
+
+ktExtensionFunctions(
+  unique int id: @method ref,
+  int typeid: @type ref,
+  int kttypeid: @kt_type ref
+)
+
+ktProperties(
+  unique int id: @kt_property,
+  string nodeName: string ref
+)
+
+ktPropertyGetters(
+  unique int id: @kt_property ref,
+  int getter: @method ref
+)
+
+ktPropertySetters(
+  unique int id: @kt_property ref,
+  int setter: @method ref
+)
+
+ktPropertyBackingFields(
+  unique int id: @kt_property ref,
+  int backingField: @field ref
+)
+
+ktSyntheticBody(
+  unique int id: @callable ref,
+  int kind: int ref
+  // 1: ENUM_VALUES
+  // 2: ENUM_VALUEOF
+  // 3: ENUM_ENTRIES
+)
+
+ktLocalFunction(
+  unique int id: @method ref
+)
+
+ktInitializerAssignment(
+  unique int id: @assignexpr ref
+)
+
+ktPropertyDelegates(
+  unique int id: @kt_property ref,
+  unique int variableId: @variable ref
+)
+
+/**
+ * If `id` is a compiler generated element, then the kind indicates the
+ * reason that the compiler generated it.
+ * See `Element.compilerGeneratedReason()` for an explanation of what
+ * each `kind` means.
+ */
+compiler_generated(
+  unique int id: @element ref,
+  int kind: int ref
+)
+
+ktFunctionOriginalNames(
+  unique int id: @method ref,
+  string name: string ref
+)
+
+ktDataClasses(
+  unique int id: @classorinterface ref
+)
diff --git a/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/upgrade.properties b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/upgrade.properties
new file mode 100644
index 000000000000..1d437ec8ac6b
--- /dev/null
+++ b/java/downgrades/38d02c063878000356a3e5db49d5a6a8f38efe24/upgrade.properties
@@ -0,0 +1,3 @@
+description: Add databaseMetadata relation
+compatibility: full
+databaseMetadata.rel: delete
diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme
index 1fd1afa7862b..38d02c063878 100644
--- a/java/ql/lib/config/semmlecode.dbscheme
+++ b/java/ql/lib/config/semmlecode.dbscheme
@@ -206,6 +206,11 @@ sourceLocationPrefix(
   string prefix : string ref
 );
 
+databaseMetadata(
+  string metadataKey : string ref,
+  string value : string ref
+);
+
 /*
  * SMAP
  */
diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats
index a6b93ae74055..024ba7c8a853 100644
--- a/java/ql/lib/config/semmlecode.dbscheme.stats
+++ b/java/ql/lib/config/semmlecode.dbscheme.stats
@@ -3968,6 +3968,21 @@
             </columnsizes>
             <dependencies/>
         </relation>
+        <relation>
+            <name>databaseMetadata</name>
+            <cardinality>1</cardinality>
+            <columnsizes>
+                <e>
+                    <k>metadataKey</k>
+                    <v>1</v>
+                </e>
+                <e>
+                    <k>value</k>
+                    <v>1</v>
+                </e>
+            </columnsizes>
+            <dependencies/>
+        </relation>
         <relation>
             <name>smap_header</name>
             <cardinality>1</cardinality>
diff --git a/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/old.dbscheme b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/old.dbscheme
new file mode 100644
index 000000000000..1fd1afa7862b
--- /dev/null
+++ b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/old.dbscheme
@@ -0,0 +1,1227 @@
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ *   javac A.java B.java C.java
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+    /**
+     * An invocation of the compiler. Note that more than one file may
+     * be compiled per invocation. For example, this command compiles
+     * three source files:
+     *
+     *   javac A.java B.java C.java
+     */
+    unique int id : @compilation,
+    int kind: int ref,
+    string cwd : string ref,
+    string name : string ref
+);
+
+case @compilation.kind of
+   1  = @javacompilation
+|  2  = @kotlincompilation
+;
+
+compilation_started(
+    int id : @compilation ref
+)
+
+compilation_info(
+    int id : @compilation ref,
+    string info_key: string ref,
+    string info_value: string ref
+)
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | *path to extractor*
+ * 1   | `--javac-args`
+ * 2   | A.java
+ * 3   | B.java
+ * 4   | C.java
+ */
+#keyset[id, num]
+compilation_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@@@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | A.java
+ * 1   | B.java
+ * 2   | C.java
+ */
+#keyset[id, num]
+compilation_compiling_files(
+    int id : @compilation ref,
+    int num : int ref,
+    int file : @file ref
+);
+
+/**
+ * For each file recorded in `compilation_compiling_files`,
+ * there will be a corresponding row in
+ * `compilation_compiling_files_completed` once extraction
+ * of that file is complete. The `result` will indicate the
+ * extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+#keyset[id, num]
+compilation_compiling_files_completed(
+    int id : @compilation ref,
+    int num : int ref,
+    int result : int ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1    | CPU seconds used by the extractor frontend
+ * 2    | Elapsed seconds during the extractor frontend
+ * 3    | CPU seconds used by the extractor backend
+ * 4    | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+    int id : @compilation ref,
+    int num : int ref,
+    /* kind:
+       1 = frontend_cpu_seconds
+       2 = frontend_elapsed_seconds
+       3 = extractor_cpu_seconds
+       4 = extractor_elapsed_seconds
+    */
+    int kind : int ref,
+    float seconds : float ref
+);
+
+/**
+ * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed
+ * time (respectively) that the original compilation (not the extraction)
+ * took for compiler invocation `id`.
+ */
+compilation_compiler_times(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ * The `result` will indicate the extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+compilation_finished(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref,
+    int result : int ref
+);
+
+diagnostics(
+    unique int id: @diagnostic,
+    string generated_by: string ref, // TODO: Sync this with the other languages?
+    int severity: int ref,
+    string error_tag: string ref,
+    string error_message: string ref,
+    string full_error_message: string ref,
+    int location: @location_default ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+    unique int diagnostic : @diagnostic ref,
+    int compilation : @compilation ref,
+    int file_number : int ref,
+    int file_number_diagnostic_number : int ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalData(
+  int id : @externalDataElement,
+  string path : string ref,
+  int column: int ref,
+  string value : string ref
+);
+
+sourceLocationPrefix(
+  string prefix : string ref
+);
+
+/*
+ * SMAP
+ */
+
+smap_header(
+  int outputFileId: @file ref,
+  string outputFilename: string ref,
+  string defaultStratum: string ref
+);
+
+smap_files(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  string inputFileName: string ref,
+  int inputFileId: @file ref
+);
+
+smap_lines(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  int inputStartLine: int ref,
+  int inputLineCount: int ref,
+  int outputStartLine: int ref,
+  int outputLineIncrement: int ref
+);
+
+/*
+ * Locations and files
+ */
+
+@location = @location_default ;
+
+locations_default(
+  unique int id: @location_default,
+  int file: @file ref,
+  int beginLine: int ref,
+  int beginColumn: int ref,
+  int endLine: int ref,
+  int endColumn: int ref
+);
+
+hasLocation(
+  int locatableid: @locatable ref,
+  int id: @location ref
+);
+
+@sourceline = @locatable ;
+
+#keyset[element_id]
+numlines(
+  int element_id: @sourceline ref,
+  int num_lines: int ref,
+  int num_code: int ref,
+  int num_comment: int ref
+);
+
+files(
+  unique int id: @file,
+  string name: string ref
+);
+
+folders(
+  unique int id: @folder,
+  string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+  int parent: @container ref,
+  unique int child: @container ref
+);
+
+/*
+ * Java
+ */
+
+cupackage(
+  unique int id: @file ref,
+  int packageid: @package ref
+);
+
+#keyset[fileid,keyName]
+jarManifestMain(
+  int fileid: @file ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+#keyset[fileid,entryName,keyName]
+jarManifestEntries(
+  int fileid: @file ref,
+  string entryName: string ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+packages(
+  unique int id: @package,
+  string nodeName: string ref
+);
+
+primitives(
+  unique int id: @primitive,
+  string nodeName: string ref
+);
+
+modifiers(
+  unique int id: @modifier,
+  string nodeName: string ref
+);
+
+/**
+ * An errortype is used when the extractor is unable to extract a type
+ * correctly for some reason.
+ */
+error_type(
+  unique int id: @errortype
+);
+
+classes_or_interfaces(
+  unique int id: @classorinterface,
+  string nodeName: string ref,
+  int parentid: @package ref,
+  int sourceid: @classorinterface ref
+);
+
+file_class(
+  int id: @classorinterface ref
+);
+
+class_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref
+);
+
+type_companion_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref,
+  unique int companion_object: @classorinterface ref
+);
+
+kt_nullable_types(
+  unique int id: @kt_nullable_type,
+  int classid: @reftype ref
+)
+
+kt_notnull_types(
+  unique int id: @kt_notnull_type,
+  int classid: @reftype ref
+)
+
+kt_type_alias(
+  unique int id: @kt_type_alias,
+  string name: string ref,
+  int kttypeid: @kt_type ref
+)
+
+@kt_type = @kt_nullable_type | @kt_notnull_type
+
+isInterface(
+  unique int id: @classorinterface ref
+);
+
+isRecord(
+  unique int id: @classorinterface ref
+);
+
+fielddecls(
+  unique int id: @fielddecl,
+  int parentid: @reftype ref
+);
+
+#keyset[fieldId] #keyset[fieldDeclId,pos]
+fieldDeclaredIn(
+  int fieldId: @field ref,
+  int fieldDeclId: @fielddecl ref,
+  int pos: int ref
+);
+
+fields(
+  unique int id: @field,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref
+);
+
+fieldsKotlinType(
+  unique int id: @field ref,
+  int kttypeid: @kt_type ref
+);
+
+constrs(
+  unique int id: @constructor,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @constructor ref
+);
+
+constrsKotlinType(
+  unique int id: @constructor ref,
+  int kttypeid: @kt_type ref
+);
+
+methods(
+  unique int id: @method,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @method ref
+);
+
+methodsKotlinType(
+  unique int id: @method ref,
+  int kttypeid: @kt_type ref
+);
+
+#keyset[parentid,pos]
+params(
+  unique int id: @param,
+  int typeid: @type ref,
+  int pos: int ref,
+  int parentid: @callable ref,
+  int sourceid: @param ref
+);
+
+paramsKotlinType(
+  unique int id: @param ref,
+  int kttypeid: @kt_type ref
+);
+
+paramName(
+  unique int id: @param ref,
+  string nodeName: string ref
+);
+
+isVarargsParam(
+  int param: @param ref
+);
+
+exceptions(
+  unique int id: @exception,
+  int typeid: @type ref,
+  int parentid: @callable ref
+);
+
+isAnnotType(
+  int interfaceid: @classorinterface ref
+);
+
+isAnnotElem(
+  int methodid: @method ref
+);
+
+annotValue(
+  int parentid: @annotation ref,
+  int id2: @method ref,
+  unique int value: @expr ref
+);
+
+isEnumType(
+  int classid: @classorinterface ref
+);
+
+isEnumConst(
+  int fieldid: @field ref
+);
+
+#keyset[parentid,pos]
+typeVars(
+  unique int id: @typevariable,
+  string nodeName: string ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+wildcards(
+  unique int id: @wildcard,
+  string nodeName: string ref,
+  int kind: int ref
+);
+
+#keyset[parentid,pos]
+typeBounds(
+  unique int id: @typebound,
+  int typeid: @reftype ref,
+  int pos: int ref,
+  int parentid: @boundedtype ref
+);
+
+#keyset[parentid,pos]
+typeArgs(
+  int argumentid: @reftype ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+isParameterized(
+  int memberid: @member ref
+);
+
+isRaw(
+  int memberid: @member ref
+);
+
+#keyset[classid] #keyset[parent]
+isAnonymClass(
+  int classid: @classorinterface ref,
+  int parent: @classinstancexpr ref
+);
+
+#keyset[typeid] #keyset[parent]
+isLocalClassOrInterface(
+  int typeid: @classorinterface ref,
+  int parent: @localtypedeclstmt ref
+);
+
+isDefConstr(
+  int constructorid: @constructor ref
+);
+
+#keyset[exprId]
+lambdaKind(
+  int exprId: @lambdaexpr ref,
+  int bodyKind: int ref
+);
+
+isCanonicalConstr(
+  int constructorid: @constructor ref
+);
+
+arrays(
+  unique int id: @array,
+  string nodeName: string ref,
+  int elementtypeid: @type ref,
+  int dimension: int ref,
+  int componenttypeid: @type ref
+);
+
+enclInReftype(
+  unique int child: @reftype ref,
+  int parent: @reftype ref
+);
+
+extendsReftype(
+  int id1: @reftype ref,
+  int id2: @classorinterface ref
+);
+
+implInterface(
+  int id1: @classorarray ref,
+  int id2: @classorinterface ref
+);
+
+permits(
+  int id1: @classorinterface ref,
+  int id2: @classorinterface ref
+);
+
+hasModifier(
+  int id1: @modifiable ref,
+  int id2: @modifier ref
+);
+
+imports(
+  unique int id: @import,
+  int holder: @classorinterfaceorpackage ref,
+  string name: string ref,
+  int kind: int ref
+);
+
+#keyset[parent,idx]
+stmts(
+  unique int id: @stmt,
+  int kind: int ref,
+  int parent: @stmtparent ref,
+  int idx: int ref,
+  int bodydecl: @callable ref
+);
+
+@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr;
+
+case @stmt.kind of
+  0 = @block
+| 1 = @ifstmt
+| 2 = @forstmt
+| 3 = @enhancedforstmt
+| 4 = @whilestmt
+| 5 = @dostmt
+| 6 = @trystmt
+| 7 = @switchstmt
+| 8 = @synchronizedstmt
+| 9 = @returnstmt
+| 10 = @throwstmt
+| 11 = @breakstmt
+| 12 = @continuestmt
+| 13 = @emptystmt
+| 14 = @exprstmt
+| 15 = @labeledstmt
+| 16 = @assertstmt
+| 17 = @localvariabledeclstmt
+| 18 = @localtypedeclstmt
+| 19 = @constructorinvocationstmt
+| 20 = @superconstructorinvocationstmt
+| 21 = @case
+| 22 = @catchclause
+| 23 = @yieldstmt
+| 24 = @errorstmt
+| 25 = @whenbranch
+;
+
+#keyset[parent,idx]
+exprs(
+  unique int id: @expr,
+  int kind: int ref,
+  int typeid: @type ref,
+  int parent: @exprparent ref,
+  int idx: int ref
+);
+
+exprsKotlinType(
+  unique int id: @expr ref,
+  int kttypeid: @kt_type ref
+);
+
+callableEnclosingExpr(
+  unique int id: @expr ref,
+  int callable_id: @callable ref
+);
+
+statementEnclosingExpr(
+  unique int id: @expr ref,
+  int statement_id: @stmt ref
+);
+
+isParenthesized(
+  unique int id: @expr ref,
+  int parentheses: int ref
+);
+
+case @expr.kind of
+   1  = @arrayaccess
+|  2  = @arraycreationexpr
+|  3  = @arrayinit
+|  4  = @assignexpr
+|  5  = @assignaddexpr
+|  6  = @assignsubexpr
+|  7  = @assignmulexpr
+|  8  = @assigndivexpr
+|  9  = @assignremexpr
+| 10  = @assignandexpr
+| 11  = @assignorexpr
+| 12  = @assignxorexpr
+| 13  = @assignlshiftexpr
+| 14  = @assignrshiftexpr
+| 15  = @assignurshiftexpr
+| 16  = @booleanliteral
+| 17  = @integerliteral
+| 18  = @longliteral
+| 19  = @floatingpointliteral
+| 20  = @doubleliteral
+| 21  = @characterliteral
+| 22  = @stringliteral
+| 23  = @nullliteral
+| 24  = @mulexpr
+| 25  = @divexpr
+| 26  = @remexpr
+| 27  = @addexpr
+| 28  = @subexpr
+| 29  = @lshiftexpr
+| 30  = @rshiftexpr
+| 31  = @urshiftexpr
+| 32  = @andbitexpr
+| 33  = @orbitexpr
+| 34  = @xorbitexpr
+| 35  = @andlogicalexpr
+| 36  = @orlogicalexpr
+| 37  = @ltexpr
+| 38  = @gtexpr
+| 39  = @leexpr
+| 40  = @geexpr
+| 41  = @eqexpr
+| 42  = @neexpr
+| 43  = @postincexpr
+| 44  = @postdecexpr
+| 45  = @preincexpr
+| 46  = @predecexpr
+| 47  = @minusexpr
+| 48  = @plusexpr
+| 49  = @bitnotexpr
+| 50  = @lognotexpr
+| 51  = @castexpr
+| 52  = @newexpr
+| 53  = @conditionalexpr
+| 54  = @parexpr         // deprecated
+| 55  = @instanceofexpr
+| 56  = @localvariabledeclexpr
+| 57  = @typeliteral
+| 58  = @thisaccess
+| 59  = @superaccess
+| 60  = @varaccess
+| 61  = @methodaccess
+| 62  = @unannotatedtypeaccess
+| 63  = @arraytypeaccess
+| 64  = @packageaccess
+| 65  = @wildcardtypeaccess
+| 66  = @declannotation
+| 67  = @uniontypeaccess
+| 68  = @lambdaexpr
+| 69  = @memberref
+| 70  = @annotatedtypeaccess
+| 71  = @typeannotation
+| 72  = @intersectiontypeaccess
+| 73  = @switchexpr
+| 74  = @errorexpr
+| 75  = @whenexpr
+| 76  = @getclassexpr
+| 77  = @safecastexpr
+| 78  = @implicitcastexpr
+| 79  = @implicitnotnullexpr
+| 80  = @implicitcoerciontounitexpr
+| 81  = @notinstanceofexpr
+| 82  = @stmtexpr
+| 83  = @stringtemplateexpr
+| 84  = @notnullexpr
+| 85  = @unsafecoerceexpr
+| 86  = @valueeqexpr
+| 87  = @valueneexpr
+| 88  = @propertyref
+| 89  = @recordpatternexpr
+;
+
+/** Holds if this `when` expression was written as an `if` expression. */
+when_if(unique int id: @whenexpr ref);
+
+/** Holds if this `when` branch was written as an `else` branch. */
+when_branch_else(unique int id: @whenbranch ref);
+
+@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref
+
+@annotation = @declannotation | @typeannotation
+@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess
+
+@assignment = @assignexpr
+             | @assignop;
+
+@unaryassignment = @postincexpr
+                 | @postdecexpr
+                 | @preincexpr
+                 | @predecexpr;
+
+@assignop = @assignaddexpr
+             | @assignsubexpr
+             | @assignmulexpr
+             | @assigndivexpr
+             | @assignremexpr
+             | @assignandexpr
+             | @assignorexpr
+             | @assignxorexpr
+             | @assignlshiftexpr
+             | @assignrshiftexpr
+             | @assignurshiftexpr;
+
+@literal = @booleanliteral
+             | @integerliteral
+             | @longliteral
+             | @floatingpointliteral
+             | @doubleliteral
+             | @characterliteral
+             | @stringliteral
+             | @nullliteral;
+
+@binaryexpr = @mulexpr
+             | @divexpr
+             | @remexpr
+             | @addexpr
+             | @subexpr
+             | @lshiftexpr
+             | @rshiftexpr
+             | @urshiftexpr
+             | @andbitexpr
+             | @orbitexpr
+             | @xorbitexpr
+             | @andlogicalexpr
+             | @orlogicalexpr
+             | @ltexpr
+             | @gtexpr
+             | @leexpr
+             | @geexpr
+             | @eqexpr
+             | @neexpr
+             | @valueeqexpr
+             | @valueneexpr;
+
+@unaryexpr =   @postincexpr
+             | @postdecexpr
+             | @preincexpr
+             | @predecexpr
+             | @minusexpr
+             | @plusexpr
+             | @bitnotexpr
+             | @lognotexpr
+             | @notnullexpr;
+
+@caller =  @classinstancexpr
+         | @methodaccess
+         | @constructorinvocationstmt
+         | @superconstructorinvocationstmt;
+
+callableBinding(
+  unique int callerid: @caller ref,
+  int callee: @callable ref
+);
+
+memberRefBinding(
+  unique int id: @expr ref,
+  int callable: @callable ref
+);
+
+propertyRefGetBinding(
+  unique int id: @expr ref,
+  int getter: @callable ref
+);
+
+propertyRefFieldBinding(
+  unique int id: @expr ref,
+  int field: @field ref
+);
+
+propertyRefSetBinding(
+  unique int id: @expr ref,
+  int setter: @callable ref
+);
+
+@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable;
+
+variableBinding(
+  unique int expr: @varaccess ref,
+  int variable: @variable ref
+);
+
+@variable = @localscopevariable | @field;
+
+@localscopevariable = @localvar | @param;
+
+localvars(
+  unique int id: @localvar,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @localvariabledeclexpr ref
+);
+
+localvarsKotlinType(
+  unique int id: @localvar ref,
+  int kttypeid: @kt_type ref
+);
+
+@namedexprorstmt = @breakstmt
+                 | @continuestmt
+                 | @labeledstmt
+                 | @literal;
+
+namestrings(
+  string name: string ref,
+  string value: string ref,
+  unique int parent: @namedexprorstmt ref
+);
+
+/*
+ * Modules
+ */
+
+#keyset[name]
+modules(
+  unique int id: @module,
+  string name: string ref
+);
+
+isOpen(
+  int id: @module ref
+);
+
+#keyset[fileId]
+cumodule(
+  int fileId: @file ref,
+  int moduleId: @module ref
+);
+
+@directive = @requires
+           | @exports
+           | @opens
+           | @uses
+           | @provides
+
+#keyset[directive]
+directives(
+  int id: @module ref,
+  int directive: @directive ref
+);
+
+requires(
+  unique int id: @requires,
+  int target: @module ref
+);
+
+isTransitive(
+  int id: @requires ref
+);
+
+isStatic(
+  int id: @requires ref
+);
+
+exports(
+  unique int id: @exports,
+  int target: @package ref
+);
+
+exportsTo(
+  int id: @exports ref,
+  int target: @module ref
+);
+
+opens(
+  unique int id: @opens,
+  int target: @package ref
+);
+
+opensTo(
+  int id: @opens ref,
+  int target: @module ref
+);
+
+uses(
+  unique int id: @uses,
+  string serviceInterface: string ref
+);
+
+provides(
+  unique int id: @provides,
+  string serviceInterface: string ref
+);
+
+providesWith(
+  int id: @provides ref,
+  string serviceImpl: string ref
+);
+
+isNullDefaultCase(
+  int id: @case ref
+);
+
+/*
+ * Javadoc
+ */
+
+javadoc(
+  unique int id: @javadoc
+);
+
+isNormalComment(
+  int commentid : @javadoc ref
+);
+
+isEolComment(
+  int commentid : @javadoc ref
+);
+
+hasJavadoc(
+  int documentableid: @member ref,
+  int javadocid: @javadoc ref
+);
+
+#keyset[parentid,idx]
+javadocTag(
+  unique int id: @javadocTag,
+  string name: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+#keyset[parentid,idx]
+javadocText(
+  unique int id: @javadocText,
+  string text: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+@javadocParent = @javadoc | @javadocTag;
+@javadocElement = @javadocTag | @javadocText;
+
+@classorinterfaceorpackage = @classorinterface | @package;
+@classorinterfaceorcallable = @classorinterface | @callable;
+@boundedtype = @typevariable | @wildcard;
+@reftype = @classorinterface | @array | @boundedtype | @errortype;
+@classorarray = @classorinterface | @array;
+@type = @primitive | @reftype;
+@callable = @method | @constructor;
+
+/** A program element that has a name. */
+@element = @package | @modifier | @annotation | @errortype |
+           @locatableElement;
+
+@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field |
+                    @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
+                    @kt_property;
+
+@modifiable = @member_modifiable| @param | @localvar | @typevariable;
+
+@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property;
+
+@member = @method | @constructor | @field | @reftype ;
+
+/** A program element that has a location. */
+@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment |
+             @locatableElement;
+
+@top = @element | @locatable | @folder;
+
+/*
+ * XML Files
+ */
+
+xmlEncoding(
+  unique int id: @file ref,
+  string encoding: string ref
+);
+
+xmlDTDs(
+  unique int id: @xmldtd,
+  string root: string ref,
+  string publicId: string ref,
+  string systemId: string ref,
+  int fileid: @file ref
+);
+
+xmlElements(
+  unique int id: @xmlelement,
+  string name: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlAttrs(
+  unique int id: @xmlattribute,
+  int elementid: @xmlelement ref,
+  string name: string ref,
+  string value: string ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlNs(
+  int id: @xmlnamespace,
+  string prefixName: string ref,
+  string URI: string ref,
+  int fileid: @file ref
+);
+
+xmlHasNs(
+  int elementId: @xmlnamespaceable ref,
+  int nsId: @xmlnamespace ref,
+  int fileid: @file ref
+);
+
+xmlComments(
+  unique int id: @xmlcomment,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int fileid: @file ref
+);
+
+xmlChars(
+  unique int id: @xmlcharacters,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int isCDATA: int ref,
+  int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+  int xmlElement: @xmllocatable ref,
+  int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*
+ * configuration files with key value pairs
+ */
+
+configs(
+  unique int id: @config
+);
+
+configNames(
+  unique int id: @configName,
+  int config: @config ref,
+  string name: string ref
+);
+
+configValues(
+  unique int id: @configValue,
+  int config: @config ref,
+  string value: string ref
+);
+
+configLocations(
+  int locatable: @configLocatable ref,
+  int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
+
+ktComments(
+  unique int id: @ktcomment,
+  int kind: int ref,
+  string text : string ref
+)
+
+ktCommentSections(
+  unique int id: @ktcommentsection,
+  int comment: @ktcomment ref,
+  string content : string ref
+)
+
+ktCommentSectionNames(
+  unique int id: @ktcommentsection ref,
+  string name : string ref
+)
+
+ktCommentSectionSubjectNames(
+  unique int id: @ktcommentsection ref,
+  string subjectname : string ref
+)
+
+#keyset[id, owner]
+ktCommentOwners(
+  int id: @ktcomment ref,
+  int owner: @top ref
+)
+
+ktExtensionFunctions(
+  unique int id: @method ref,
+  int typeid: @type ref,
+  int kttypeid: @kt_type ref
+)
+
+ktProperties(
+  unique int id: @kt_property,
+  string nodeName: string ref
+)
+
+ktPropertyGetters(
+  unique int id: @kt_property ref,
+  int getter: @method ref
+)
+
+ktPropertySetters(
+  unique int id: @kt_property ref,
+  int setter: @method ref
+)
+
+ktPropertyBackingFields(
+  unique int id: @kt_property ref,
+  int backingField: @field ref
+)
+
+ktSyntheticBody(
+  unique int id: @callable ref,
+  int kind: int ref
+  // 1: ENUM_VALUES
+  // 2: ENUM_VALUEOF
+  // 3: ENUM_ENTRIES
+)
+
+ktLocalFunction(
+  unique int id: @method ref
+)
+
+ktInitializerAssignment(
+  unique int id: @assignexpr ref
+)
+
+ktPropertyDelegates(
+  unique int id: @kt_property ref,
+  unique int variableId: @variable ref
+)
+
+/**
+ * If `id` is a compiler generated element, then the kind indicates the
+ * reason that the compiler generated it.
+ * See `Element.compilerGeneratedReason()` for an explanation of what
+ * each `kind` means.
+ */
+compiler_generated(
+  unique int id: @element ref,
+  int kind: int ref
+)
+
+ktFunctionOriginalNames(
+  unique int id: @method ref,
+  string name: string ref
+)
+
+ktDataClasses(
+  unique int id: @classorinterface ref
+)
diff --git a/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/semmlecode.dbscheme b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/semmlecode.dbscheme
new file mode 100644
index 000000000000..38d02c063878
--- /dev/null
+++ b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/semmlecode.dbscheme
@@ -0,0 +1,1232 @@
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ *   javac A.java B.java C.java
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+    /**
+     * An invocation of the compiler. Note that more than one file may
+     * be compiled per invocation. For example, this command compiles
+     * three source files:
+     *
+     *   javac A.java B.java C.java
+     */
+    unique int id : @compilation,
+    int kind: int ref,
+    string cwd : string ref,
+    string name : string ref
+);
+
+case @compilation.kind of
+   1  = @javacompilation
+|  2  = @kotlincompilation
+;
+
+compilation_started(
+    int id : @compilation ref
+)
+
+compilation_info(
+    int id : @compilation ref,
+    string info_key: string ref,
+    string info_value: string ref
+)
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | *path to extractor*
+ * 1   | `--javac-args`
+ * 2   | A.java
+ * 3   | B.java
+ * 4   | C.java
+ */
+#keyset[id, num]
+compilation_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@@@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+    int id : @compilation ref,
+    int num : int ref,
+    string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ *   javac A.java B.java C.java
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0   | A.java
+ * 1   | B.java
+ * 2   | C.java
+ */
+#keyset[id, num]
+compilation_compiling_files(
+    int id : @compilation ref,
+    int num : int ref,
+    int file : @file ref
+);
+
+/**
+ * For each file recorded in `compilation_compiling_files`,
+ * there will be a corresponding row in
+ * `compilation_compiling_files_completed` once extraction
+ * of that file is complete. The `result` will indicate the
+ * extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+#keyset[id, num]
+compilation_compiling_files_completed(
+    int id : @compilation ref,
+    int num : int ref,
+    int result : int ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1    | CPU seconds used by the extractor frontend
+ * 2    | Elapsed seconds during the extractor frontend
+ * 3    | CPU seconds used by the extractor backend
+ * 4    | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+    int id : @compilation ref,
+    int num : int ref,
+    /* kind:
+       1 = frontend_cpu_seconds
+       2 = frontend_elapsed_seconds
+       3 = extractor_cpu_seconds
+       4 = extractor_elapsed_seconds
+    */
+    int kind : int ref,
+    float seconds : float ref
+);
+
+/**
+ * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed
+ * time (respectively) that the original compilation (not the extraction)
+ * took for compiler invocation `id`.
+ */
+compilation_compiler_times(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ * The `result` will indicate the extraction result:
+ *
+ *     0: Successfully extracted
+ *     1: Errors were encountered, but extraction recovered
+ *     2: Errors were encountered, and extraction could not recover
+ */
+compilation_finished(
+    unique int id : @compilation ref,
+    float cpu_seconds : float ref,
+    float elapsed_seconds : float ref,
+    int result : int ref
+);
+
+diagnostics(
+    unique int id: @diagnostic,
+    string generated_by: string ref, // TODO: Sync this with the other languages?
+    int severity: int ref,
+    string error_tag: string ref,
+    string error_message: string ref,
+    string full_error_message: string ref,
+    int location: @location_default ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+    unique int diagnostic : @diagnostic ref,
+    int compilation : @compilation ref,
+    int file_number : int ref,
+    int file_number_diagnostic_number : int ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalData(
+  int id : @externalDataElement,
+  string path : string ref,
+  int column: int ref,
+  string value : string ref
+);
+
+sourceLocationPrefix(
+  string prefix : string ref
+);
+
+databaseMetadata(
+  string metadataKey : string ref,
+  string value : string ref
+);
+
+/*
+ * SMAP
+ */
+
+smap_header(
+  int outputFileId: @file ref,
+  string outputFilename: string ref,
+  string defaultStratum: string ref
+);
+
+smap_files(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  string inputFileName: string ref,
+  int inputFileId: @file ref
+);
+
+smap_lines(
+  int outputFileId: @file ref,
+  string stratum: string ref,
+  int inputFileNum: int ref,
+  int inputStartLine: int ref,
+  int inputLineCount: int ref,
+  int outputStartLine: int ref,
+  int outputLineIncrement: int ref
+);
+
+/*
+ * Locations and files
+ */
+
+@location = @location_default ;
+
+locations_default(
+  unique int id: @location_default,
+  int file: @file ref,
+  int beginLine: int ref,
+  int beginColumn: int ref,
+  int endLine: int ref,
+  int endColumn: int ref
+);
+
+hasLocation(
+  int locatableid: @locatable ref,
+  int id: @location ref
+);
+
+@sourceline = @locatable ;
+
+#keyset[element_id]
+numlines(
+  int element_id: @sourceline ref,
+  int num_lines: int ref,
+  int num_code: int ref,
+  int num_comment: int ref
+);
+
+files(
+  unique int id: @file,
+  string name: string ref
+);
+
+folders(
+  unique int id: @folder,
+  string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+  int parent: @container ref,
+  unique int child: @container ref
+);
+
+/*
+ * Java
+ */
+
+cupackage(
+  unique int id: @file ref,
+  int packageid: @package ref
+);
+
+#keyset[fileid,keyName]
+jarManifestMain(
+  int fileid: @file ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+#keyset[fileid,entryName,keyName]
+jarManifestEntries(
+  int fileid: @file ref,
+  string entryName: string ref,
+  string keyName: string ref,
+  string value: string ref
+);
+
+packages(
+  unique int id: @package,
+  string nodeName: string ref
+);
+
+primitives(
+  unique int id: @primitive,
+  string nodeName: string ref
+);
+
+modifiers(
+  unique int id: @modifier,
+  string nodeName: string ref
+);
+
+/**
+ * An errortype is used when the extractor is unable to extract a type
+ * correctly for some reason.
+ */
+error_type(
+  unique int id: @errortype
+);
+
+classes_or_interfaces(
+  unique int id: @classorinterface,
+  string nodeName: string ref,
+  int parentid: @package ref,
+  int sourceid: @classorinterface ref
+);
+
+file_class(
+  int id: @classorinterface ref
+);
+
+class_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref
+);
+
+type_companion_object(
+  unique int id: @classorinterface ref,
+  unique int instance: @field ref,
+  unique int companion_object: @classorinterface ref
+);
+
+kt_nullable_types(
+  unique int id: @kt_nullable_type,
+  int classid: @reftype ref
+)
+
+kt_notnull_types(
+  unique int id: @kt_notnull_type,
+  int classid: @reftype ref
+)
+
+kt_type_alias(
+  unique int id: @kt_type_alias,
+  string name: string ref,
+  int kttypeid: @kt_type ref
+)
+
+@kt_type = @kt_nullable_type | @kt_notnull_type
+
+isInterface(
+  unique int id: @classorinterface ref
+);
+
+isRecord(
+  unique int id: @classorinterface ref
+);
+
+fielddecls(
+  unique int id: @fielddecl,
+  int parentid: @reftype ref
+);
+
+#keyset[fieldId] #keyset[fieldDeclId,pos]
+fieldDeclaredIn(
+  int fieldId: @field ref,
+  int fieldDeclId: @fielddecl ref,
+  int pos: int ref
+);
+
+fields(
+  unique int id: @field,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref
+);
+
+fieldsKotlinType(
+  unique int id: @field ref,
+  int kttypeid: @kt_type ref
+);
+
+constrs(
+  unique int id: @constructor,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @constructor ref
+);
+
+constrsKotlinType(
+  unique int id: @constructor ref,
+  int kttypeid: @kt_type ref
+);
+
+methods(
+  unique int id: @method,
+  string nodeName: string ref,
+  string signature: string ref,
+  int typeid: @type ref,
+  int parentid: @reftype ref,
+  int sourceid: @method ref
+);
+
+methodsKotlinType(
+  unique int id: @method ref,
+  int kttypeid: @kt_type ref
+);
+
+#keyset[parentid,pos]
+params(
+  unique int id: @param,
+  int typeid: @type ref,
+  int pos: int ref,
+  int parentid: @callable ref,
+  int sourceid: @param ref
+);
+
+paramsKotlinType(
+  unique int id: @param ref,
+  int kttypeid: @kt_type ref
+);
+
+paramName(
+  unique int id: @param ref,
+  string nodeName: string ref
+);
+
+isVarargsParam(
+  int param: @param ref
+);
+
+exceptions(
+  unique int id: @exception,
+  int typeid: @type ref,
+  int parentid: @callable ref
+);
+
+isAnnotType(
+  int interfaceid: @classorinterface ref
+);
+
+isAnnotElem(
+  int methodid: @method ref
+);
+
+annotValue(
+  int parentid: @annotation ref,
+  int id2: @method ref,
+  unique int value: @expr ref
+);
+
+isEnumType(
+  int classid: @classorinterface ref
+);
+
+isEnumConst(
+  int fieldid: @field ref
+);
+
+#keyset[parentid,pos]
+typeVars(
+  unique int id: @typevariable,
+  string nodeName: string ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+wildcards(
+  unique int id: @wildcard,
+  string nodeName: string ref,
+  int kind: int ref
+);
+
+#keyset[parentid,pos]
+typeBounds(
+  unique int id: @typebound,
+  int typeid: @reftype ref,
+  int pos: int ref,
+  int parentid: @boundedtype ref
+);
+
+#keyset[parentid,pos]
+typeArgs(
+  int argumentid: @reftype ref,
+  int pos: int ref,
+  int parentid: @classorinterfaceorcallable ref
+);
+
+isParameterized(
+  int memberid: @member ref
+);
+
+isRaw(
+  int memberid: @member ref
+);
+
+#keyset[classid] #keyset[parent]
+isAnonymClass(
+  int classid: @classorinterface ref,
+  int parent: @classinstancexpr ref
+);
+
+#keyset[typeid] #keyset[parent]
+isLocalClassOrInterface(
+  int typeid: @classorinterface ref,
+  int parent: @localtypedeclstmt ref
+);
+
+isDefConstr(
+  int constructorid: @constructor ref
+);
+
+#keyset[exprId]
+lambdaKind(
+  int exprId: @lambdaexpr ref,
+  int bodyKind: int ref
+);
+
+isCanonicalConstr(
+  int constructorid: @constructor ref
+);
+
+arrays(
+  unique int id: @array,
+  string nodeName: string ref,
+  int elementtypeid: @type ref,
+  int dimension: int ref,
+  int componenttypeid: @type ref
+);
+
+enclInReftype(
+  unique int child: @reftype ref,
+  int parent: @reftype ref
+);
+
+extendsReftype(
+  int id1: @reftype ref,
+  int id2: @classorinterface ref
+);
+
+implInterface(
+  int id1: @classorarray ref,
+  int id2: @classorinterface ref
+);
+
+permits(
+  int id1: @classorinterface ref,
+  int id2: @classorinterface ref
+);
+
+hasModifier(
+  int id1: @modifiable ref,
+  int id2: @modifier ref
+);
+
+imports(
+  unique int id: @import,
+  int holder: @classorinterfaceorpackage ref,
+  string name: string ref,
+  int kind: int ref
+);
+
+#keyset[parent,idx]
+stmts(
+  unique int id: @stmt,
+  int kind: int ref,
+  int parent: @stmtparent ref,
+  int idx: int ref,
+  int bodydecl: @callable ref
+);
+
+@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr;
+
+case @stmt.kind of
+  0 = @block
+| 1 = @ifstmt
+| 2 = @forstmt
+| 3 = @enhancedforstmt
+| 4 = @whilestmt
+| 5 = @dostmt
+| 6 = @trystmt
+| 7 = @switchstmt
+| 8 = @synchronizedstmt
+| 9 = @returnstmt
+| 10 = @throwstmt
+| 11 = @breakstmt
+| 12 = @continuestmt
+| 13 = @emptystmt
+| 14 = @exprstmt
+| 15 = @labeledstmt
+| 16 = @assertstmt
+| 17 = @localvariabledeclstmt
+| 18 = @localtypedeclstmt
+| 19 = @constructorinvocationstmt
+| 20 = @superconstructorinvocationstmt
+| 21 = @case
+| 22 = @catchclause
+| 23 = @yieldstmt
+| 24 = @errorstmt
+| 25 = @whenbranch
+;
+
+#keyset[parent,idx]
+exprs(
+  unique int id: @expr,
+  int kind: int ref,
+  int typeid: @type ref,
+  int parent: @exprparent ref,
+  int idx: int ref
+);
+
+exprsKotlinType(
+  unique int id: @expr ref,
+  int kttypeid: @kt_type ref
+);
+
+callableEnclosingExpr(
+  unique int id: @expr ref,
+  int callable_id: @callable ref
+);
+
+statementEnclosingExpr(
+  unique int id: @expr ref,
+  int statement_id: @stmt ref
+);
+
+isParenthesized(
+  unique int id: @expr ref,
+  int parentheses: int ref
+);
+
+case @expr.kind of
+   1  = @arrayaccess
+|  2  = @arraycreationexpr
+|  3  = @arrayinit
+|  4  = @assignexpr
+|  5  = @assignaddexpr
+|  6  = @assignsubexpr
+|  7  = @assignmulexpr
+|  8  = @assigndivexpr
+|  9  = @assignremexpr
+| 10  = @assignandexpr
+| 11  = @assignorexpr
+| 12  = @assignxorexpr
+| 13  = @assignlshiftexpr
+| 14  = @assignrshiftexpr
+| 15  = @assignurshiftexpr
+| 16  = @booleanliteral
+| 17  = @integerliteral
+| 18  = @longliteral
+| 19  = @floatingpointliteral
+| 20  = @doubleliteral
+| 21  = @characterliteral
+| 22  = @stringliteral
+| 23  = @nullliteral
+| 24  = @mulexpr
+| 25  = @divexpr
+| 26  = @remexpr
+| 27  = @addexpr
+| 28  = @subexpr
+| 29  = @lshiftexpr
+| 30  = @rshiftexpr
+| 31  = @urshiftexpr
+| 32  = @andbitexpr
+| 33  = @orbitexpr
+| 34  = @xorbitexpr
+| 35  = @andlogicalexpr
+| 36  = @orlogicalexpr
+| 37  = @ltexpr
+| 38  = @gtexpr
+| 39  = @leexpr
+| 40  = @geexpr
+| 41  = @eqexpr
+| 42  = @neexpr
+| 43  = @postincexpr
+| 44  = @postdecexpr
+| 45  = @preincexpr
+| 46  = @predecexpr
+| 47  = @minusexpr
+| 48  = @plusexpr
+| 49  = @bitnotexpr
+| 50  = @lognotexpr
+| 51  = @castexpr
+| 52  = @newexpr
+| 53  = @conditionalexpr
+| 54  = @parexpr         // deprecated
+| 55  = @instanceofexpr
+| 56  = @localvariabledeclexpr
+| 57  = @typeliteral
+| 58  = @thisaccess
+| 59  = @superaccess
+| 60  = @varaccess
+| 61  = @methodaccess
+| 62  = @unannotatedtypeaccess
+| 63  = @arraytypeaccess
+| 64  = @packageaccess
+| 65  = @wildcardtypeaccess
+| 66  = @declannotation
+| 67  = @uniontypeaccess
+| 68  = @lambdaexpr
+| 69  = @memberref
+| 70  = @annotatedtypeaccess
+| 71  = @typeannotation
+| 72  = @intersectiontypeaccess
+| 73  = @switchexpr
+| 74  = @errorexpr
+| 75  = @whenexpr
+| 76  = @getclassexpr
+| 77  = @safecastexpr
+| 78  = @implicitcastexpr
+| 79  = @implicitnotnullexpr
+| 80  = @implicitcoerciontounitexpr
+| 81  = @notinstanceofexpr
+| 82  = @stmtexpr
+| 83  = @stringtemplateexpr
+| 84  = @notnullexpr
+| 85  = @unsafecoerceexpr
+| 86  = @valueeqexpr
+| 87  = @valueneexpr
+| 88  = @propertyref
+| 89  = @recordpatternexpr
+;
+
+/** Holds if this `when` expression was written as an `if` expression. */
+when_if(unique int id: @whenexpr ref);
+
+/** Holds if this `when` branch was written as an `else` branch. */
+when_branch_else(unique int id: @whenbranch ref);
+
+@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref
+
+@annotation = @declannotation | @typeannotation
+@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess
+
+@assignment = @assignexpr
+             | @assignop;
+
+@unaryassignment = @postincexpr
+                 | @postdecexpr
+                 | @preincexpr
+                 | @predecexpr;
+
+@assignop = @assignaddexpr
+             | @assignsubexpr
+             | @assignmulexpr
+             | @assigndivexpr
+             | @assignremexpr
+             | @assignandexpr
+             | @assignorexpr
+             | @assignxorexpr
+             | @assignlshiftexpr
+             | @assignrshiftexpr
+             | @assignurshiftexpr;
+
+@literal = @booleanliteral
+             | @integerliteral
+             | @longliteral
+             | @floatingpointliteral
+             | @doubleliteral
+             | @characterliteral
+             | @stringliteral
+             | @nullliteral;
+
+@binaryexpr = @mulexpr
+             | @divexpr
+             | @remexpr
+             | @addexpr
+             | @subexpr
+             | @lshiftexpr
+             | @rshiftexpr
+             | @urshiftexpr
+             | @andbitexpr
+             | @orbitexpr
+             | @xorbitexpr
+             | @andlogicalexpr
+             | @orlogicalexpr
+             | @ltexpr
+             | @gtexpr
+             | @leexpr
+             | @geexpr
+             | @eqexpr
+             | @neexpr
+             | @valueeqexpr
+             | @valueneexpr;
+
+@unaryexpr =   @postincexpr
+             | @postdecexpr
+             | @preincexpr
+             | @predecexpr
+             | @minusexpr
+             | @plusexpr
+             | @bitnotexpr
+             | @lognotexpr
+             | @notnullexpr;
+
+@caller =  @classinstancexpr
+         | @methodaccess
+         | @constructorinvocationstmt
+         | @superconstructorinvocationstmt;
+
+callableBinding(
+  unique int callerid: @caller ref,
+  int callee: @callable ref
+);
+
+memberRefBinding(
+  unique int id: @expr ref,
+  int callable: @callable ref
+);
+
+propertyRefGetBinding(
+  unique int id: @expr ref,
+  int getter: @callable ref
+);
+
+propertyRefFieldBinding(
+  unique int id: @expr ref,
+  int field: @field ref
+);
+
+propertyRefSetBinding(
+  unique int id: @expr ref,
+  int setter: @callable ref
+);
+
+@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @classorinterface | @param | @localvar | @typevariable;
+
+variableBinding(
+  unique int expr: @varaccess ref,
+  int variable: @variable ref
+);
+
+@variable = @localscopevariable | @field;
+
+@localscopevariable = @localvar | @param;
+
+localvars(
+  unique int id: @localvar,
+  string nodeName: string ref,
+  int typeid: @type ref,
+  int parentid: @localvariabledeclexpr ref
+);
+
+localvarsKotlinType(
+  unique int id: @localvar ref,
+  int kttypeid: @kt_type ref
+);
+
+@namedexprorstmt = @breakstmt
+                 | @continuestmt
+                 | @labeledstmt
+                 | @literal;
+
+namestrings(
+  string name: string ref,
+  string value: string ref,
+  unique int parent: @namedexprorstmt ref
+);
+
+/*
+ * Modules
+ */
+
+#keyset[name]
+modules(
+  unique int id: @module,
+  string name: string ref
+);
+
+isOpen(
+  int id: @module ref
+);
+
+#keyset[fileId]
+cumodule(
+  int fileId: @file ref,
+  int moduleId: @module ref
+);
+
+@directive = @requires
+           | @exports
+           | @opens
+           | @uses
+           | @provides
+
+#keyset[directive]
+directives(
+  int id: @module ref,
+  int directive: @directive ref
+);
+
+requires(
+  unique int id: @requires,
+  int target: @module ref
+);
+
+isTransitive(
+  int id: @requires ref
+);
+
+isStatic(
+  int id: @requires ref
+);
+
+exports(
+  unique int id: @exports,
+  int target: @package ref
+);
+
+exportsTo(
+  int id: @exports ref,
+  int target: @module ref
+);
+
+opens(
+  unique int id: @opens,
+  int target: @package ref
+);
+
+opensTo(
+  int id: @opens ref,
+  int target: @module ref
+);
+
+uses(
+  unique int id: @uses,
+  string serviceInterface: string ref
+);
+
+provides(
+  unique int id: @provides,
+  string serviceInterface: string ref
+);
+
+providesWith(
+  int id: @provides ref,
+  string serviceImpl: string ref
+);
+
+isNullDefaultCase(
+  int id: @case ref
+);
+
+/*
+ * Javadoc
+ */
+
+javadoc(
+  unique int id: @javadoc
+);
+
+isNormalComment(
+  int commentid : @javadoc ref
+);
+
+isEolComment(
+  int commentid : @javadoc ref
+);
+
+hasJavadoc(
+  int documentableid: @member ref,
+  int javadocid: @javadoc ref
+);
+
+#keyset[parentid,idx]
+javadocTag(
+  unique int id: @javadocTag,
+  string name: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+#keyset[parentid,idx]
+javadocText(
+  unique int id: @javadocText,
+  string text: string ref,
+  int parentid: @javadocParent ref,
+  int idx: int ref
+);
+
+@javadocParent = @javadoc | @javadocTag;
+@javadocElement = @javadocTag | @javadocText;
+
+@classorinterfaceorpackage = @classorinterface | @package;
+@classorinterfaceorcallable = @classorinterface | @callable;
+@boundedtype = @typevariable | @wildcard;
+@reftype = @classorinterface | @array | @boundedtype | @errortype;
+@classorarray = @classorinterface | @array;
+@type = @primitive | @reftype;
+@callable = @method | @constructor;
+
+/** A program element that has a name. */
+@element = @package | @modifier | @annotation | @errortype |
+           @locatableElement;
+
+@locatableElement = @file | @primitive | @classorinterface | @method | @constructor | @param | @exception | @field |
+                    @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias |
+                    @kt_property;
+
+@modifiable = @member_modifiable| @param | @localvar | @typevariable;
+
+@member_modifiable = @classorinterface | @method | @constructor | @field | @kt_property;
+
+@member = @method | @constructor | @field | @reftype ;
+
+/** A program element that has a location. */
+@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment |
+             @locatableElement;
+
+@top = @element | @locatable | @folder;
+
+/*
+ * XML Files
+ */
+
+xmlEncoding(
+  unique int id: @file ref,
+  string encoding: string ref
+);
+
+xmlDTDs(
+  unique int id: @xmldtd,
+  string root: string ref,
+  string publicId: string ref,
+  string systemId: string ref,
+  int fileid: @file ref
+);
+
+xmlElements(
+  unique int id: @xmlelement,
+  string name: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlAttrs(
+  unique int id: @xmlattribute,
+  int elementid: @xmlelement ref,
+  string name: string ref,
+  string value: string ref,
+  int idx: int ref,
+  int fileid: @file ref
+);
+
+xmlNs(
+  int id: @xmlnamespace,
+  string prefixName: string ref,
+  string URI: string ref,
+  int fileid: @file ref
+);
+
+xmlHasNs(
+  int elementId: @xmlnamespaceable ref,
+  int nsId: @xmlnamespace ref,
+  int fileid: @file ref
+);
+
+xmlComments(
+  unique int id: @xmlcomment,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int fileid: @file ref
+);
+
+xmlChars(
+  unique int id: @xmlcharacters,
+  string text: string ref,
+  int parentid: @xmlparent ref,
+  int idx: int ref,
+  int isCDATA: int ref,
+  int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+  int xmlElement: @xmllocatable ref,
+  int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/*
+ * configuration files with key value pairs
+ */
+
+configs(
+  unique int id: @config
+);
+
+configNames(
+  unique int id: @configName,
+  int config: @config ref,
+  string name: string ref
+);
+
+configValues(
+  unique int id: @configValue,
+  int config: @config ref,
+  string value: string ref
+);
+
+configLocations(
+  int locatable: @configLocatable ref,
+  int location: @location_default ref
+);
+
+@configLocatable = @config | @configName | @configValue;
+
+ktComments(
+  unique int id: @ktcomment,
+  int kind: int ref,
+  string text : string ref
+)
+
+ktCommentSections(
+  unique int id: @ktcommentsection,
+  int comment: @ktcomment ref,
+  string content : string ref
+)
+
+ktCommentSectionNames(
+  unique int id: @ktcommentsection ref,
+  string name : string ref
+)
+
+ktCommentSectionSubjectNames(
+  unique int id: @ktcommentsection ref,
+  string subjectname : string ref
+)
+
+#keyset[id, owner]
+ktCommentOwners(
+  int id: @ktcomment ref,
+  int owner: @top ref
+)
+
+ktExtensionFunctions(
+  unique int id: @method ref,
+  int typeid: @type ref,
+  int kttypeid: @kt_type ref
+)
+
+ktProperties(
+  unique int id: @kt_property,
+  string nodeName: string ref
+)
+
+ktPropertyGetters(
+  unique int id: @kt_property ref,
+  int getter: @method ref
+)
+
+ktPropertySetters(
+  unique int id: @kt_property ref,
+  int setter: @method ref
+)
+
+ktPropertyBackingFields(
+  unique int id: @kt_property ref,
+  int backingField: @field ref
+)
+
+ktSyntheticBody(
+  unique int id: @callable ref,
+  int kind: int ref
+  // 1: ENUM_VALUES
+  // 2: ENUM_VALUEOF
+  // 3: ENUM_ENTRIES
+)
+
+ktLocalFunction(
+  unique int id: @method ref
+)
+
+ktInitializerAssignment(
+  unique int id: @assignexpr ref
+)
+
+ktPropertyDelegates(
+  unique int id: @kt_property ref,
+  unique int variableId: @variable ref
+)
+
+/**
+ * If `id` is a compiler generated element, then the kind indicates the
+ * reason that the compiler generated it.
+ * See `Element.compilerGeneratedReason()` for an explanation of what
+ * each `kind` means.
+ */
+compiler_generated(
+  unique int id: @element ref,
+  int kind: int ref
+)
+
+ktFunctionOriginalNames(
+  unique int id: @method ref,
+  string name: string ref
+)
+
+ktDataClasses(
+  unique int id: @classorinterface ref
+)
diff --git a/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/upgrade.properties b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/upgrade.properties
new file mode 100644
index 000000000000..9b83871fb9b6
--- /dev/null
+++ b/java/ql/lib/upgrades/1fd1afa7862b82955785edd29820054ab6c9ec81/upgrade.properties
@@ -0,0 +1,2 @@
+description: Add databaseMetadata relation
+compatibility: full