Daniel Heward-Mills · OpenLink Community, June 1, 2026

Introducing RDF 1.2 Support in Virtuoso

Triple terms, reifiers, and annotation syntax bring standards-based statement provenance to Virtuoso via RDF 1.2 and SPARQL 1.2.

Executive SummaryBy Daniel Heward-Mills · OpenLink Software · 2026-06-01

Synopsis

Organizations routinely need to answer questions a plain RDF triple cannot: where a fact came from, when it was verified, who asserted it, and how trustworthy it is. Before RDF 1.2, developers reached for standard reification, n-ary relations, or singleton properties to attach that metadata — each solved the immediate problem but introduced its own verbosity, lost-triple, or predicate-explosion tradeoff. RDF 1.2 replaces all three with a single standardized mechanism.

Virtuoso now implements that mechanism directly: triple terms let a statement be referenced as a value, reifiers attach source/date/confidence metadata to it without disturbing the base triple, and the compact annotation syntax lets both be written in one line. SPARQL 1.2 extends the query language to match — INSERT DATA, TRIPLE(), SUBJECT()/PREDICATE()/OBJECT(), and isTRIPLE() all operate on triple terms directly — so provenance, confidence, and verification data become first-class, standards-based, and queryable rather than a bespoke application convention.

View this analysis as a KG entity
People

People

Organizations

Organizations

Knowledge Graph Explorer 126 nodes · 257 links

Interactive graph visualization derived from the companion RDF. Click nodes to resolve, drag to explore. Graph data embedded from companion RDF at generation time.

Introducing RDF 1.2 Support in Virtuoso

Nodes: 0 Links: 0
Click SVG to activate zoom, click outside to release | Drag nodes to pin, double-click to unpin
Classes Properties Instances

SPARQL Workbench 6 sample queries

Query this knowledge graph on URIBurner. The editor opens on the canonical SAMPLE entity-type summary (DAV named graph). Pick a recipe, edit freely, then run live or copy.

Sample Queries

Reproduced verbatim from the companion RDF. Execute loads the query into the workbench below and runs it live.

A Triple Represented Directly as a Value
PREFIX : <https://community.openlinksw.com/t/introducing-rdf-1-2-support-in-virtuoso/6283/data#>

SELECT (<< :alice :worksFor :AcmeCorp >> AS ?statement) WHERE {}
SPARQL 1.2 SELECT Constructing a Triple Term with TRIPLE()
PREFIX : <https://community.openlinksw.com/t/introducing-rdf-1-2-support-in-virtuoso/6283/data#>

SELECT ?statement WHERE {
  GRAPH <https://linkeddata.uriburner.com/DAV/demos/daas/rdf-1-2-support-in-virtuoso-claude_sonnet_5-1.ttl> {
    ?person :worksFor ?org .
    BIND(TRIPLE(?person, :worksFor, ?org) AS ?statement)
  }
}
SPARQL 1.2 FILTER Using SUBJECT()/PREDICATE()/OBJECT()
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX : <https://community.openlinksw.com/t/introducing-rdf-1-2-support-in-virtuoso/6283/data#>

SELECT ?reifier WHERE {
  GRAPH <https://linkeddata.uriburner.com/DAV/demos/daas/rdf-1-2-support-in-virtuoso-claude_sonnet_5-1.ttl> {
    ?reifier rdf:reifies ?stmt ;
             :source :HRSystem .
    FILTER (SUBJECT(?stmt) = :alice && PREDICATE(?stmt) = :worksFor)
  }
}
SPARQL 1.2 FILTER Using isTRIPLE()
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?reifier ?stmt WHERE {
  GRAPH <https://linkeddata.uriburner.com/DAV/demos/daas/rdf-1-2-support-in-virtuoso-claude_sonnet_5-1.ttl> {
    ?reifier rdf:reifies ?stmt .
    FILTER isTRIPLE(?stmt)
  }
}
SPARQL 1.2 CONSTRUCT Producing Triple Terms
PREFIX : <https://community.openlinksw.com/t/introducing-rdf-1-2-support-in-virtuoso/6283/data#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

CONSTRUCT {
  :provenanceReport rdf:reifies ?stmt ;
                     :confidence ?confidence .
}
WHERE {
  GRAPH <https://linkeddata.uriburner.com/DAV/demos/daas/rdf-1-2-support-in-virtuoso-claude_sonnet_5-1.ttl> {
    ?person :worksFor ?org {| :confidence ?confidence |} .
    BIND(TRIPLE(?person, :worksFor, ?org) AS ?stmt)
  }
}
SPARQL 1.2 VALUES With a Triple-Term Literal
PREFIX : <https://community.openlinksw.com/t/introducing-rdf-1-2-support-in-virtuoso/6283/data#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?reifier WHERE {
  GRAPH <https://linkeddata.uriburner.com/DAV/demos/daas/rdf-1-2-support-in-virtuoso-claude_sonnet_5-1.ttl> {
    VALUES ?stmt { << :alice :worksFor :AcmeCorp >> }
    ?reifier rdf:reifies ?stmt .
  }
}

Query editor

▶ Run live on URIBurner SELECT: text/x-html+tr | DESCRIBE/CONSTRUCT: text/x-html-nice-turtle
FAQ

Frequently Asked Questions

RDF 1.2 is the current W3C-standardized revision of the Resource Description Framework. It adds triple terms, reifiers, and annotation syntax so RDF statements themselves can be referenced and annotated with metadata such as provenance, confidence, and verification dates, without changing the base triple.

A triple term is an RDF triple written as a value using double angle brackets, e.g. << :alice :worksFor :AcmeCorp >>. It lets a statement be referenced from elsewhere in the graph, for example as the object of rdf:reifies.

A reifier is a resource related to a triple term through rdf:reifies. It carries metadata about the statement — source system, verification date, confidence score — while leaving the original triple untouched and directly queryable.

The annotation syntax lets you assert a triple and its metadata in a single compact statement, e.g. :alice :worksFor :AcmeCorp {| :source :HRSystem |} . It automatically creates an underlying reifier equivalent to writing the explicit rdf:reifies form by hand.

Standard reification (rdf:type rdf:Statement with rdf:subject/predicate/object) is verbose, does not clearly express who is making the claim (observer/scribe semantics), and is cumbersome for humans to author and maintain at scale.

N-ary relations work well when the relationship genuinely is a multi-participant event, but they remove the direct triple: every query has to traverse an intermediate resource even for the simple case of 'who works where'.

Singleton properties preserve a direct subject-predicate-object triple, but minting a unique predicate per occurrence (e.g. :worksFor_123) does not scale: large datasets can generate millions of one-off predicates that complicate querying, indexing, and reasoning.

Yes. RDF 1.2 explicitly separates the statement from the records describing it, so independent sources (e.g. an HR System and a Corporate Directory) can each attach their own reifier with its own provenance to the same underlying triple.

SPARQL 1.2 adds TRIPLE() to construct a triple term from three bound terms, SUBJECT()/PREDICATE()/OBJECT() to decompose a bound triple term, and isTRIPLE() to test whether a value is a triple term — usable in SELECT projections, BIND, FILTER, CONSTRUCT, and VALUES.

Use SPARQL 1.2 INSERT DATA with either the annotation shorthand (triple followed by {| ... |}) or the explicit reifier form (a resource with rdf:reifies << ... >>) inside a GRAPH <...> block, as shown in the two SPARQL 1.2 INSERT DATA reference examples on this page — note that anonymous SPARQL UPDATE against a public endpoint like URIBurner always requires authentication (401), so these are documented as reference syntax rather than presented as live-runnable Workbench queries.

Yes. Virtuoso now provides support for RDF 1.2 capabilities — triple terms, reifiers, annotation syntax, and SPARQL 1.2 query support — so developers can build graph applications on the latest RDF and SPARQL standards.

It answers questions organizations routinely need to ask about their data: where a fact came from, when it was verified, who asserted it, how trustworthy it is, and what evidence supports it — without inventing a bespoke, non-portable annotation scheme.

Glossary

Glossary of Terms

RDF 1.2

The W3C-standardized next major revision of the Resource Description Framework, adding triple terms, reifiers, and annotation syntax for statement-level metadata.

SPARQL 1.2

The companion query-language revision to RDF 1.2, adding triple-term literals, VALUES/FILTER/BIND support for triple terms, and the TRIPLE()/SUBJECT()/PREDICATE()/OBJECT()/isTRIPLE() functions.

Triple Term

An RDF triple used as a value, written << :s :p :o >>, that can be referenced as the object of rdf:reifies or as the subject/object of another statement.

Reifier

A resource linked to a triple term via rdf:reifies, used to attach source, date, and confidence metadata to a statement.

Annotation Syntax

RDF 1.2 Turtle shorthand ({| ... |}) that asserts a triple and creates its reifier in one statement.

Standard (RDF) Reification

The original RDF mechanism describing a statement via an rdf:Statement resource with rdf:subject, rdf:predicate, and rdf:object.

N-Ary Relation

A modeling pattern that turns a relationship into a first-class resource carrying all its participants and metadata as properties.

Singleton Property

A uniquely minted predicate created for one specific occurrence of a relationship so metadata can attach to the predicate itself.

Provenance

Information describing the origin of a piece of data: who asserted it, when, from what source, and how it was verified.

Named Graph

A collection of RDF triples identified by an IRI (e.g. urn:graph:employees), used to partition datasets, applications, or tenants within a single quad store.

SPARQL

The query-language companion to RDF 1.2, adding syntax and functions (TRIPLE, SUBJECT, PREDICATE, OBJECT, isTRIPLE) for working with triple terms.

Confidence Score

A numeric value (e.g. 0.98) attached to a statement via its reifier, expressing how trustworthy the asserted fact is judged to be.

Virtuoso

OpenLink Software's multi-model database/universal server, which now supports RDF 1.2 triple terms, reifiers, annotation syntax, and SPARQL 1.2 query features.

rdf:Statement

The RDF 1.0/1.1 class used by standard reification to represent a statement as a resource with rdf:subject/rdf:predicate/rdf:object properties.

How-To

How-To Guide

1

Identify the base relationship you need to annotate

Start with the plain, direct triple you want to keep queryable — for example :alice :worksFor :AcmeCorp . Do not fold it into an event node or a one-off predicate.

2

Decide what metadata needs to be attached

List the provenance facts required: source system, verification date, confidence score, or other evidence — the same fields the article attaches via :source and :verifiedOn.

3

Choose annotation syntax for a single quick assertion

For a one-shot, human-authored assertion, use the compact form: :alice :worksFor :AcmeCorp {| :source :HRSystem ; :verifiedOn \"2025-01-15\"^^xsd:date |} .

4

Choose an explicit reifier when the observation needs its own identifier

If the reifier itself will be referenced elsewhere in the domain model, mint a named resource with rdf:reifies << :alice :worksFor :AcmeCorp >> instead of relying on the auto-generated blank node.

5

Attach multiple independent reifiers for multiple sources

When more than one system confirms the same fact, create one reifier per source (e.g. :hrRecord, :directoryRecord) rather than merging their metadata onto a single record.

6

Insert annotated data into a named graph with SPARQL 1.2

Use INSERT DATA { GRAPH <urn:graph:employees> { ... } } with either the annotation shorthand or the explicit reifier form, as shown in the two SPARQL 1.2 INSERT DATA reference examples on this page — this requires an authenticated SPARQL UPDATE session, since anonymous INSERT against a public endpoint always fails with 401.

7

Query triple terms with SPARQL 1.2 functions

Use TRIPLE() to build triple terms in a projection, SUBJECT()/PREDICATE()/OBJECT() to decompose a bound triple term in a FILTER, and isTRIPLE() to test whether a value is a triple term before further processing, as shown in the read-only SPARQL Workbench queries on this page.