Build the DELETE template (construct) and matching WHERE patterns for the
Concise Bounded Description (CBD) of subjectURI as described by rootSchema.
Used exclusively by the write path (save → DELETE/INSERT, remove → DELETE).
Reads use traversalSchema2construct.
Boundary semantics — two independent guards decide how far the template
expands into nested objects:
Schema (TBox) guard: recursion stops at sub-schemas whose properties
contain one of stopSymbols (callers pass ["@id"], i.e. named-entity
definitions). This is the declared boundary.
Data (ABox) guard: every nested expansion is anchored in its own
OPTIONAL { <link> FILTER(isBlank(?o)) … } group. Only anonymous
(blank-node) objects owned by the subject are ever expanded; IRIs are
never followed, regardless of what the schema declares. This is the CBD
definition proper and protects linked named entities (e.g. a
Location.parent pointing at another Location) from being wiped when
the schema artifact omits @id on referenced definitions.
The link triple itself (<s> :p ?o) is always matched in a branch of its
own, so stale references are removed even when the target is an IRI.
Shape of the WHERE patterns — a UNION, not a chain of OPTIONALs:
{ a ?__type_0 . }
UNION { :title ?title_1 . }
UNION { :parent ?parent_2 . }
UNION { :parent ?parent_2 . FILTER(isBlank(?parent_2))
{ ?parent_2 a ?__type_3 . } UNION { ?parent_2 :title ?title_4 . } }
Every solution binds the variables of one branch, so the number of
solutions is the sum of the stored values. A chain of sibling OPTIONALs
yields their product: an entity with a few multi-valued properties made
every save and remove pay for thousands of solutions.
No pattern is required. A DELETE wants maximal matching: a stored entity
that lacks a property the schema calls required must still have its
other triples removed, otherwise a save leaves the old state in place and
adds the new one next to it.
A DELETE template skips triples with unbound variables, so each solution
removes exactly the triples of its branch.
Build the DELETE template (
construct) and matching WHERE patterns for the Concise Bounded Description (CBD) ofsubjectURIas described byrootSchema.Used exclusively by the write path (
save→ DELETE/INSERT,remove→ DELETE). Reads usetraversalSchema2construct.Boundary semantics — two independent guards decide how far the template expands into nested objects:
Schema (TBox) guard: recursion stops at sub-schemas whose
propertiescontain one ofstopSymbols(callers pass["@id"], i.e. named-entity definitions). This is the declared boundary.Data (ABox) guard: every nested expansion is anchored in its own
OPTIONAL { <link> FILTER(isBlank(?o)) … }group. Only anonymous (blank-node) objects owned by the subject are ever expanded; IRIs are never followed, regardless of what the schema declares. This is the CBD definition proper and protects linked named entities (e.g. aLocation.parentpointing at anotherLocation) from being wiped when the schema artifact omits@idon referenced definitions.The link triple itself (
<s> :p ?o) is always matched in a branch of its own, so stale references are removed even when the target is an IRI.Shape of the WHERE patterns — a UNION, not a chain of OPTIONALs:
requiredmust still have its other triples removed, otherwise a save leaves the old state in place and adds the new one next to it.A DELETE template skips triples with unbound variables, so each solution removes exactly the triples of its branch.