Shared: Add support for provenance pretty-printing as a qltest postprocess step.

This commit is contained in:
Anders Schack-Mulligen
2024-07-18 11:28:48 +02:00
parent a9bf17ef49
commit 94078e851c
6 changed files with 95 additions and 36 deletions

View File

@@ -9,6 +9,8 @@ module;
signature predicate interpretModelForTestSig(QlBuiltins::ExtensionId madId, string model);
signature predicate queryResultsSig(string relation, int row, int column, string data);
signature class PathNodeSig {
string toString();
}
@@ -28,14 +30,14 @@ signature module PathGraphSig<PathNodeSig PathNode> {
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}
/** Transforms a `PathGraph` by printing the provenance information. */
module ShowProvenance<
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
PathGraphSig<PathNode> PathGraph>
private signature predicate provenanceSig(string model);
private module TranslateModels<
interpretModelForTestSig/2 interpretModelForTest, provenanceSig/1 provenance>
{
private predicate madIds(string madId) {
exists(string model |
PathGraph::edges(_, _, _, model) and
provenance(model) and
model.regexpFind("(?<=MaD:)[0-9]*", _, _) = madId
)
}
@@ -44,14 +46,15 @@ module ShowProvenance<
madId = rank[r](string madId0 | madIds(madId0) | madId0 order by madId0.toInt())
}
query predicate models(int r, string model) {
/** Lists the renumbered and pretty-printed models used in the edges relation. */
predicate models(int r, string model) {
exists(QlBuiltins::ExtensionId madId |
rankedMadIds(madId.toString(), r) and interpretModelForTest(madId, model)
)
}
private predicate translateModelsPart(string model1, string model2, int i) {
PathGraph::edges(_, _, _, model1) and
provenance(model1) and
exists(string s | model1.splitAt("MaD:", i) = s |
model2 = s and i = 0
or
@@ -65,17 +68,29 @@ module ShowProvenance<
)
}
private predicate translateModels(string model1, string model2) {
predicate translateModels(string model1, string model2) {
exists(int i |
translateModelsPart(model1, model2, i) and
not translateModelsPart(model1, _, i + 1)
)
}
}
/** Transforms a `PathGraph` by printing the provenance information. */
module ShowProvenance<
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
PathGraphSig<PathNode> PathGraph>
{
private predicate provenance(string model) { PathGraph::edges(_, _, _, model) }
private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;
query predicate models(int r, string model) { Models::models(r, model) }
query predicate edges(PathNode a, PathNode b, string key, string val) {
exists(string model |
PathGraph::edges(a, b, key, model) and
translateModels(model, val)
Models::translateModels(model, val)
)
}
@@ -83,3 +98,36 @@ module ShowProvenance<
query predicate subpaths = PathGraph::subpaths/4;
}
/** Transforms a `PathGraph` by printing the provenance information. */
module TranslateProvenanceResults<
interpretModelForTestSig/2 interpretModelForTest, queryResultsSig/4 queryResults>
{
private int provenanceColumn() { result = 5 }
private predicate provenance(string model) { queryResults("edges", _, provenanceColumn(), model) }
private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;
predicate results(string relation, int row, int column, string data) {
queryResults(relation, row, column, data) and
(relation != "edges" or column != provenanceColumn())
or
exists(string model |
relation = "edges" and
column = provenanceColumn() and
queryResults(relation, row, column, model) and
Models::translateModels(model, data)
)
or
exists(int r, string model |
Models::models(r, model) and
relation = "models" and
row = r
|
column = 0 and data = r.toString()
or
column = 1 and data = model
)
}
}