DELETE/INSERT

The DELETE/INSERT operation can be used to remove or add triples from/to the Graph Store based on bindings for a query pattern specified in a WHERE clause:

( **WITH** *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )?
( ( *[DeleteClause](../../../../sparql11-query/grammar/#rDeleteData) [InsertClause](../../../../sparql11-query/grammar/#rInsertData)*? ) | *[InsertClause](../../../../sparql11-query/grammar/#rInsertData)* )
( **USING ( NAMED )?** *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )*
**WHERE** *[GroupGraphPattern](../../../../sparql11-query/grammar/#rGroupGraphPattern)*

The DeleteClause and InsertClause forms can be broken down as follows:

*DeleteClause* ::= **DELETE ** QuadPattern 
*InsertClause* ::= **INSERT ** QuadPattern 

This operation identifies data with the WHERE clause, which will be used to compute solution sequences of bindings for a set of variables. The bindings for each solution are then substituted into the DELETE template to remove triples, and then in the INSERT template to create new triples. If any solution produces a triple containing an unbound variable or an illegal RDF construct, such as a literal in a subject or predicate position, then that triple is not included when processing the operation: INSERT will not instantiate new data in the output graph, and DELETE will not remove anything. The graphs used for computing a solution sequence may be different to the graphs modified with the DELETE and INSERT templates.

The WITH clause defines the graph that will be modified or matched against for any of the subsequent elements (in DELETE, INSERT, or WHERE clauses) if they do not specify a graph explicitly. If not provided, then the default graph of the Graph Store (or an explicitly declared dataset in the WHERE clause) will be assumed. That is, a WITH clause may be viewed as syntactic sugar for wrapping both the QuadPatterns in subsequent DELETE and INSERT clauses, and likewise the GroupGraphPattern in the subsequent WHERE clause into GRAPH patterns. This can be used to avoid refering to the same graph multiple times in a single operation.

Following the optional WITH clause are the INSERT and/or DELETE clauses. The deletion of the triples happens before the insertion. The pattern in the WHERE clause is evaluated only once, before the delete part of the operation is performed. The overall processing model is that the pattern is executed, the results used to instantiate the DELETE template, the deletes performed, the results used again to instantiate the INSERT template, and the inserts performed.

If the DELETE clause is omitted, then the operation only inserts data (see INSERT). If the INSERT clause is omitted, then the operation only removes data (see DELETE). The grammar does not permit both DELETE and INSERT to be omitted in the same operation.

The USING and USING NAMED clauses affect the RDF Dataset used while evaluating the WHERE clause. This describes a dataset in the same way as FROM and FROM NAMED clauses describe RDF Datasets in the SPARQL 1.1 Query Language. The keyword USING instead of FROM in update requests is to avoid possible ambiguities which could arise from writing "DELETE FROM". That is, the GroupGraphPattern in the WHERE clause will be matched against the dataset described by explicit USING or USING NAMED clauses, if specified, and against the Graph Store otherwise.

The WITH clause provides a convenience for when an operation primarily refers to a single graph. If a graph name is specified in a WITH clause, then - for the purposes of evaluating the WHERE clause - this will define an RDF Dataset containing a default graph with the specified name, but only in the absence of USING or USING NAMED clauses. In the presence of one or more graphs referred to in USING clauses and/or USING NAMED clauses, the WITH clause will be ignored while evaluating the WHERE clause.

The GroupGraphPattern in the WHERE clause is evaluated as in a SPARQL query "SELECT * WHERE GroupGraphPattern" and all the solution bindings are applied to the preceding DELETE and INSERT templates for defining the triples to be deleted from or inserted into the Graph Store.

Again, QuadPatterns are formed by TriplesTemplates, i.e., sets of triple patterns, optionally wrapped into a GRAPH block, where the GRAPH clause indicates the named graph in the Graph Store to be updated; on any TripleTemplates without a GRAPH clause, the INSERT or DELETE clauses applies to the graph specified by the WITH clause, or the default graph of the Graph Store if no WITH clause is present.

To illustrate the use of the WITH clause, an operation of the general form:

WITH <g1> DELETE { a b c } INSERT { x y z } WHERE { ... }

is considered equivalent to:

DELETE { GRAPH <g1> { a b c } } INSERT { GRAPH <g1> { x y z } } USING <g1> WHERE { ... }

Note that explicit GRAPH clauses override a WITH clause. WITH provides a fallback to specify a graph (different from the default graph) to use when one is not explicitly stipulated via GRAPH.

Deleting triples that are not present, or from a graph that is not present will have no effect and will result in success. Blank nodes are prohibited in a DELETE template, since using a new blank node in a DELETE template would lead to nothing being deleted, as a new blank node cannot match anything in the Graph Store. It should be noted that this restriction is not in the EBNF for the DeleteClause itself, but made explicit in Note 9 to the grammar.

If an operation tries to insert into a graph that does not exist, then that graph SHOULD be created; again, there may be implementations providing an update service over a fixed set of graphs which in such case MUST return with failure for update requests that would create an unallowed graph. If no data is to be inserted, then no graph will be created. Particularly, note that

INSERT ... { GRAPH <g> {} } ...

does not create <g>. If a user intends to create a graph regardless of the data to be inserted, then the graph management operations (CREATE/LOAD) may be used prior to any insertion operations.

Blank nodes that appear in an INSERT clause operate similarly to blank nodes in the template of a CONSTRUCT query, i.e., they are re-instantiated for any solution of the WHERE clause; refer to Templates with Blank Nodes in SPARQL Query 1.1 and to the formal semantics of DELETE/INSERT below for details. Blank nodes in the WHERE clause match data in the same way as for any SPARQL Query.

Example 5:

An example to update the graph http://example/addresses to rename all people with the given name "Bill" to "William".

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

WITH <http://example/addresses>
DELETE { ?person foaf:givenName 'Bill' }
INSERT { ?person foaf:givenName 'William' }
WHERE
  { ?person foaf:givenName 'Bill'
  } 

Data before:

**# Graph: http://example/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/president25> foaf:givenName "Bill" .
<http://example/president25> foaf:familyName "McKinley" .
<http://example/president27> foaf:givenName "Bill" .
<http://example/president27> foaf:familyName "Taft" .
<http://example/president42> foaf:givenName "Bill" .
<http://example/president42> foaf:familyName "Clinton" .

Data after:

**# Graph: http://example/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/president25> foaf:givenName "William" .
<http://example/president25> foaf:familyName "McKinley" .
<http://example/president27> foaf:givenName "William" .
<http://example/president27> foaf:familyName "Taft" .
<http://example/president42> foaf:givenName "William" .
<http://example/president42> foaf:familyName "Clinton" .
DELETE (Informative)
( **WITH**  *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )?
**DELETE ** QuadPattern 
( **USING ( NAMED )?** *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )*
**WHERE** *[GroupGraphPattern](../../../../sparql11-query/grammar/#rGroupGraphPattern)*

The DELETE operation is a form of the DELETE/INSERT operation having no INSERT section. A compliant implementation of DELETE/INSERT will already implement this operation correctly. The DELETE operation is described here separately for clarity. Analogous to DELETE/INSERT, deleting triples that are not present, or from a graph that is not present will have no effect and will result in success.

If any DELETE template specifies a GRAPH then this will be the graph affected. Otherwise, the operation will be applied to the graph specified in the WITH clause, if one was specified, or the default graph otherwise.

The WHERE clause identifies data in existing graphs, and creates bindings to be used by the template. The graphs to apply the GroupGraphPattern follow the same rules as for DELETE/INSERT.

Example 6:

This example request deletes all records of old books (with date before year 1970) from the store's default graph:

PREFIX dc:  <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

DELETE
 { ?book ?p ?v }
WHERE
 { ?book dc:date ?date .
   FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
   ?book ?p ?v
 }

The pattern in WHERE is matched against the Graph Store. The resulting sequence of solutions to the WHERE clause is used to instantiate the triple patterns in the DELETE template similar to CONSTRUCT in SPARQL 1.1 Query. The resulting triples are then removed from the Graph Store.

Data before:

**# Default graph**
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example/book1> dc:title "Principles of Compiler Design" .
<http://example/book1> dc:date "1977-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book2> ns:price 42 .
<http://example/book2> dc:title "David Copperfield" .
<http://example/book2> dc:creator "Edmund Wells" .
<http://example/book2> dc:date "1948-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .

Data after:

**# Default graph**
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example/book2> ns:price 42 .
<http://example/book2> dc:title "David Copperfield" .
<http://example/book2> dc:creator "Edmund Wells" .
<http://example/book2> dc:date "1948-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .

Example 7:

This example request removes all statements about anything with a given name of "Fred" from the graph http://example/addresses. A WITH clause is present, meaning that graph http://example/addresses is both the one from which triples are being removed and the one which the WHERE clause is matched against.

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

WITH <http://example/addresses>
DELETE { ?person ?property ?value } 
WHERE { ?person ?property ?value ; foaf:givenName 'Fred' } 

Data before:

**# Graph: http://example/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .
<http://example/william> foaf:mbox <mailto:bill@example> .

<http://example/fred> a foaf:Person .
<http://example/fred> foaf:givenName "Fred" .
<http://example/fred> foaf:mbox  <mailto:fred@example> .

Data after:

**# Graph: http://example/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .
<http://example/william> foaf:mbox  <mailto:bill@example> .

Another example of DELETE is provided in the final example in the following section which demonstrates multiple operations combining an INSERT with a DELETE.

INSERT (Informative)
( **WITH**  *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )?
**INSERT ** QuadPattern 
( **USING ( NAMED )?**  *[IRIref](../../../../sparql11-query/grammar/#rIRIREF)* )*
**WHERE** *[GroupGraphPattern](../../../../sparql11-query/grammar/#rGroupGraphPattern)*

The INSERT operation is a form of the DELETE/INSERT operation having no DELETE section. A compliant implementation of DELETE/INSERT will already implement this operation correctly. The INSERT operation is described here separately for clarity.

If the INSERT template specifies GRAPH blocks then these will be the graphs affected. Otherwise, the operation will be applied to the default graph, or, respectively, to the graph specified in the WITH clause, if one was specified. If no USING (NAMED) clause is present, then the pattern in the WHERE clause will be matched against the Graph Store, otherwise against the dataset specified by the USING (NAMED) clauses. The matches against the WHERE clause create bindings to be applied to the template for determining triples to be inserted (following the same rules as for DELETE/INSERT).

If any instantiation arising from the solution sequence produces a triple containing an unbound variable or an illegal RDF construct, such as a literal in subject or predicate position, then that triple is not inserted. The template can contain triples with no variables (known as ground or explicit triples), and these will also be inserted, provided that the solution sequence is not empty.

Example 8:

This example copies triples from one named graph to another named graph based on a pattern:

PREFIX dc:  <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT 
  { GRAPH <http://example/bookStore2> { ?book ?p ?v } }
WHERE
  { GRAPH  <http://example/bookStore>
       { ?book dc:date ?date .
         FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
         ?book ?p ?v
  } }   

Data before:

**# Graph: http://example/bookStore**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://example/book1> dc:title "Fundamentals of Compiler Design" .
<http://example/book1> dc:date "1977-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book2> ns:price 42 .
<http://example/book2> dc:title "David Copperfield" .
<http://example/book2> dc:creator "Edmund Wells" .
<http://example/book2> dc:date "1948-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .
**# Graph: http://example/bookStore2**
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example/book4> dc:title "SPARQL 1.0 Tutorial" .

Data after:

**# Graph: http://example/bookStore**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://example/book1> dc:title "Fundamentals of Compiler Design" .
<http://example/book1> dc:date "1977-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book2> ns:price 42 .
<http://example/book2> dc:title "David Copperfield" .
<http://example/book2> dc:creator "Edmund Wells" .
<http://example/book2> dc:date "1948-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .
**# Graph: http://example/bookStore2**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<http://example/book1> dc:title "Fundamentals of Compiler Design" .
<http://example/book1> dc:date "1977-01-01T00:00:00-02:00"^^xsd:dateTime .

<http://example/book4> dc:title "SPARQL 1.0 Tutorial" .

Example 9:

This example copies triples of name and email from one named graph to another. Some individuals may not have an address, but the name is copied regardless:

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

INSERT 
  { GRAPH <http://example/addresses>
    {
      ?person  foaf:name  ?name .
      ?person  foaf:mbox  ?email
    } }
WHERE
  { GRAPH  <http://example/people>
    {
      ?person  foaf:name  ?name .
      OPTIONAL { ?person  foaf:mbox  ?email }
    } }

Data before:

**# Graph: http://example/people**
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdf:  >http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

_:a  rdf:type        foaf:Person .
_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@example.com> .

_:b  rdf:type        foaf:Person .
_:b  foaf:name       "Bob" .
**# Graph: http://example/addresses**
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

Data after:

**# Graph: http://example/people**
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rdf:  >http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

_:a  rdf:type        foaf:Person .
_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@example.com> .

_:b  rdf:type        foaf:Person .
_:b  foaf:name       "Bob" .
**# Graph: http://example/addresses**
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@example.com> .

_:b  foaf:name       "Bob" .

Example 10:

This example request first copies triples from one named graph to another named graph based on a pattern; triples about all the copied objects that are classified as Physical Objects are then deleted. This demonstrates two operations in a single request, both of which share common PREFIX definitions.

PREFIX dc:  <http://purl.org/dc/elements/1.1/>
PREFIX dcmitype: <http://purl.org/dc/dcmitype/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

INSERT
  { GRAPH <http://example/bookStore2> { ?book ?p ?v } }
WHERE
  { GRAPH  <http://example/bookStore>
     { ?book dc:date ?date . 
       FILTER ( ?date < "2000-01-01T00:00:00-02:00"^^xsd:dateTime )
       ?book ?p ?v
     }
  } ;

WITH <http://example/bookStore>
DELETE
 { ?book ?p ?v }
WHERE
 { ?book dc:date ?date ;
         dc:type dcmitype:PhysicalObject .
   FILTER ( ?date < "2000-01-01T00:00:00-02:00"^^xsd:dateTime ) 
   ?book ?p ?v
 } 

Data before:

**# Graph: http://example/bookStore**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcmitype: <http://purl.org/dc/dcmitype/> .

<http://example/book1> dc:title "Fundamentals of Compiler Design" .
<http://example/book1> dc:date "1996-01-01T00:00:00-02:00"^^xsd:dateTime .
<http://example/book1> a dcmitype:PhysicalObject .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .
**# Graph: http://example/bookStore2**
@prefix dc: <http://purl.org/dc/elements/1.1/> .

<http://example/book4> dc:title "SPARQL 1.0 Tutorial" .

Data after:

**# Graph: http://example/bookStore**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcmitype: <http://purl.org/dc/dcmitype/> .

<http://example/book3> dc:title "SPARQL 1.1 Tutorial" .
**# Graph: http://example/bookStore2**
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcmitype: <http://purl.org/dc/dcmitype/> .

<http://example/book1> dc:title "Fundamentals of Compiler Design" .
<http://example/book1> dc:date "1996-01-01T00:00:00-02:00"^^xsd:dateTime .
<http://example/book1> a dcmitype:PhysicalObject .

<http://example/book4> dc:title "SPARQL 1.0 Tutorial" .
DELETE WHERE
**DELETE WHERE ** QuadPattern 

The DELETE WHERE operation is a shortcut form for the DELETE/INSERT operation where bindings matched by the WHERE clause are used to define the triples in a graph that will be deleted. Analogous to DELETE/INSERT, deleting triples that are not present, or from a graph that is not present will have no effect and will result in success.

The QuadPattern is used both as a pattern for matching against triples and graphs, and as the template for deletion. If any TripleTemplates within the QuadPattern appear in the scope of a GRAPH clause then this will determine the graph that that template is matched on, and also the graph from which any matching triples will be removed. Any TripleTemplates not in the scope of a GRAPH clause will be matched against/removed from the default graph.

Example 11:

This example request removes all statements about anything with a given name of "Fred" from the default graph:

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

DELETE WHERE { ?person foaf:givenName 'Fred';
                       ?property      ?value }

Data before:

**# Default graph**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .
<http://example/william> foaf:mbox  <mailto:bill@example> .

<http://example/fred> a foaf:Person .
<http://example/fred> foaf:givenName "Fred" .
<http://example/fred> foaf:mbox  <mailto:fred@example> .

Data after:

**# Default graph**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .
<http://example/william> foaf:mbox  <mailto:bill@example> .

Example 12:

This example request removes both statements naming some resource "Fred" in the graph http://example.com/names, and also statements about that resource from the graph http://example/addresses (assuming that some of the resources in the graph http://example.com/names have corresponding triples in the graph http://example/addresses).

PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

DELETE WHERE {
  GRAPH <http://example.com/names> {
    ?person foaf:givenName 'Fred' ;
            ?property1 ?value1
  }
  GRAPH <http://example.com/addresses> {
    ?person ?property2 ?value2
  }
}
**# Graph: http://example.com/names**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .

<http://example/fred> a foaf:Person .
<http://example/fred> foaf:givenName "Fred" .
**# Graph: http://example.com/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> foaf:mbox  <mailto:bill@example> .

<http://example/fred> foaf:mbox  <mailto:fred@example> .

Data after:

**# Graph: http://example.com/names**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> a foaf:Person .
<http://example/william> foaf:givenName "William" .
**# Graph: http://example.com/addresses**
@prefix foaf:  <http://xmlns.com/foaf/0.1/> .

<http://example/william> foaf:mbox  <mailto:bill@example> .