2026-07-10 The Goodhart Law
Coordinating with David Chavez and the other folks: https://github.com/kg-construct/rml-core/issues/266
test: add RML-Core RDB test cases (RMLTC0000-RMLTC0021a)
Port the 59 PostgreSQL test cases removed from rml-core in kg-construct/rml-core@2a232cf ("test-cases: only keep JSON") as RMLTC*-RDB, following the guidance in kg-construct/rml-core#266.
Deviations from the removed snapshot:
- RMLTC0007h: objectMap references FirstName and graphMap references ID instead of the non-existent Name column, so the only intended error is the literal graph term (mirrors kg-construct/rml-core#143)
- RMLTC0019a, RMLTC0020a: expected outputs resolve relative IRIs against http://example.com/ instead of http://example.com/base/ (mirrors kg-construct/rml-core#223)
- RMLTC0002e, RMLTC0002g, RMLTC0002h, RMLTC0003a: object maps reference ID instead of the undefined IDs, so each error test fails for one reason only (mirrors the fixes to the JSON variants)
- RMLTC0002h: the SQL query duplicates the "ID" column via an alias, as in R2RMLTC0002h, instead of an unquoted query that fails on PostgreSQL before the duplicate-name check is reached
- RMLTC0003a: the undefined SQL version identifier is expressed as the undefined reference formulation rml:SQL2000Query with a valid query, matching the intent of R2RMLTC0003a
- RMLTC0002i, RMLTC0002j: the queries select the "ID" and "Name" columns the mapping references (qualified names in 0002j, per R2RMLTC0002j); the expected id literal is typed xsd:integer per the SQL natural mapping
- RMLTC0005a, RMLTC0005b, RMLTC0012e, RMLTC0016b: xsd:double literals use decimal notation, matching the registry convention
- RMLTC0015b: references use the lowercase names produced by the unquoted DDL, as in RMLTC0015a, and the second query filters Lan = 'ES'; the only intended errors are the invalid language tags
- RMLTC0019b: the table keeps only the row with the data error, as in the current JSON variant
- RMLTC0002f: PostgreSQL JDBC driver and user instead of MySQL
- RMLTC0004a: dropped a stray student_sport.csv from the CSV variant
All resource.sql files load and all SQL2008Query iterators behave as expected on PostgreSQL 16; mappings and expected outputs parse as Turtle/N-Quads.
test: add missing BlankNode termType to RMLTC0001b-RDB
The PostgreSQL variant of RMLTC0001b never had the rml:termType rml:BlankNode subject since the original import into rml-core (0ff3dc8), diverging from both R2RMLTC0001b and RMLTC0001b-JSON, which generate a blank node subject as the test title states.
test: restore delimited identifier scenario in RMLTC0002f-RDB
The PostgreSQL variant inherited from rml-core inverted the scenario of R2RMLTC0002f: the DDL used regular identifiers while the mapping referenced everything as delimited.
Restore the original design: delimited identifiers in the DDL and in rml:iterator/rml:reference, regular identifiers only in the subject template, which is the non-conforming reference under test.
Drop the "Within rr:template ID is ok, but Name is not" sentence from the description: it only holds under standard SQL uppercase folding, while PostgreSQL folds regular identifiers to lowercase and rejects both references.
Note: RMLMapper v8.0.1 does not reject the non-conforming template and materializes output for this mapping, exactly as it does for R2RMLTC0002f.
feat(conformance): support rml io registry rdb tests
Switch the RML conformance suite to the rml-io-registry RDB fork and add handling for the new RML vocabulary used by those cases.
fix(benchmark): reduce redundant subject-map queries
KROWN Mappings scenarios repeat the same predicate-object maps across multiple subject templates. Reusing every equivalent subject group made the generated SPARQL query grow unnecessary
Select one reducible subject group per predicate-object signature before building the query, keep non-reducible groups, and publish the updated benchmark results.
Let’s take the case with 5 TM and 8 POM
TM1 subject {p1}, -> p1...p8TM2 subject {p2}, -> p1...p8...TM5 subject {p5}, -> p1...p8All columns used in the subjects, p1…p5, are already available as literal objects in every TM. We don’t need 5 groups to rebuild the row. We can take only one representative subject map.
This optimization made mappings_5_8 go from 36,35s to 6,30s
I only considered the cases where TM < POM, otherwise it’s impossible to associate a value to a specific TM and, therefore, to a specific column/row
TM1: subject /table/{p1}, -> p1 e p2TM2: subject /table/{p2}, -> p1 e p2TM3: subject /table/{p3}, -> p1 e p2These three subject templates have the same structure. There is no way to understand from the graph that p3 comes from TM3.
feat(benchmarks): add gtfs benchmark