Class ValuesServiceQueryResolver
java.lang.Object
se.liu.ida.hefquin.engine.ValuesServiceQueryResolver
Queries with a WHERE clause of a form such as the following one need to be
rewritten, which is what this class does.
PREFIX ex: invalid input: '<'http://example.org/>
SELECT * WHERE {
VALUES (?s1 ?s2) {
(ex:endpoint1 ex:endpoint2)
(ex:endpoint1 ex:endpoint3)
}
SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
}
The rewriting that is applied to such query patterns is to apply the
solution mappings of the VALUES clause to the SERVICE clauses and, then
remove the VALUES clause. If the VALUES clause contains multiple solution
mappings (as in the example above), than the group of SERVICE clauses is
copied for each of these solution mappings, and the resulting groups are
combined via UNION. Additionally, in any of the two cases (just one solution
mapping in the VALUES clause or multiple), BIND clauses are appended to still
capture the bindings for the variables of the VALUES clause. For instance,
the result of rewriting the example query above is given as follows.
PREFIX ex: invalid input: '<'http://example.org/>
SELECT * WHERE {
{
SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
SERVICE ex:endpoint2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
BIND (?s1 AS ex:endpoint1)
BIND (?s2 AS ex:endpoint2)
}
UNION
{
SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
SERVICE ex:endpoint3 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
BIND (?s1 AS ex:endpoint1)
BIND (?s2 AS ex:endpoint3)
}
}
The VALUES clause may also be split up in the given queries, in order to
avoid a combinatorial blow-up of possible combinations. For instance, the
the initial example query above may also be provided in the following form
(which results in the same rewritten query).
PREFIX ex: invalid input: '<'http://example.org/>
SELECT * WHERE {
VALUES ?s1 { ex:endpoint1 }
VALUES ?s2 { ex:endpoint2 ex:endpoint3 }
SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
}
When using multiple VALUES clauses, it is not even necessary to place all
of them at the beginning of the WHERE clause. Instead, some of them may be
moved closer to the SERVICE clause(s) in which the variables of a VALUES
clause are used as the service variable. For instance, the initial example
query above may also be provided in the following form (but, then, the
rewritten version looks different, as discussed below).
PREFIX ex: invalid input: '<'http://example.org/>
SELECT * WHERE {
VALUES ?s1 { ex:endpoint1 }
SERVICE ?s1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
VALUES ?s2 { ex:endpoint2 ex:endpoint3 }
SERVICE ?s2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
}
However, queries given in this form (with VALUES clauses in between other
patterns) are treated slightly different by the rewriting algorithm in this
class. That is, every VALUES clause that follows some other patterns (such
as the VALUES clause with variable ?s2
in the previous example)
is considered to end the scope of rewriting based on the previous VALUES
clause(s) and to start a new rewriting scope. The rewritten parts from the
different rewriting scopes are joined together in the resulting rewritten
query. For instance, for the previous example query, the result looks as
follows.
PREFIX ex: invalid input: '<'http://example.org/>
SELECT * WHERE {
{
SERVICE ex:endpoint1 { .. some pattern (that neither mentions ?s1 nor ?2) .. }
BIND (?s1 AS ex:endpoint1)
}
{
SERVICE ex:endpoint2 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
BIND (?s2 AS ex:endpoint2)
}
UNION
{
SERVICE ex:endpoint3 { .. also some pattern (that also doesn't mention ?s1 or ?2) .. }
BIND (?s2 AS ex:endpoint3)
}
}
Notice that this resulting query differs from the one obtained for the
cases in which the VALUES clauses are all at the beginning of the given
query. Here, each rewriting scope results in its own UNION group (instead
of just one big UNION group for everything together). Yet, since the input
queries are semantically equivalent, the same also hold for the two resulting
queries.
The approach to consider different rewriting scopes introduces a limitation:
It does not support SERVICE clauses with a variable that is not bound by the
VALUES clause(s) that come closest before the SERVICE clause. Hence, HeFQUIN
cannot support queries with such SERVICE clauses.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static class
Transforms all SERVICE clauses that have a service variable by replacing this variable with the URI that a given solution mapping assigns to the variable.protected static class
This exception is used internally by this class.protected static class
This exception is used internally by this class.protected static class
Collects all variables in a givenElement
except for variables that occur *only* as the variable of SERVICE clauses.protected static class
Checks for each visited SERVICE clause that has a service variable whether that variable is in a given list of permitted variables. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected static List
<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern
(List<org.apache.jena.sparql.syntax.Element> elmts) Rewrites the given list of query elements (if needed).protected static List
<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern
(List<org.apache.jena.sparql.syntax.Element> elmts, org.apache.jena.sparql.syntax.ElementData valClause, int startPos) Rewrites the given list of query elements by using the solution mappings of the given VALUES clause as a basis, and starting only from the given position within the list (i.e., list elements that are at an earlier position in the list are ignored).static void
expandValuesPlusServicePattern
(org.apache.jena.query.Query q) If the WHERE clause of the given query is of a form that should be rewritten, then this method replaces the WHERE clause of the query by the rewritten one.protected static org.apache.jena.sparql.syntax.ElementData
merge
(org.apache.jena.sparql.syntax.ElementData valClause1, org.apache.jena.sparql.syntax.ElementData valClause2) Merges the two given VALUES clauses into a single one by creating a cross-product of their respective sets of solution mappings.protected static int
positionOfNextVALUES
(List<org.apache.jena.sparql.syntax.Element> elmts, int startPos) Determines the position of the next VALUES clause in the given list of query elements, starting from the given position (i.e., the first element that this function considers is the element at the given position).protected static org.apache.jena.sparql.syntax.Element
rewrite
(org.apache.jena.sparql.engine.binding.Binding solmap, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos, List<org.apache.jena.sparql.core.Var> varsForBind) Rewrites the query elements of the given list based on the given solution mapping, but considering only the list elements from the given start position until (and including) the given end position.protected static org.apache.jena.sparql.syntax.Element
rewrite
(org.apache.jena.sparql.syntax.ElementData valClause, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos) Rewrites the query elements of the given list based on the solution mappings of the given VALUES clause, but considering only the list elements from the given start position until (and including) the given end position.
-
Constructor Details
-
ValuesServiceQueryResolver
public ValuesServiceQueryResolver()
-
-
Method Details
-
expandValuesPlusServicePattern
public static void expandValuesPlusServicePattern(org.apache.jena.query.Query q) throws UnsupportedQueryException, IllegalQueryException If the WHERE clause of the given query is of a form that should be rewritten, then this method replaces the WHERE clause of the query by the rewritten one. Otherwise, the WHERE clause of the query is not changed. AnUnsupportedQueryException
is thrown if it is discovered that the WHERE clause of the given query uses VALUES clauses and SERVICE clauses in a way that is currently not supported. AnIllegalQueryException
is thrown if it is discovered that the WHERE clause of the given query uses VALUES clauses in an incorrect way. -
expandValuesPlusServicePattern
protected static List<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts) throws ValuesServiceQueryResolver.MyUnsupportedQueryException, ValuesServiceQueryResolver.MyIllegalQueryException Rewrites the given list of query elements (if needed). Returnsnull
if it turns out that nothing needs to be rewritten, which is the case if there is no VALUES clause in the given list or there is a VALUES clause but only as the very last element of the list. Throws anValuesServiceQueryResolver.MyIllegalQueryException
if it discovers two VALUES clauses whose sets of variables are not disjoint. -
expandValuesPlusServicePattern
protected static List<org.apache.jena.sparql.syntax.Element> expandValuesPlusServicePattern(List<org.apache.jena.sparql.syntax.Element> elmts, org.apache.jena.sparql.syntax.ElementData valClause, int startPos) throws ValuesServiceQueryResolver.MyUnsupportedQueryException, ValuesServiceQueryResolver.MyIllegalQueryException Rewrites the given list of query elements by using the solution mappings of the given VALUES clause as a basis, and starting only from the given position within the list (i.e., list elements that are at an earlier position in the list are ignored). May returnnull
, namely in case that given position is the very last position of the list and there is another VALUES clause at that position. Throws anValuesServiceQueryResolver.MyIllegalQueryException
if it discovers two VALUES clauses whose sets of variables are not disjoint. -
positionOfNextVALUES
protected static int positionOfNextVALUES(List<org.apache.jena.sparql.syntax.Element> elmts, int startPos) Determines the position of the next VALUES clause in the given list of query elements, starting from the given position (i.e., the first element that this function considers is the element at the given position). If there is no VALUES clause in the given list from the given position until the end of the list, then this function returns -1. -
merge
protected static org.apache.jena.sparql.syntax.ElementData merge(org.apache.jena.sparql.syntax.ElementData valClause1, org.apache.jena.sparql.syntax.ElementData valClause2) throws ValuesServiceQueryResolver.MyIllegalQueryException Merges the two given VALUES clauses into a single one by creating a cross-product of their respective sets of solution mappings. Throws anValuesServiceQueryResolver.MyIllegalQueryException
if the sets of variables of the two given VALUES clauses are not disjoint. -
rewrite
protected static org.apache.jena.sparql.syntax.Element rewrite(org.apache.jena.sparql.syntax.ElementData valClause, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos) Rewrites the query elements of the given list based on the solution mappings of the given VALUES clause, but considering only the list elements from the given start position until (and including) the given end position. Assumes that none of these elements is a VALUES clause. -
rewrite
protected static org.apache.jena.sparql.syntax.Element rewrite(org.apache.jena.sparql.engine.binding.Binding solmap, List<org.apache.jena.sparql.syntax.Element> elmts, int startPos, int endPos, List<org.apache.jena.sparql.core.Var> varsForBind) Rewrites the query elements of the given list based on the given solution mapping, but considering only the list elements from the given start position until (and including) the given end position. Assumes that none of these elements is a VALUES clause. The given list of variables is used to add BIND clauses; in particular, for every variable in this list, if the given solution mapping covers the variable, then a BIND clause is added that assigns the variable to the corresponding RDF term of the solution mapping.
-