This was generated by AI during triage.
What to build
triples_update builds two separate blank-node → variable maps, one for the DELETE patterns
(oldbn) and one for the INSERT patterns (newbn), and then binds every new-side variable with
BIND(BNODE() AS ?newbnN).
The consequence: a blank node that appears on both sides of an update — that is, the same node,
retained while one of its properties changes — is rendered as two different variables, and the INSERT
side always mints a brand-new store node. It is therefore impossible for any caller to update a
property of an existing blank node while keeping the node; the old one is unlinked and a fresh one
takes its place, orphaning any triple the caller did not include in old_triples.
A BNode present in both old_triples and new_triples is the same node and must render as the
same variable.
Direction. One shared map across both pattern sets. Emit BIND(BNODE() AS ?v) only for blank
nodes that occur exclusively in new_triples; a blank node also present in old_triples is
already bound by the WHERE clause and must reuse that binding.
Illustration. Given _:b on both sides with only its value changing, today's query is
DELETE { ?oldbn1 :hasValue 12.1 }
INSERT { ?newbn1 :hasValue 1.4 }
WHERE { ?oldbn1 :hasValue 12.1 . BIND(BNODE() AS ?newbn1) }
which deletes the property from the existing node and creates a different node carrying the new
value. It should be
DELETE { ?bn1 :hasValue 12.1 }
INSERT { ?bn1 :hasValue 1.4 }
WHERE { ?bn1 :hasValue 12.1 }
Acceptance criteria
Context
Found while designing anonymous-node identity in SAWeindel/kapps_ogm — see
docs/prd/kapps-ogm-anonymous-node-identity.md (requirement R11) in
EHoffm/kapps_semantic_middleware. The fix is needed there whenever a blank node must survive an
update; it is a correctness fix for this library independent of that work.
I have a branch with the change and a query-construction test but only read access to this repository,
so I cannot push it — happy to hand it over or open a PR from a fork if that is easier.
Blocked by
None — can start immediately.
What to build
triples_updatebuilds two separate blank-node → variable maps, one for the DELETE patterns(
oldbn) and one for the INSERT patterns (newbn), and then binds every new-side variable withBIND(BNODE() AS ?newbnN).The consequence: a blank node that appears on both sides of an update — that is, the same node,
retained while one of its properties changes — is rendered as two different variables, and the INSERT
side always mints a brand-new store node. It is therefore impossible for any caller to update a
property of an existing blank node while keeping the node; the old one is unlinked and a fresh one
takes its place, orphaning any triple the caller did not include in
old_triples.A
BNodepresent in bothold_triplesandnew_triplesis the same node and must render as thesame variable.
Direction. One shared map across both pattern sets. Emit
BIND(BNODE() AS ?v)only for blanknodes that occur exclusively in
new_triples; a blank node also present inold_triplesisalready bound by the WHERE clause and must reuse that binding.
Illustration. Given
_:bon both sides with only its value changing, today's query iswhich deletes the property from the existing node and creates a different node carrying the new
value. It should be
Acceptance criteria
BNodeoccurring in bothold_triplesandnew_triplesrenders as one variable in thegenerated query, used in both the DELETE and the INSERT block.
BIND(BNODE() AS ?v)is emitted only for blank nodes exclusive tonew_triples.DELETE ... INSERT ... WHEREtransaction — the intermediatestate must never be observable, which is what the existing SHACL-correctness comment relies on.
regress. (The existing update tests require a live GraphDB; a query-construction test does not
and is the cheaper guard.)
Context
Found while designing anonymous-node identity in
SAWeindel/kapps_ogm— seedocs/prd/kapps-ogm-anonymous-node-identity.md(requirement R11) inEHoffm/kapps_semantic_middleware. The fix is needed there whenever a blank node must survive anupdate; it is a correctness fix for this library independent of that work.
I have a branch with the change and a query-construction test but only read access to this repository,
so I cannot push it — happy to hand it over or open a PR from a fork if that is easier.
Blocked by
None — can start immediately.