Skip to content

Commit

Permalink
Merge main into develop (#5011)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmottestad committed Jun 4, 2024
2 parents a58ff06 + 510e719 commit c58eb52
Show file tree
Hide file tree
Showing 15 changed files with 2,089 additions and 27 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.function.Predicate;

import org.eclipse.rdf4j.collection.factory.api.CollectionFactory;
import org.eclipse.rdf4j.common.annotation.InternalUseOnly;
import org.eclipse.rdf4j.common.iteration.CloseableIteration;
import org.eclipse.rdf4j.common.iteration.LookAheadIteration;
import org.eclipse.rdf4j.model.Value;
Expand Down Expand Up @@ -130,7 +131,8 @@ public PathIteration(EvaluationStrategy strategy, Scope scope, Var startVar,
* @param s the name of the variable to see if it is in the bindingset
* @return the value of the start or end or if asked for a different field a null.
*/
private static final BiConsumer<Value, MutableBindingSet> getSet(String s) {
@InternalUseOnly
public static final BiConsumer<Value, MutableBindingSet> getSet(String s) {
switch (s) {
case START:
return (v, vp) -> ((ValuePair) vp).startValue = v;
Expand All @@ -149,7 +151,7 @@ private static final BiConsumer<Value, MutableBindingSet> getSet(String s) {
* @param s the name of the variable to see if it is in the bindingset
* @return the value of the start or end, if asked for a different field throw an illegalstate exception
*/
private static final Function<BindingSet, Value> getGet(String s) {
public static final Function<BindingSet, Value> getGet(String s) {
switch (s) {
case START:
return (vp) -> ((ValuePair) vp).startValue;
Expand All @@ -168,7 +170,7 @@ private static final Function<BindingSet, Value> getGet(String s) {
* @param s the name of the variable to see if it is in the bindingset
* @return true if start or end is not null, if asked for a different field throw an illegalstate exception
*/
private static final Predicate<BindingSet> getHas(String s) {
public static final Predicate<BindingSet> getHas(String s) {
switch (s) {
case START:
return (vp) -> ((ValuePair) vp).startValue != null;
Expand Down Expand Up @@ -431,7 +433,7 @@ protected boolean isUnbound(Var var, BindingSet bindings) {
* A specialized BingingSet that can only hold the start and end values of a Path. Minimizing unneeded memory use,
* and allows specialization in the sets required to answer this part of a query.
*/
protected static class ValuePair implements MutableBindingSet {
public static class ValuePair implements MutableBindingSet {
private static final long serialVersionUID = 1L;

private Value startValue;
Expand Down Expand Up @@ -614,7 +616,7 @@ public void meet(Var var) {
QueryModelNode parent = var.getParentNode();
parent.replaceChildNode(var, replacement.clone());
} else if (replaceAnons && var.isAnonymous() && !var.hasValue()) {
String varName = "anon-replace-" + var.getName() + index;
String varName = "anon_replace_" + var.getName() + index;
Var replacementVar = createAnonVar(varName, null, true);
QueryModelNode parent = var.getParentNode();
parent.replaceChildNode(var, replacementVar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public class ZeroLengthPathIteration extends LookAheadIteration<BindingSet> {

private static final Literal SUBJECT = SimpleValueFactory.getInstance().createLiteral("subject");

public static final String ANON_SUBJECT_VAR = "zero-length-internal-start";
public static final String ANON_SUBJECT_VAR = "zero_length_internal_start";

public static final String ANON_PREDICATE_VAR = "zero-length-internal-pred";
public static final String ANON_PREDICATE_VAR = "zero_length_internal_pred";

public static final String ANON_OBJECT_VAR = "zero-length-internal-end";
public static final String ANON_OBJECT_VAR = "zero_length_internal_end";

public static final String ANON_SEQUENCE_VAR = "zero-length-internal-seq";
public static final String ANON_SEQUENCE_VAR = "zero_length_internal_seq";

private QueryBindingSet result;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,12 @@ private void indexShape(Object shape, String field) {
doc.add(f);
}
} else if (shape instanceof double[]) { // WKT:POINT
double point[] = (double[]) shape;
double[] point = (double[]) shape;

for (Field f : LatLonShape.createIndexableFields(GEO_FIELD_PREFIX + field, point[1],
point[0])) {
doc.add(f);
}
doc.add(new LatLonPoint(POINT_FIELD_PREFIX + field, point[1], point[0]));
} else if (shape instanceof Rectangle) { // WKT:ENVELOPE / RECTANGLE
Rectangle box = (Rectangle) shape;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Function;

import org.apache.lucene.analysis.en.EnglishAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
Expand All @@ -39,12 +41,23 @@
import org.eclipse.rdf4j.common.concurrent.locks.Properties;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.base.CoreDatatype;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.impl.TreeModel;
import org.eclipse.rdf4j.model.vocabulary.GEO;
import org.eclipse.rdf4j.model.vocabulary.GEOF;
import org.eclipse.rdf4j.query.BindingSet;
import org.eclipse.rdf4j.query.TupleQuery;
import org.eclipse.rdf4j.query.TupleQueryResult;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
import org.eclipse.rdf4j.repository.util.Repositories;
import org.eclipse.rdf4j.sail.evaluation.TupleFunctionEvaluationMode;
import org.eclipse.rdf4j.sail.lucene.LuceneSail;
import org.eclipse.rdf4j.sail.lucene.SearchFields;
import org.eclipse.rdf4j.sail.memory.MemoryStore;
Expand Down Expand Up @@ -478,4 +491,85 @@ private void assertNoStatement(Statement statement, Document document) {
* for(String notFound : toFind) { assertEquals("Was the expected text value '" + notFound + "' found?", true,
* false); } }
*/

@Test
public void geoSparqlQueryTest() {
final String prefix = "http://www.example.org/#";
final String prefixes = "PREFIX ex: <" + prefix + ">\n"
+ "PREFIX geof: <" + GEOF.NAMESPACE + ">\n"
+ "PREFIX geo: <" + CoreDatatype.GEO.NAMESPACE + ">\n"
+ "PREFIX uom: <http://www.opengis.net/def/uom/OGC/1.0/>\n";
Model data = new TreeModel();

IRI cp = vf.createIRI(prefix + "cp");
IRI bm = vf.createIRI(prefix + "bm");
IRI nkv = vf.createIRI(prefix + "nkv");

data.add(cp, GEO.AS_WKT, vf.createLiteral("Point(4.38436 45.44917)", CoreDatatype.GEO.WKT_LITERAL));
data.add(bm, GEO.AS_WKT, vf.createLiteral("Point(4.38311 45.45423)", CoreDatatype.GEO.WKT_LITERAL));
data.add(nkv, GEO.AS_WKT, vf.createLiteral("Point(4.87306 45.77903)", CoreDatatype.GEO.WKT_LITERAL));
data.add(vf.createIRI(prefix + "arp"), GEO.AS_WKT,
vf.createLiteral("Point(2.89271 42.69848)", CoreDatatype.GEO.WKT_LITERAL));

String polyVill = "POLYGON((4.864712 45.784405, 4.883165 45.787756, 4.889946 45.785781, 4.904881 45.767403, 4.900761 45.765487, 4.872093 45.770995, 4.86454 45.770457, 4.858789 45.770277, 4.859905 45.784644, 4.864712 45.784405))";
String polySain = "POLYGON((4.380627 45.463983, 4.400539 45.462177, 4.428349 45.436286, 4.399509 45.411346, 4.374447 45.426528, 4.370499 45.450618, 4.380627 45.463983))";

SailRepository m1 = new SailRepository(new MemoryStore());
LuceneSail lc = new LuceneSail();
lc.setBaseSail(new MemoryStore());
lc.setParameter(LuceneSail.WKT_FIELDS, GEO.AS_WKT.toString());
lc.setLuceneIndex(index);
lc.setEvaluationMode(TupleFunctionEvaluationMode.NATIVE);
SailRepository m2 = new SailRepository(lc);

// add test data
Repositories.consume(m1, conn -> conn.add(data));
Repositories.consume(m2, conn -> conn.add(data));

lc.reindex();

Function<TupleQueryResult, Set<Value>> toval = (res) -> {
Set<Value> list = new HashSet<>();
while (res.hasNext()) {
BindingSet next = res.next();
list.add(next.getValue("v"));
}
return list;
};

// test queries

String q0 = prefixes
+ "SELECT * {\n"
+ " ?v geo:asWKT ?loc .\n"
+ " FILTER(geof:distance(\"Point(4.386914 45.440637)\"^^geo:wktLiteral, ?loc, uom:metre) < 10000) \n"
+ "}\n";
Set<Value> q0ex = Set.of(bm, cp);

String q1 = prefixes
+ "SELECT * {\n"
+ " ?v geo:asWKT ?loc .\n"
+ " FILTER(geof:ehContains(\"" + polySain + "\"^^geo:wktLiteral, ?loc)) \n"
+ "}\n";
Set<Value> q1ex = Set.of(bm, cp);

String q2 = prefixes
+ "SELECT * {\n"
+ " ?v geo:asWKT ?loc .\n"
+ " FILTER(geof:ehContains(\"" + polyVill + "\"^^geo:wktLiteral, ?loc)) \n"
+ "}\n";
Set<Value> q2ex = Set.of(nkv);

Set<Value> nlcq0 = Repositories.tupleQuery(m1, q0, toval);
Set<Value> nlcq1 = Repositories.tupleQuery(m1, q1, toval);
Set<Value> nlcq2 = Repositories.tupleQuery(m1, q2, toval);

assertEquals(q0ex, nlcq0);
assertEquals(q1ex, nlcq1);
assertEquals(q2ex, nlcq2);

assertEquals(nlcq0, Repositories.tupleQuery(m2, q0, toval));
assertEquals(nlcq1, Repositories.tupleQuery(m2, q1, toval));
assertEquals(nlcq2, Repositories.tupleQuery(m2, q2, toval));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2024 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.federated.algebra;

import java.util.List;

import org.eclipse.rdf4j.federated.structures.QueryInfo;
import org.eclipse.rdf4j.federated.util.QueryAlgebraUtil;
import org.eclipse.rdf4j.query.algebra.ArbitraryLengthPath;
import org.eclipse.rdf4j.query.algebra.Var;

/**
* A specialization of {@link ArbitraryLengthPath} to maintain the {@link QueryInfo}
*
* @author Andreas Schwarte
*/
public class FedXArbitraryLengthPath extends ArbitraryLengthPath implements FedXTupleExpr {

private static final long serialVersionUID = -7512248084095130084L;

private final QueryInfo queryInfo;

public FedXArbitraryLengthPath(ArbitraryLengthPath path, QueryInfo queryInfo) {
super(path.getScope(), clone(path.getSubjectVar()), path.getPathExpression(), clone(path.getObjectVar()),
clone(path.getContextVar()), path.getMinLength());
this.queryInfo = queryInfo;
}

private static Var clone(Var var) {
if (var == null) {
return null;
}
return var.clone();
}

@Override
public List<String> getFreeVars() {
return List.copyOf(QueryAlgebraUtil.getFreeVars(getPathExpression()));
}

@Override
public QueryInfo getQueryInfo() {
return queryInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2024 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.federated.algebra;

import java.util.List;

import org.eclipse.rdf4j.federated.structures.QueryInfo;
import org.eclipse.rdf4j.query.algebra.StatementPattern.Scope;
import org.eclipse.rdf4j.query.algebra.Var;
import org.eclipse.rdf4j.query.algebra.ZeroLengthPath;

/**
* A specialization of {@link ZeroLengthPath} that keeps track of {@link QueryInfo} and statement sources.
*
* @author Andreas Schwarte
*/
public class FedXZeroLengthPath extends ZeroLengthPath implements QueryRef {

private static final long serialVersionUID = 2241037911187178861L;

private final QueryInfo queryInfo;

private final List<StatementSource> statementSources;

public FedXZeroLengthPath(Scope scope, Var subjVar, Var objVar, Var conVar, QueryInfo queryInfo,
List<StatementSource> statementSources) {
super(scope, subjVar, objVar, conVar);
this.queryInfo = queryInfo;
this.statementSources = statementSources;
}

public List<StatementSource> getStatementSources() {
return statementSources;
}

@Override
public QueryInfo getQueryInfo() {
return queryInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2024 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.federated.algebra;

import org.eclipse.rdf4j.query.algebra.AbstractQueryModelNode;
import org.eclipse.rdf4j.query.algebra.QueryModelNode;
import org.eclipse.rdf4j.query.algebra.QueryModelVisitor;

/**
* An artificial holder node serving as parent holder to allow replacement.
*/
public class HolderNode extends AbstractQueryModelNode {

private static final long serialVersionUID = -4689963986499825771L;
private QueryModelNode child;

public HolderNode(QueryModelNode child) {
super();
setChild(child);
}

public void setChild(QueryModelNode child) {
this.child = child;
this.child.setParentNode(this);
}

@Override
public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor) throws X {
child.visit(visitor);
}

@Override
public <X extends Exception> void visit(QueryModelVisitor<X> visitor) throws X {
visitor.meetOther(this);
}

@Override
public void replaceChildNode(QueryModelNode current, QueryModelNode replacement) {
if (child.equals(current)) {
setChild(replacement);

}
}
}
Loading

0 comments on commit c58eb52

Please sign in to comment.