/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Aug 20, 2011
*/
package com.bigdata.rdf.sail.sparql;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.algebra.StatementPattern.Scope;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.XSD;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.model.BigdataResource;
import com.bigdata.rdf.model.BigdataStatement;
import com.bigdata.rdf.model.BigdataURI;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.rdf.model.StatementEnum;
import com.bigdata.rdf.sail.sparql.ast.ParseException;
import com.bigdata.rdf.sail.sparql.ast.TokenMgrError;
import com.bigdata.rdf.sparql.AbstractBigdataExprBuilderTestCase;
import com.bigdata.rdf.sparql.ast.ClearGraph;
import com.bigdata.rdf.sparql.ast.ConstantNode;
import com.bigdata.rdf.sparql.ast.CreateGraph;
import com.bigdata.rdf.sparql.ast.DeleteInsertGraph;
import com.bigdata.rdf.sparql.ast.DropGraph;
import com.bigdata.rdf.sparql.ast.FilterNode;
import com.bigdata.rdf.sparql.ast.FunctionNode;
import com.bigdata.rdf.sparql.ast.JoinGroupNode;
import com.bigdata.rdf.sparql.ast.ProjectionNode;
import com.bigdata.rdf.sparql.ast.QuadsDataOrNamedSolutionSet;
import com.bigdata.rdf.sparql.ast.QueryHints;
import com.bigdata.rdf.sparql.ast.StatementPatternNode;
import com.bigdata.rdf.sparql.ast.UpdateRoot;
import com.bigdata.rdf.sparql.ast.VarNode;
import com.bigdata.rdf.sparql.ast.hints.QueryHintScope;
/**
* Test suite for bigdata specific extensions in {@link UpdateExprBuilder}.
*
* @see https://sourceforge.net/apps/mediawiki/bigdata/index.php?title=SPARQL_Update
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
*/
public class TestUpdateExprBuilder2 extends AbstractBigdataExprBuilderTestCase {
public TestUpdateExprBuilder2() {
}
public TestUpdateExprBuilder2(String name) {
super(name);
}
/*
* Bigdata specific extensions for named solution sets.
*/
/**
* INSERT INTO named solution set (bigdata extension).
*
* <pre>
* PREFIX dc: <http://purl.org/dc/elements/1.1/>
* PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
*
* INSERT INTO %cached_solution_set
* WHERE
* { GRAPH <http://example/bookStore>
* { ?book dc:date ?date .
* FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
* ?book ?p ?v
* } }
* </pre>
*
* @see https://sourceforge.net/apps/trac/bigdata/ticket/524 (SPARQL Cache)
*/
@SuppressWarnings("rawtypes")
public void test_delete_insert__insertInto_01() throws MalformedQueryException,
TokenMgrError, ParseException {
final String sparql = //
"PREFIX dc: <http://purl.org/dc/elements/1.1/>\n"//
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"//
+ "INSERT INTO %cached_solution_set\n"//
+ "SELECT ?book ?date\n"//
+ "WHERE\n"//
+ " { GRAPH <http://example/bookStore>\n"//
+ " { ?book dc:date ?date .\n"//
+ " FILTER ( ?date > \"1970-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"//
+ " ?book ?p ?v\n"//
+ "} }";
final IV dcDate = makeIV(valueFactory.createURI("http://purl.org/dc/elements/1.1/date"));
final IV dateTime = makeIV(valueFactory.createLiteral("1970-01-01T00:00:00-02:00",XSD.DATETIME));
final IV bookstore = makeIV(valueFactory.createURI("http://example/bookStore"));
final UpdateRoot expected = new UpdateRoot();
{
final DeleteInsertGraph op = new DeleteInsertGraph();
expected.addChild(op);
{
final QuadsDataOrNamedSolutionSet insertClause = new QuadsDataOrNamedSolutionSet(
"%cached_solution_set");
assertTrue(insertClause.isSolutions());
assertFalse(insertClause.isQuads());
final ProjectionNode projection = new ProjectionNode();
insertClause.setProjection(projection);
projection.addProjectionVar(new VarNode("book"));
projection.addProjectionVar(new VarNode("date"));
op.setInsertClause(insertClause);
}
{
final JoinGroupNode whereClause = new JoinGroupNode();
final JoinGroupNode graphGroup = new JoinGroupNode();
whereClause.addChild(graphGroup);
graphGroup.setContext(new ConstantNode(bookstore));
graphGroup.addChild(new StatementPatternNode(
new VarNode("book"), new ConstantNode(dcDate),
new VarNode("date"), new ConstantNode(bookstore),
Scope.NAMED_CONTEXTS));
graphGroup.addChild(new FilterNode(FunctionNode.GT(new VarNode(
"date"), new ConstantNode(dateTime))));
graphGroup.addChild(new StatementPatternNode(
new VarNode("book"), new VarNode("p"),
new VarNode("v"), new ConstantNode(bookstore),
Scope.NAMED_CONTEXTS));
op.setWhereClause(whereClause);
}
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* DELETE FROM named solution set (bigdata extension).
*
* <pre>
* PREFIX dc: <http://purl.org/dc/elements/1.1/>
* PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
*
* DELETE FROM %cached_solution_set
* WHERE
* { GRAPH <http://example/bookStore>
* { ?book dc:date ?date .
* FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
* ?book ?p ?v
* } }
* </pre>
*
* @see https://sourceforge.net/apps/trac/bigdata/ticket/524 (SPARQL Cache)
*/
@SuppressWarnings("rawtypes")
public void test_delete_insert__deleteFrom_01() throws MalformedQueryException,
TokenMgrError, ParseException {
final String sparql = //
"PREFIX dc: <http://purl.org/dc/elements/1.1/>\n"//
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"//
+ "DELETE FROM %cached_solution_set\n"//
+ "SELECT ?book ?date\n"//
+ "WHERE\n"//
+ " { GRAPH <http://example/bookStore>\n"//
+ " { ?book dc:date ?date .\n"//
+ " FILTER ( ?date > \"1970-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"//
+ " ?book ?p ?v\n"//
+ "} }";
final IV dcDate = makeIV(valueFactory.createURI("http://purl.org/dc/elements/1.1/date"));
final IV dateTime = makeIV(valueFactory.createLiteral("1970-01-01T00:00:00-02:00",XSD.DATETIME));
final IV bookstore = makeIV(valueFactory.createURI("http://example/bookStore"));
final UpdateRoot expected = new UpdateRoot();
{
final DeleteInsertGraph op = new DeleteInsertGraph();
expected.addChild(op);
{
final QuadsDataOrNamedSolutionSet deleteClause = new QuadsDataOrNamedSolutionSet(
"%cached_solution_set");
final ProjectionNode projection = new ProjectionNode();
deleteClause.setProjection(projection);
projection.addProjectionVar(new VarNode("book"));
projection.addProjectionVar(new VarNode("date"));
op.setDeleteClause(deleteClause);
}
{
final JoinGroupNode whereClause = new JoinGroupNode();
final JoinGroupNode graphGroup = new JoinGroupNode();
whereClause.addChild(graphGroup);
graphGroup.setContext(new ConstantNode(bookstore));
graphGroup.addChild(new StatementPatternNode(
new VarNode("book"), new ConstantNode(dcDate),
new VarNode("date"), new ConstantNode(bookstore),
Scope.NAMED_CONTEXTS));
graphGroup.addChild(new FilterNode(FunctionNode.GT(new VarNode(
"date"), new ConstantNode(dateTime))));
graphGroup.addChild(new StatementPatternNode(
new VarNode("book"), new VarNode("p"),
new VarNode("v"), new ConstantNode(bookstore),
Scope.NAMED_CONTEXTS));
op.setWhereClause(whereClause);
}
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* create solutions %solutionSet
* </pre>
*/
public void test_create_solutions() throws MalformedQueryException,
TokenMgrError, ParseException {
//CREATE ( SILENT )? SOLUTIONS SolutionSetName
final String sparql = "create solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final CreateGraph op = new CreateGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
assertTrue(op.isTargetSolutionSet());
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* create silent solutions %solutionSet
* </pre>
*/
public void test_create_solutions_silent() throws MalformedQueryException,
TokenMgrError, ParseException {
//CREATE ( SILENT )? SOLUTIONS SolutionSetName
final String sparql = "create silent solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final CreateGraph op = new CreateGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
op.setSilent(true);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* Example of a CREATE using a triples block to provision the named solution
* set.
*
* <pre>
* create silent solutions %solutionSet {
* hint:Query hint:engine "cache" .
* hint:Query hint:expireAge "100000"^^<http://www.w3.org/2001/XMLSchema#long> .
* }
* </pre>
*
* TODO Test to verify that we reject variables in the triples template
* (ground triples only).
*
* TODO Maybe specify the implementation class for the persistence?
*/
// @SuppressWarnings("rawtypes")
public void test_create_solutions_silent_params()
throws MalformedQueryException, TokenMgrError, ParseException {
//CREATE ( SILENT )? SOLUTIONS SolutionSetName { TriplesTemplate }
final String sparql = "create silent solutions %solutionSet {\n"//
+" hint:Query hint:engine \"cache\" .\n"
+" hint:Query hint:expireAge \"100000\"^^<http://www.w3.org/2001/XMLSchema#long> .\n"
+"}"
;
final UpdateRoot expected = new UpdateRoot();
{
final CreateGraph op = new CreateGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
op.setSilent(true);
// final IV hintQuery = makeIV(valueFactory.createURI(QueryHints.NAMESPACE+QueryHintScope.Query));
// final IV hintEngine = makeIV(valueFactory.createURI(QueryHints.NAMESPACE+"engine"));
// final IV hintExpireAge = makeIV(valueFactory.createURI(QueryHints.NAMESPACE+"expireAge"));
// final IV cache = makeIV(valueFactory.createLiteral("cache"));
// final IV millis = makeIV(valueFactory.createLiteral("100000",XSD.LONG));
// final QuadData params = new QuadData();
//
// params.addChild(new StatementPatternNode(
// new ConstantNode(hintQuery), new ConstantNode(hintEngine),
// new ConstantNode(cache)));
//
// params.addChild(new StatementPatternNode(
// new ConstantNode(hintQuery), new ConstantNode(hintExpireAge),
// new ConstantNode(millis)));
final BigdataURI hintQuery = valueFactory.createURI(QueryHints.NAMESPACE+QueryHintScope.Query);
final BigdataURI hintEngine = valueFactory.createURI(QueryHints.NAMESPACE+"engine");
final BigdataURI hintExpireAge = valueFactory.createURI(QueryHints.NAMESPACE+"expireAge");
final BigdataLiteral cache = valueFactory.createLiteral("cache");
final BigdataLiteral millis = valueFactory.createLiteral("100000",XSD.LONG);
final BigdataStatement[] params = new BigdataStatement[] {
valueFactory.createStatement(//
(BigdataResource)hintQuery, //
(BigdataURI)hintEngine,//
(BigdataValue)cache, //
null, // c
StatementEnum.Explicit),//
valueFactory.createStatement(//
(BigdataResource)hintQuery,//
(BigdataURI)hintExpireAge,//
(BigdataValue)millis,//
null,// c
StatementEnum.Explicit),//
};
op.setParams(params);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* drop solutions %solutionSet
* </pre>
*/
public void test_drop_solutions_namedSet() throws MalformedQueryException,
TokenMgrError, ParseException {
// DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "drop solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final DropGraph op = new DropGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* drop silent solutions %solutionSet
* </pre>
*/
public void test_drop_solutions_namedSet_silent() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "drop silent solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final DropGraph op = new DropGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
op.setSilent(true);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* drop solutions
* </pre>
*/
public void test_drop_solutions() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "drop solutions";
final UpdateRoot expected = new UpdateRoot();
{
final DropGraph op = new DropGraph();
op.setAllSolutionSets(true);
expected.addChild(op);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* drop graphs
* </pre>
*/
public void test_drop_graphs() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "drop graphs";
final UpdateRoot expected = new UpdateRoot();
{
final DropGraph op = new DropGraph();
op.setAllGraphs(true);
expected.addChild(op);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* clear solutions %solutionSet
* </pre>
*/
public void test_clear_solutions_namedSet() throws MalformedQueryException,
TokenMgrError, ParseException {
// DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "clear solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final ClearGraph op = new ClearGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* clear silent solutions %solutionSet
* </pre>
*/
public void test_clear_solutions_namedSet_silent() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "clear silent solutions %solutionSet";
final UpdateRoot expected = new UpdateRoot();
{
final ClearGraph op = new ClearGraph();
expected.addChild(op);
op.setTargetSolutionSet("%solutionSet");
op.setSilent(true);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* clear solutions
* </pre>
*/
public void test_clear_solutions() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME))
final String sparql = "clear solutions";
final UpdateRoot expected = new UpdateRoot();
{
final ClearGraph op = new ClearGraph();
op.setAllSolutionSets(true);
expected.addChild(op);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
/**
* <pre>
* clear graphs
* </pre>
*/
public void test_clear_graphs() throws MalformedQueryException,
TokenMgrError, ParseException {
//DROP ( SILENT )? (GRAPH IRIref | DEFAULT | NAMED | ALL | GRAPHS | SOLUTIONS | SOLUTIONS %VARNAME)
final String sparql = "clear graphs";
final UpdateRoot expected = new UpdateRoot();
{
final ClearGraph op = new ClearGraph();
op.setAllGraphs(true);
expected.addChild(op);
}
final UpdateRoot actual = parseUpdate(sparql, baseURI);
assertSameAST(sparql, expected, actual);
}
}