SPARQL Update

pg_ripple supports the full SPARQL 1.1 Update specification via the sparql_update() function. All update operations — INSERT DATA, DELETE DATA, DELETE/INSERT WHERE, LOAD, CLEAR, DROP, and CREATE — are available as of v0.12.0.

sparql_update

pg_ripple.sparql_update(query TEXT) RETURNS BIGINT

Executes a SPARQL Update statement and returns the number of triples affected (inserted + deleted).

INSERT DATA

Adds one or more ground triples (no variables) to the store:

-- Insert a single triple
SELECT pg_ripple.sparql_update(
    'INSERT DATA { <https://example.org/alice> <https://example.org/age> "30"^^<http://www.w3.org/2001/XMLSchema#integer> }'
);

-- Insert multiple triples in one statement
SELECT pg_ripple.sparql_update('
    INSERT DATA {
        <https://example.org/alice> <https://example.org/knows> <https://example.org/bob> .
        <https://example.org/bob>   <https://example.org/name>  "Bob"
    }
');

All subjects, predicates, and objects are dictionary-encoded before insertion. Typed literals that qualify for inline encoding (xsd:integer, xsd:boolean, xsd:date, xsd:dateTime) are stored as bit-packed IDs rather than dictionary rows.

DELETE DATA

Removes exact-match triples from the store:

SELECT pg_ripple.sparql_update(
    'DELETE DATA { <https://example.org/alice> <https://example.org/knows> <https://example.org/bob> }'
);

Returns 0 if the triple does not exist (no error).

DELETE/INSERT WHERE

Pattern-based updates find matching triples via a WHERE clause and delete and/or insert triples for each match. This is the SPARQL equivalent of SQL UPDATE.

-- Replace all "draft" status values with "published":
SELECT pg_ripple.sparql_update('
    DELETE { ?s <https://example.org/status> <https://example.org/draft> }
    INSERT { ?s <https://example.org/status> <https://example.org/published> }
    WHERE  { ?s <https://example.org/status> <https://example.org/draft> }
');

-- Add an email placeholder for every person who lacks one:
SELECT pg_ripple.sparql_update('
    INSERT { ?person <https://schema.org/email> "no-reply@example.org" }
    WHERE  {
        ?person a <https://schema.org/Person> .
        FILTER NOT EXISTS { ?person <https://schema.org/email> ?e }
    }
');

The WHERE clause is compiled through the existing SPARQL→SQL engine. All bound variables in the WHERE clause are available in the DELETE and INSERT templates. The DELETE phase runs before the INSERT phase for each bound row. The entire operation is transactional.

Return value: (number of triples deleted) + (number of triples inserted).

Named graphs

All forms support named graphs:

SELECT pg_ripple.sparql_update('
    INSERT DATA {
        GRAPH <https://example.org/graph1> {
            <https://example.org/alice> <https://example.org/memberOf> <https://example.org/org1>
        }
    }
');

-- Pattern-based update in a named graph:
SELECT pg_ripple.sparql_update('
    DELETE { GRAPH <https://example.org/graph1> { ?s ?p ?o } }
    WHERE  { GRAPH <https://example.org/graph1> { ?s ?p ?o } }
');

The default graph has ID 0. Named graphs are created implicitly when the first triple is inserted.

Graph management

LOAD

Fetches an RDF document from a URL via HTTP(S) and inserts all triples into the store.

-- Load into the default graph:
SELECT pg_ripple.sparql_update(
    'LOAD <https://www.w3.org/People/Berners-Lee/card.rdf>'
);

-- Load into a named graph:
SELECT pg_ripple.sparql_update(
    'LOAD <https://example.org/data.ttl> INTO GRAPH <https://example.org/mygraph>'
);

-- Ignore errors (e.g. network failures):
SELECT pg_ripple.sparql_update(
    'LOAD SILENT <https://example.org/data.nt>'
);

Format detection: Turtle if the Content-Type contains turtle or the URL ends in .ttl; RDF/XML if rdf+xml or .rdf/.owl; otherwise N-Triples. Named graphs inside TriG are not split out — the destination graph overrides.

CLEAR

Deletes all triples from the target graph(s) without removing the graph name from the dictionary.

-- Clear a specific named graph:
SELECT pg_ripple.sparql_update(
    'CLEAR GRAPH <https://example.org/mygraph>'
);

-- Clear the default graph:
SELECT pg_ripple.sparql_update('CLEAR DEFAULT');

-- Clear all named graphs (default graph untouched):
SELECT pg_ripple.sparql_update('CLEAR NAMED');

-- Clear everything:
SELECT pg_ripple.sparql_update('CLEAR ALL');

-- Ignore if the graph does not exist:
SELECT pg_ripple.sparql_update(
    'CLEAR SILENT GRAPH <https://example.org/nonexistent>'
);

DROP

Like CLEAR, but also deregisters the graph. In pg_ripple, the graph IRI remains in the dictionary (deregistering is a no-op beyond clearing triples), so DROP and CLEAR are functionally equivalent.

SELECT pg_ripple.sparql_update(
    'DROP GRAPH <https://example.org/mygraph>'
);
SELECT pg_ripple.sparql_update('DROP ALL');
SELECT pg_ripple.sparql_update(
    'DROP SILENT GRAPH <https://example.org/nonexistent>'
);

CREATE

Registers a named graph in the dictionary. Since pg_ripple creates graphs implicitly on first insert, CREATE GRAPH is rarely needed but is supported for SPARQL compliance.

SELECT pg_ripple.sparql_update(
    'CREATE GRAPH <https://example.org/newgraph>'
);
-- No-op if the graph already exists:
SELECT pg_ripple.sparql_update(
    'CREATE SILENT GRAPH <https://example.org/newgraph>'
);

Return value

sparql_update() returns the total count of triples affected:

StatementReturn value
INSERT DATA { t1 . t2 . t3 }3 if all were new
DELETE DATA { t1 }1 if found, 0 if not found
DELETE { … } INSERT { … } WHERE { … }deletes + inserts
CLEAR GRAPH <g>triples removed
DROP GRAPH <g>triples removed
CREATE GRAPH <g>0 (no triples touched)
LOAD <url>triples inserted

Compared to insert_triple / delete_triple

insert_triplesparql_update
Input formatN-Triples strings (subject, predicate, object)SPARQL text
Multiple triplesOne call per tripleMultiple triples per statement
Pattern-basedNoYes (DELETE/INSERT WHERE)
Graph managementNoYes (CLEAR/DROP/CREATE/LOAD)
Use caseProgrammatic insertion from SQLSPARQL-based tools and standards-compliant clients

sparql_update

pg_ripple.sparql_update(query TEXT) RETURNS BIGINT

Executes a SPARQL Update statement and returns the number of triples affected.

INSERT DATA

Adds one or more ground triples (no variables) to the store:

-- Insert a single triple
SELECT pg_ripple.sparql_update(
    'INSERT DATA { <https://example.org/alice> <https://example.org/age> "30"^^<http://www.w3.org/2001/XMLSchema#integer> }'
);

-- Insert multiple triples in one statement
SELECT pg_ripple.sparql_update('
    INSERT DATA {
        <https://example.org/alice> <https://example.org/knows> <https://example.org/bob> .
        <https://example.org/bob>   <https://example.org/name>  "Bob"
    }
');

All subjects, predicates, and objects are dictionary-encoded before insertion. Typed literals that qualify for inline encoding (xsd:integer, xsd:boolean, xsd:date, xsd:dateTime) are stored as bit-packed IDs rather than dictionary rows.

DELETE DATA

Removes exact-match triples from the store:

SELECT pg_ripple.sparql_update(
    'DELETE DATA { <https://example.org/alice> <https://example.org/knows> <https://example.org/bob> }'
);

Returns 0 if the triple does not exist (no error). DELETE DATA is an atomic set operation — all triples in the statement are deleted or none are (if any are missing, the count reflects only the triples actually removed).

Named graphs

Both forms support named graphs:

SELECT pg_ripple.sparql_update('
    INSERT DATA {
        GRAPH <https://example.org/graph1> {
            <https://example.org/alice> <https://example.org/memberOf> <https://example.org/org1>
        }
    }
');

The default graph has ID 0. Named graphs are created implicitly when the first triple is inserted.

Return value

sparql_update() returns the count of triples inserted or deleted:

StatementReturn value
INSERT DATA { t1 . t2 . t3 }3 if all were new; fewer if some already existed
DELETE DATA { t1 }1 if found, 0 if not found

Compared to insert_triple / delete_triple

insert_triplesparql_update
Input formatN-Triples strings (subject, predicate, object)SPARQL text
Missing argumentsNULL used for absent componentsNot applicable — all parts required for INSERT/DELETE DATA
Multiple triplesOne call per tripleMultiple triples per statement
Use caseProgrammatic insertion from SQL or application codeSPARQL-based tools and standards-compliant clients

Unsupported forms (planned for later releases)

The following SPARQL Update forms are not yet supported in v0.5.1:

  • DELETE/INSERT WHERE { … } — pattern-based updates (v0.12.0)
  • LOAD <url> (v0.12.0)
  • CLEAR GRAPH <g> (v0.12.0)
  • DROP GRAPH <g> (v0.12.0)
  • CREATE GRAPH <g> (v0.12.0)
  • Update sequences (; UPDATE1 ; UPDATE2) (v0.12.0)

Graph management operations (v0.38.0)

ADD, COPY, and MOVE are supported from v0.38.0. These operations are desugared by the spargebra parser into equivalent INSERT DATA / DELETE DATA sequences before execution.

-- ADD: copy all triples from SOURCE into DEST (SOURCE is preserved)
SELECT sparql_update('ADD GRAPH <http://example.org/source> TO GRAPH <http://example.org/dest>');

-- COPY: replace DEST with the contents of SOURCE (SOURCE is preserved)
SELECT sparql_update('COPY GRAPH <http://example.org/source> TO GRAPH <http://example.org/dest>');

-- MOVE: rename SOURCE to DEST (SOURCE is emptied)
SELECT sparql_update('MOVE GRAPH <http://example.org/source> TO GRAPH <http://example.org/dest>');

All three operations use DEFAULT in place of a named graph IRI to refer to the default graph.