1

problem with insert query, can't pars simple statements

Example: query:

PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA 
{
    <http://example/book1> dc:title "A new book";
                           dc:creator "A.N.Other" .
}

result:

PREFIX dc: <http://purl.org/dc/elements/1.1/> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX sesame: <http://www.openrdf.org/schema/sesame#> 
PREFIX owl: <http://www.w3.org/2002/07/owl#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX fn: <http://www.w3.org/2005/xpath-functions#> 
 <http://example/book1> dc:title "A new book" ; dc:creator "A.N.Other" .

But if I pars something more difficult all is well.

query:

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
  } }

result:

StatementPattern FROM NAMED CONTEXT
   Var (name=book)
   Var (name=p)
   Var (name=v)
   Var (name=_const_f1165b11_uri, value=http://example/bookStore2, anonymous)

Modify
   StatementPattern FROM NAMED CONTEXT
      Var (name=book)
      Var (name=p)
      Var (name=v)
      Var (name=_const_f1165b11_uri, value=http://example/bookStore2, anonymous)
   Filter
      Compare (>)
         Var (name=date)
         ValueConstant (value="1970-01-01T00:00:00-02:00"^^<http://www.w3.org/2001/XMLSchema#dateTime>)
      Join
         StatementPattern FROM NAMED CONTEXT
            Var (name=book)
            Var (name=_const_9b277d39_uri, value=http://purl.org/dc/elements/1.1/date, anonymous)
            Var (name=date)
            Var (name=_const_39534d41_uri, value=http://example/bookStore, anonymous)
         StatementPattern FROM NAMED CONTEXT
            Var (name=book)
            Var (name=p)
            Var (name=v)
            Var (name=_const_39534d41_uri, value=http://example/bookStore, anonymous)

I need to get something like that the first case. What am I doing wrong?

Java code for executing these queries:

String query = ...
SPARQLParser parser = new SPARQLParser();
ParsedUpdate q2 = parser.parseUpdate(query, null);
Iterator var2 = q2.getUpdateExprs().iterator();
UpdateExpr updateExpr = (UpdateExpr)var2.next();
System.out.println(updateExpr);
  • I don't get it. What doesn't work with the second query? For the first query you've shown the RDF result but for the second query you've shown the query execution plan. Are you running both queries in the same way? I guess not – UninformedUser Mar 12 '19 at 10:13
  • @AKSW I need to get the execution plan for the first query. The second query result is ok. – Gevorg Arutiunian Mar 12 '19 at 10:17
  • @AKSW "Are you running both queries in the same way? " of course. – Gevorg Arutiunian Mar 12 '19 at 13:58
  • I can't reproduce what you're saying. I tried with version 2.5.0 and the output is `InsertData` for your first query. And this is correct, it is the root node of the parse tree and your code does nothing more than printing the root node. What i'm saying hereby: you're not traversing the parse tree in your code. – UninformedUser Mar 12 '19 at 14:09
  • @AKSW Let me reword the question. The problem is that `InsertData` doesn't provide simple statements, it's just text. Is there the way to extract simple statements? (I agree, question is not really clear; problem is not about `println` output, it's about further traversing; Геворг says that in the first example he needs the same structure (`StatementPattern`s) that in the second) – Andrey Rechitsky Mar 12 '19 at 15:03
  • 1
    I see. The main difference is: the first query will be parsed into an object of type [`org.eclipse.rdf4j.query.algebra.InsertData`](http://docs.rdf4j.org/javadoc/2.4/org/eclipse/rdf4j/query/algebra/InsertData.html) - it is static data, thus, you won't see statements here.The second query on the other hand is parsed into an [`org.eclipse.rdf4j.query.algebra.Modify`](http://docs.rdf4j.org/javadoc/2.4/org/eclipse/rdf4j/query/algebra/Modify.html) object which in fact has those `TupleExp` objects that you see rendered as tree like those `StatementPattern` object. – UninformedUser Mar 12 '19 at 15:22
  • Use a debugger and you'll it at runtime. For the `InsertData` there is no `TuplExp` it's just the data block stored as plain string. – UninformedUser Mar 12 '19 at 15:24
  • 1
    @ГеворгАрутюнян why exactly do you need this at all - I mean what do you plan to do with these "simple statements"? Reason I ask is that if we understand what you're trying to do, we may be able to recommend other/better ways of achieving it. – Jeen Broekstra Mar 12 '19 at 15:31

1 Answers1

3

As indicated in the comments, the data block for an INSERT DATA SPARQL update is internally stored as an (unparsed) string. If you wish to process it further, you have a couple of options.

One option is to actually just execute the update, for example against a temporary/empty in-memory store, and then just retrieve the statements from that store:

 String update = "INSERT DATA { .... }";
 Repository tempRep = new SailRepository(new MemoryStore());
 tempRep.init();
 try(RepositoryConnection conn = tempRep.getConnection()) {
     conn.prepareUpdate(update).execute());
     Model statements = QueryResults.asModel(conn.getStatements(null, null, null));
 }

Another option, which is perhaps more scalable, is to just extract the data block as a string and pass it through a parser. The SPARQLUpdateDataBlockParser specifically exists for this purpose:

InsertData insertDataExpr = (InsertData)updateExpr;

RDFParser parser = new SPARQLUpdateDataBlockParser();
StatementCollector handler = new StatementCollector();
parser.setRDFHandler(handler);

parser.parse(new StringReader(insertDataExpr.getDataBlock()), "");

Collection<Statement> stmts = handler.getStatements();
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73