iris) {
/**
* Converts an API {@link BindingSet} into a KGRAM {@link Mapping} that can be
- * passed to {@link Eval#query(Node, Query, Mapping)} as initial variable bindings.
+ * passed to {@link Eval#query(Node, QueryPlan, Mapping)} as initial variable bindings.
*
* Each binding entry becomes a (variable-node, value-node) pair. The variable
* node carries the variable name as its label so that
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/StreamingTupleQueryResult.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/StreamingTupleQueryResult.java
index c0956f620..c5ab4a6dd 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/StreamingTupleQueryResult.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/StreamingTupleQueryResult.java
@@ -7,7 +7,7 @@
import fr.inria.corese.core.next.query.impl.engine.diagnostics.ExecutionDiagnostics;
import fr.inria.corese.core.next.query.impl.engine.eval.SelectCursor;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.solution.Mappings;
import fr.inria.corese.core.next.query.impl.engine.storage.StorageManagerProducer;
import fr.inria.corese.core.next.storage.api.StorageManager;
@@ -58,7 +58,7 @@ private static ScheduledThreadPoolExecutor deadlines() {
private BindingSet delivered;
private boolean unwound;
- StreamingTupleQueryResult(SelectCursor cursor, Query query,
+ StreamingTupleQueryResult(SelectCursor cursor, QueryPlan query,
StorageManagerProducer producer, StorageManager snapshot, ExecutionDiagnostics diagnostics,
long timeoutMillis, long started) {
this.cursor = cursor;
@@ -162,7 +162,7 @@ private boolean beginAdvance() {
if (timedOut) throw new QueryTimeoutException(timeoutMillis);
if (closed) throw new IllegalStateException("This tuple query result is closed.");
if (exhausted) return false;
- if (owner.isInterrupted()) throw new QueryEvaluationException("Query interrupted");
+ if (owner.isInterrupted()) throw new QueryEvaluationException("QueryPlan interrupted");
advancing = true;
return true;
}
@@ -175,7 +175,7 @@ private void endAdvance() {
Thread.interrupted();
throw new QueryTimeoutException(timeoutMillis);
}
- if (closed) throw new QueryEvaluationException("Query cursor was cancelled");
+ if (closed) throw new QueryEvaluationException("QueryPlan cursor was cancelled");
}
}
@@ -202,7 +202,7 @@ public BindingSet next() {
private void checkOwner() {
if (Thread.currentThread() != owner) {
- throw new IllegalStateException("Query results must be consumed on their creating thread");
+ throw new IllegalStateException("QueryPlan results must be consumed on their creating thread");
}
}
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelector.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelector.java
index 33bdaea75..e6bd33679 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelector.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelector.java
@@ -1,7 +1,7 @@
package fr.inria.corese.core.next.query.impl.sparql.execution;
import fr.inria.corese.core.next.query.impl.engine.eval.Eval;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.solution.Mapping;
import fr.inria.corese.core.next.query.impl.engine.solution.Mappings;
@@ -31,7 +31,7 @@ final class TopKSelector {
* @param query completed eligible ordered SELECT with finite LIMIT plus OFFSET
* @param eval evaluator supplying the official Corese ordering comparator
*/
- TopKSelector(Query query, Eval eval) {
+ TopKSelector(QueryPlan query, Eval eval) {
capacity = Math.addExact(query.getLimit(), query.getOffset());
offset = query.getOffset();
needsInput = query.getLimit() != 0;
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/diagnostics/QueryDeliveryDiagnosticsTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/diagnostics/QueryDeliveryDiagnosticsTest.java
index dac93de70..a3840d98c 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/diagnostics/QueryDeliveryDiagnosticsTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/diagnostics/QueryDeliveryDiagnosticsTest.java
@@ -9,7 +9,7 @@
import fr.inria.corese.core.next.query.impl.engine.eval.SelectCursor;
import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.sparql.execution.SparqlQueryExecutor;
import fr.inria.corese.core.next.storage.api.StorageManager;
import fr.inria.corese.core.next.storage.api.operations.QueryOperations;
@@ -298,9 +298,9 @@ void aTraversalFailureBeforeAnyRowDoesNotClaimAnEmptyResult() {
@Test
void guardClassificationDoesNotExecuteAnUnsupportedServiceOrExtension() {
- assertEquals(FallbackReason.SERVICE, SelectCursor.fallbackReason(Query.create(Exp.create(Type.SERVICE))));
+ assertEquals(FallbackReason.SERVICE, SelectCursor.fallbackReason(QueryPlan.create(Exp.create(Type.SERVICE))));
var functional = Exp.create(Type.BIND);
functional.setFunctional(true);
- assertEquals(FallbackReason.UNSUPPORTED_OPERATOR, SelectCursor.fallbackReason(Query.create(functional)));
+ assertEquals(FallbackReason.UNSUPPORTED_OPERATOR, SelectCursor.fallbackReason(QueryPlan.create(functional)));
}
}
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java
index aa20102e4..b0d9d693c 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/eval/EvalTest.java
@@ -14,7 +14,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.model.BindingContext;
import fr.inria.corese.core.next.query.impl.engine.event.ResultListener;
import org.junit.jupiter.api.BeforeEach;
@@ -428,7 +428,7 @@ void testServiceWithoutProviderThrows() {
Stack stack = new Stack();
stack.add(serviceExp);
- Query q = Query.create();
+ QueryPlan q = QueryPlan.create();
eval.init(q);
assertThrows(QueryEvaluationException.class, () ->
@@ -445,7 +445,7 @@ void testServiceSilentWithoutProviderBypasses() {
Stack stack = new Stack();
stack.add(serviceExp);
- Query q = Query.create();
+ QueryPlan q = QueryPlan.create();
eval.init(q);
assertDoesNotThrow(() -> eval.eval(mockProducer, null, stack, null, 0),
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlanTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlanTest.java
index 3e211d0ac..394bb80b3 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlanTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlanTest.java
@@ -26,10 +26,10 @@ class CompiledQueryPlanTest {
@Test
void captureDetachesTheCompilerAndEveryExecutionHasIndependentMutableState() {
- Query compiler = query();
+ QueryPlan compiler = query();
CompiledQueryPlan image = CompiledQueryPlan.capture(compiler, Map.of());
- Query first = image.newExecution(null);
- Query second = image.newExecution(null);
+ QueryPlan first = image.newExecution(null);
+ QueryPlan second = image.newExecution(null);
assertNotSame(first, second);
assertEquals(first.getSelect().size(), second.getSelect().size());
Node firstVariable = first.getSelect().getFirst();
@@ -42,7 +42,7 @@ void captureDetachesTheCompilerAndEveryExecutionHasIndependentMutableState() {
compiler.getSelect().clear();
compiler.setLimit(2);
assertEquals(compiledIndex, secondVariable.getIndex());
- Query fresh = image.newExecution(null);
+ QueryPlan fresh = image.newExecution(null);
assertEquals(2, fresh.getSelect().size());
assertEquals(Integer.MAX_VALUE, fresh.getLimit());
assertEquals(compiledIndex, fresh.getSelect().getFirst().getIndex());
@@ -52,8 +52,8 @@ void captureDetachesTheCompilerAndEveryExecutionHasIndependentMutableState() {
@Test
void valuesRowsAndFilterIndexesAreNotShared() {
CompiledQueryPlan image = CompiledQueryPlan.capture(query(), Map.of());
- Query first = image.newExecution(null);
- Query second = image.newExecution(null);
+ QueryPlan first = image.newExecution(null);
+ QueryPlan second = image.newExecution(null);
Exp firstValues = operators(first).stream().filter(e -> e.type() == Exp.Type.VALUES).findFirst().orElseThrow();
Exp secondValues = operators(second).stream().filter(e -> e.type() == Exp.Type.VALUES).findFirst().orElseThrow();
assertNotSame(firstValues.getMappings(), secondValues.getMappings());
@@ -72,7 +72,7 @@ void valuesRowsAndFilterIndexesAreNotShared() {
@Test
void copiesPreserveIdentityWithinAFrameAndRejectUnknownMutablePayloads() {
- Query first = CompiledQueryPlan.capture(query(), Map.of()).newExecution(null);
+ QueryPlan first = CompiledQueryPlan.capture(query(), Map.of()).newExecution(null);
Exp values = operators(first).stream().filter(e -> e.type() == Exp.Type.VALUES).findFirst().orElseThrow();
Node variable = first.getSelect().getFirst();
assertSame(variable, values.getNodeList().getFirst());
@@ -80,9 +80,9 @@ void copiesPreserveIdentityWithinAFrameAndRejectUnknownMutablePayloads() {
assertThrows(IllegalArgumentException.class, () -> new PlanCopy().copy(new StringBuilder()));
}
- private static Query query() {
+ private static QueryPlan query() {
var ast = (SelectQueryAst) new SparqlParser().parse(TEXT);
- Query query = new CoreseAstQueryBuilder().toNextQuery(ast);
+ QueryPlan query = new CoreseAstQueryBuilder().toNextQuery(ast);
query.complete(new ProducerDefault());
return query;
}
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlanTest.java
similarity index 90%
rename from src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java
rename to src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlanTest.java
index 14a1cd1f8..805d6a9e8 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlanTest.java
@@ -17,15 +17,15 @@
import static org.mockito.Mockito.when;
/**
- * Comprehensive unit tests for Query class.
+ * Comprehensive unit tests for QueryPlan class.
* Tests KGRAM query structure including select, from, where, order by,
* group by, having, filters, and various query types.
*
*/
-@DisplayName("Query Tests")
-class QueryTest {
+@DisplayName("QueryPlan Tests")
+class QueryPlanTest {
- private Query query;
+ private QueryPlan query;
private Node mockNode;
private Filter mockFilter;
@@ -33,18 +33,18 @@ class QueryTest {
void setUp() {
mockNode = mock(Node.class);
mockFilter = mock(Filter.class);
- query = new Query();
+ query = new QueryPlan();
}
@Nested
- @DisplayName("Query Creation Tests")
+ @DisplayName("QueryPlan Creation Tests")
class QueryCreationTests {
@Test
@DisplayName("Should create empty query")
void testCreateEmptyQuery() {
- Query q = new Query();
- assertNotNull(q, "Query should not be null");
+ QueryPlan q = new QueryPlan();
+ assertNotNull(q, "QueryPlan should not be null");
assertEquals(ExpType.Type.QUERY, q.type(), "Type should be QUERY");
}
@@ -52,15 +52,15 @@ void testCreateEmptyQuery() {
@DisplayName("Should create query using factory method")
void testCreateQueryFactory() {
Exp exp = Exp.create(ExpType.Type.AND);
- Query q = Query.create(exp);
- assertNotNull(q, "Query should not be null");
+ QueryPlan q = QueryPlan.create(exp);
+ assertNotNull(q, "QueryPlan should not be null");
}
@Test
@DisplayName("Should create an empty query")
void testCreateQueryWithType() {
- Query q = Query.create();
- assertNotNull(q, "Query should not be null");
+ QueryPlan q = QueryPlan.create();
+ assertNotNull(q, "QueryPlan should not be null");
}
}
@@ -120,13 +120,13 @@ class DistinctTests {
@DisplayName("Should set and check distinct")
void testSetAndIsDistinct() {
query.setDistinct(true);
- assertTrue(query.isDistinct(), "Query should be distinct");
+ assertTrue(query.isDistinct(), "QueryPlan should be distinct");
}
@Test
@DisplayName("Should not be distinct by default")
void testDefaultDistinct() {
- assertFalse(query.isDistinct(), "Query should not be distinct by default");
+ assertFalse(query.isDistinct(), "QueryPlan should not be distinct by default");
}
}
@@ -194,7 +194,7 @@ void testIsSelect() {
void testAskIsNotSelect() {
query.setAsk(true);
- assertTrue(query.isAsk(), "Query should be flagged as ASK");
+ assertTrue(query.isAsk(), "QueryPlan should be flagged as ASK");
assertFalse(query.isSelect(), "ASK query should not be reported as SELECT");
}
}
@@ -276,7 +276,7 @@ void testIsOrderBy() {
@Test
@DisplayName("Should chain order by")
void testOrderByChaining() {
- Query result = query.orderBy(mockNode);
+ QueryPlan result = query.orderBy(mockNode);
assertSame(query, result, "Should return same query for chaining");
}
}
@@ -329,7 +329,7 @@ void testHasGroupBy() {
@Test
@DisplayName("Should chain group by")
void testGroupByChaining() {
- Query result = query.groupBy(mockNode);
+ QueryPlan result = query.groupBy(mockNode);
assertSame(query, result, "Should return same query for chaining");
}
}
@@ -355,7 +355,7 @@ class ConstructTests {
@DisplayName("Should set and check if is construct")
void testSetAndIsConstruct() {
query.setConstruct(true);
- assertTrue(query.isConstruct(), "Query should be construct");
+ assertTrue(query.isConstruct(), "QueryPlan should be construct");
}
@Test
@@ -384,7 +384,7 @@ class DeleteTests {
@DisplayName("Should set and check if is delete")
void testSetAndIsDelete() {
query.setDelete(true);
- assertTrue(query.isDelete(), "Query should be delete");
+ assertTrue(query.isDelete(), "QueryPlan should be delete");
}
@Test
@@ -404,14 +404,14 @@ class UpdateTests {
@DisplayName("Should set and check if is update")
void testSetAndIsUpdate() {
query.setUpdate(true);
- assertTrue(query.isUpdate(), "Query should be update");
+ assertTrue(query.isUpdate(), "QueryPlan should be update");
}
@Test
@DisplayName("Should set and check if is insert")
void testSetAndIsInsert() {
query.setInsert(true);
- assertTrue(query.isInsert(), "Query should be insert");
+ assertTrue(query.isInsert(), "QueryPlan should be insert");
}
}
@@ -423,7 +423,7 @@ class AggregateTests {
@DisplayName("Should set and check if is aggregate")
void testSetAndIsAggregate() {
query.setAggregate(true);
- assertTrue(query.isAggregate(), "Query should be aggregate");
+ assertTrue(query.isAggregate(), "QueryPlan should be aggregate");
}
@Test
@@ -469,7 +469,7 @@ void testGetPatternNodes() {
@DisplayName("Should get query nodes")
void testGetQueryNodes() {
List nodes = query.getQueryNodes();
- assertNotNull(nodes, "Query nodes should not be null");
+ assertNotNull(nodes, "QueryPlan nodes should not be null");
}
@Test
@@ -514,56 +514,56 @@ void testSetAndGetGraphNode() {
}
@Nested
- @DisplayName("Query Flags Tests")
+ @DisplayName("QueryPlan Flags Tests")
class QueryFlagsTests {
@Test
@DisplayName("Should set and check relax flag")
void testSetAndIsRelax() {
query.setRelax(true);
- assertTrue(query.isRelax(), "Query should be relax");
+ assertTrue(query.isRelax(), "QueryPlan should be relax");
}
@Test
@DisplayName("Should set and check optimize flag")
void testSetAndIsOptimize() {
query.setOptimize(true);
- assertTrue(query.isOptimize(), "Query should be optimize");
+ assertTrue(query.isOptimize(), "QueryPlan should be optimize");
}
@Test
@DisplayName("Should set and check test flag")
void testSetAndIsTest() {
query.setTest(true);
- assertTrue(query.isTest(), "Query should be test");
+ assertTrue(query.isTest(), "QueryPlan should be test");
}
@Test
@DisplayName("Should set and check new flag")
void testSetAndIsNew() {
query.setNew(false);
- assertFalse(query.isNew(), "Query should not be new");
+ assertFalse(query.isNew(), "QueryPlan should not be new");
}
@Test
@DisplayName("Should set and check correct flag")
void testSetAndIsCorrect() {
query.setCorrect(false);
- assertFalse(query.isCorrect(), "Query should not be correct");
+ assertFalse(query.isCorrect(), "QueryPlan should not be correct");
}
@Test
@DisplayName("Should set and check map flag")
void testSetAndIsMap() {
query.setMap(false);
- assertFalse(query.isMap(), "Query should not be map");
+ assertFalse(query.isMap(), "QueryPlan should not be map");
}
@Test
@DisplayName("Should set and check rule flag")
void testSetAndIsRule() {
query.setRule(true);
- assertTrue(query.isRule(), "Query should be rule");
+ assertTrue(query.isRule(), "QueryPlan should be rule");
}
@Test
@@ -590,7 +590,7 @@ class ServiceTests {
@DisplayName("Should set and check if is service")
void testSetAndIsService() {
query.setService(true);
- assertTrue(query.isService(), "Query should be service");
+ assertTrue(query.isService(), "QueryPlan should be service");
}
@Test
@@ -603,20 +603,20 @@ void testSetAndGetService() {
}
@Nested
- @DisplayName("Global Query Tests")
+ @DisplayName("Global QueryPlan Tests")
class GlobalQueryTests {
@Test
@DisplayName("Should get global query")
void testGetGlobalQuery() {
- Query global = query.getGlobalQuery();
+ QueryPlan global = query.getGlobalQuery();
assertSame(query, global, "Should return self when not subquery");
}
@Test
@DisplayName("Should set outer query")
void testSetOuterQuery() {
- Query outer = new Query();
+ QueryPlan outer = new QueryPlan();
query.setOuterQuery(outer);
assertEquals(outer, query.getOuterQuery(), "Outer query should match");
}
@@ -624,7 +624,7 @@ void testSetOuterQuery() {
@Test
@DisplayName("Should get outer query")
void testGetOuterQuery() {
- Query outer = query.getOuterQuery();
+ QueryPlan outer = query.getOuterQuery();
assertSame(query, outer, "Should return self when no outer query");
}
}
@@ -637,14 +637,14 @@ class FederateValidateTests {
@DisplayName("Should set and check federate flag")
void testSetAndIsFederate() {
query.setFederate(true);
- assertTrue(query.isFederate(), "Query should be federate");
+ assertTrue(query.isFederate(), "QueryPlan should be federate");
}
@Test
@DisplayName("Should set and check validate flag")
void testSetAndIsValidate() {
query.setValidate(true);
- assertTrue(query.isValidate(), "Query should be validate");
+ assertTrue(query.isValidate(), "QueryPlan should be validate");
}
}
@@ -663,7 +663,7 @@ void testToString() {
@DisplayName("Should get datatype label")
void testGetDatatypeLabel() {
String label = query.getDatatypeLabel();
- assertEquals("[Query]", label, "Datatype label should be [Query]");
+ assertEquals("[QueryPlan]", label, "Datatype label should be [QueryPlan]");
}
}
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java
new file mode 100644
index 000000000..41dbded89
--- /dev/null
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java
@@ -0,0 +1,135 @@
+package fr.inria.corese.core.next.query.impl.engine.pattern;
+
+import fr.inria.corese.core.next.query.impl.engine.model.Node;
+import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@DisplayName("VariableLayout Tests")
+class VariableLayoutTest {
+
+ @Test
+ @DisplayName("Should allocate sequential node and edge indexes")
+ void shouldAllocateIndexes() {
+ VariableLayout layout = new VariableLayout();
+
+ assertEquals(0, layout.getNodeIndex());
+ assertEquals(0, layout.getEdgeIndex());
+
+ assertEquals(0, layout.allocateNodeIndex());
+ assertEquals(1, layout.allocateNodeIndex());
+ assertEquals(2, layout.getNodeIndex());
+
+ assertEquals(0, layout.allocateEdgeIndex());
+ assertEquals(1, layout.allocateEdgeIndex());
+ assertEquals(2, layout.getEdgeIndex());
+
+ layout.setNodeIndex(10);
+ assertEquals(10, layout.getNodeIndex());
+ layout.setEdgeIndex(20);
+ assertEquals(20, layout.getEdgeIndex());
+ }
+
+ @Test
+ @DisplayName("Should store nodes in appropriate pattern and query collections")
+ void shouldStoreNodesCorrectly() {
+ VariableLayout layout = new VariableLayout();
+ Node pNode = NodeImpl.forVariable("?p");
+ Node psNode = NodeImpl.forVariable("?ps");
+ Node qNode = NodeImpl.forVariable("?q");
+ Node qsNode = NodeImpl.forVariable("?qs");
+
+ // Pattern regular node (exist = false, select = false)
+ layout.store(pNode, false, false);
+ // Pattern select node (exist = false, select = true)
+ layout.store(psNode, false, true);
+ // Query regular node (exist = true, select = false)
+ layout.store(qNode, true, false);
+ // Query select node (exist = true, select = true)
+ layout.store(qsNode, true, true);
+
+ assertEquals(List.of(pNode), layout.getPatternNodes());
+ assertEquals(List.of(psNode), layout.getPatternSelectNodes());
+ assertEquals(List.of(qNode), layout.getQueryNodes());
+ assertEquals(List.of(qsNode), layout.getQuerySelectNodes());
+
+ assertSame(pNode, layout.getPatternNode("?p"));
+ assertSame(psNode, layout.getPatternSelectNode("?ps"));
+ assertSame(qNode, layout.getQueryNode("?q"));
+ assertSame(qsNode, layout.getQuerySelectNode("?qs"));
+
+ assertNull(layout.getPatternNode("?unknown"));
+ }
+
+ @Test
+ @DisplayName("Should ignore non-variable and blank nodes when storing")
+ void shouldIgnoreNonVariableAndBlankNodes() {
+ VariableLayout layout = new VariableLayout();
+
+ Node blankNode = NodeImpl.forBlankVariable("_:b0");
+ Node constantNode = NodeImpl.forIRI("http://example.org/item");
+
+ layout.store(blankNode, false, false);
+ layout.store(constantNode, false, false);
+
+ assertTrue(layout.getPatternNodes().isEmpty());
+ }
+
+ @Test
+ @DisplayName("Should resolve external nodes in hierarchical precedence")
+ void shouldResolveExtNodeWithPrecedence() {
+ VariableLayout layout = new VariableLayout();
+ Node pNode = NodeImpl.forVariable("?x");
+ layout.store(pNode, false, false);
+
+ Node selectNode = NodeImpl.forVariable("?selectX");
+
+ assertSame(pNode, layout.getExtNode("?x", false, null));
+ assertSame(pNode, layout.getNode("?x", null));
+
+ assertSame(selectNode, layout.getExtNode("?y", true, selectNode));
+ assertNull(layout.getExtNode("?y", false, selectNode));
+ }
+
+ @Test
+ @DisplayName("Should copy layout cleanly using PlanCopy")
+ void shouldCopyFromCleanly() {
+ VariableLayout source = new VariableLayout();
+ Node n1 = NodeImpl.forVariable("?n1");
+ Node n2 = NodeImpl.forVariable("?n2");
+ source.store(n1, false, false);
+ source.store(n2, true, true);
+ source.allocateNodeIndex();
+ source.allocateEdgeIndex();
+
+ PlanCopy copyContext = new PlanCopy();
+ VariableLayout target = new VariableLayout();
+ target.copyFrom(source, copyContext);
+
+ assertEquals(source.getNodeIndex(), target.getNodeIndex());
+ assertEquals(source.getEdgeIndex(), target.getEdgeIndex());
+ assertEquals(1, target.getPatternNodes().size());
+ assertEquals(1, target.getQuerySelectNodes().size());
+ assertEquals("?n1", target.getPatternNodes().get(0).getLabel());
+ assertEquals("?n2", target.getQuerySelectNodes().get(0).getLabel());
+ }
+
+ @Test
+ @DisplayName("Should manage binding, construct and arg node collections")
+ void shouldManageAuxiliaryNodeLists() {
+ VariableLayout layout = new VariableLayout();
+ Node bNode = NodeImpl.forVariable("?b");
+ Node cNode = NodeImpl.forVariable("?c");
+
+ layout.setBindingNodes(List.of(bNode));
+ layout.setConstructNodes(List.of(cNode));
+
+ assertEquals(List.of(bNode), layout.getBindingNodes());
+ assertEquals(List.of(cNode), layout.getConstructNodes());
+ assertNotNull(layout.getArgList());
+ }
+}
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/planning/CardinalityQueryPlannerTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/planning/CardinalityQueryPlannerTest.java
index e2f887152..66485e866 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/planning/CardinalityQueryPlannerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/planning/CardinalityQueryPlannerTest.java
@@ -8,7 +8,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
import fr.inria.corese.core.next.query.impl.engine.path.PropertyPathEdge;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.storage.ProducerDefault;
import fr.inria.corese.core.next.query.impl.engine.storage.StorageManagerProducer;
import fr.inria.corese.core.next.query.impl.sparql.ast.SelectQueryAst;
@@ -68,7 +68,7 @@ void close() {
@Test
void choosesSelectiveFirstPatternWithoutOpeningCursorsOrTransactions() {
- Query query = query(BROAD_THEN_SELECTIVE);
+ QueryPlan query = query(BROAD_THEN_SELECTIVE);
QueryOperations operations = mock(QueryOperations.class, delegatesTo(storage.queries()));
StorageManager observed = mock(StorageManager.class);
when(observed.queries()).thenReturn(operations);
@@ -109,7 +109,7 @@ void executionStartsWithSelectivePatternAndReadsOnlyTwoStatements() {
@Test
void connectedJoinsPrecedeDisconnectedPatternsAfterSelectiveSeed() {
- Query query = query("?s :link ?v . ?u :unrelated ?z . ?s :seed ?x");
+ QueryPlan query = query("?s :link ?v . ?u :unrelated ?z . ?s :seed ?x");
query.complete(new StatisticsProducer(Map.of("urn:bench:link", 100L,
"urn:bench:unrelated", 2L, "urn:bench:seed", 1L)));
assertEquals(List.of("urn:bench:seed", "urn:bench:link", "urn:bench:unrelated"), predicates(query));
@@ -117,10 +117,10 @@ void connectedJoinsPrecedeDisconnectedPatternsAfterSelectiveSeed() {
@Test
void variablePredicatesParticipateInJoinConnectivity() {
- Query query = query("?s ?p :seed . ?u :unrelated ?z . ?p :link ?x");
+ QueryPlan query = query("?s ?p :seed . ?u :unrelated ?z . ?p :link ?x");
query.complete(new StatisticsProducer(Map.of("urn:bench:link", 100L, "urn:bench:unrelated", 2L)) {
@Override
- public long estimateCardinality(Query scope, Node graph, Edge edge) {
+ public long estimateCardinality(QueryPlan scope, Node graph, Edge edge) {
return edge.getEdgeVariable() == null ? super.estimateCardinality(scope, graph, edge) : 1;
}
});
@@ -132,7 +132,7 @@ public long estimateCardinality(Query scope, Node graph, Edge edge) {
@Test
void cardinalitiesRetainLongPrecision() {
- Query query = query("?s :large ?x . ?s :small ?y");
+ QueryPlan query = query("?s :large ?x . ?s :small ?y");
query.complete(new StatisticsProducer(Map.of("urn:bench:large", Long.MAX_VALUE,
"urn:bench:small", 3_000_000_000L)));
assertEquals(List.of("urn:bench:small", "urn:bench:large"), predicates(query));
@@ -141,14 +141,14 @@ void cardinalitiesRetainLongPrecision() {
@ParameterizedTest
@ValueSource(longs = {0, QueryStatistics.UNKNOWN_CARDINALITY, 7})
void equalOrUnavailableStatisticsKeepStableSourceOrder(long count) {
- Query query = query("?s :left ?x . ?s :right ?y");
+ QueryPlan query = query("?s :left ?x . ?s :right ?y");
query.complete(new StatisticsProducer(Map.of("urn:bench:left", count, "urn:bench:right", count)));
assertEquals(List.of("urn:bench:left", "urn:bench:right"), predicates(query));
}
@Test
void producerWithoutStatisticsRetainsConnectedFallback() {
- Query query = query(BROAD_THEN_SELECTIVE);
+ QueryPlan query = query(BROAD_THEN_SELECTIVE);
query.complete(new ProducerDefault());
assertEquals(List.of("urn:bench:type", "urn:bench:name"), predicates(query));
}
@@ -180,7 +180,7 @@ void singlePatternAskDoesNotRequestStatistics() {
@Test
void emptyStorageProducesStablePlansAndEmptyResults() {
storage.mutations().clear();
- Query query = query(BROAD_THEN_SELECTIVE);
+ QueryPlan query = query(BROAD_THEN_SELECTIVE);
query.complete(new StorageManagerProducer(storage));
assertEquals(List.of("urn:bench:type", "urn:bench:name"), predicates(query));
try (var result = new SparqlQueryExecutor(storage).evaluateTuple(
@@ -230,7 +230,7 @@ void valuesAndUnionPreserveSolutionBags() {
@Test
void pathsAreBarriersAndDoNotReceiveOrdinaryTripleCounts() {
- Query query = query("?s :type :Person . ?s :knows/:knows ?friend . ?s :name \"name42\"");
+ QueryPlan query = query("?s :type :Person . ?s :knows/:knows ?friend . ?s :name \"name42\"");
QueryOperations operations = mock(QueryOperations.class, delegatesTo(storage.queries()));
StorageManager observed = mock(StorageManager.class);
when(observed.queries()).thenReturn(operations);
@@ -245,7 +245,7 @@ void estimatesHonorDefaultNamedAndExplicitEmptyDatasets() {
storage.mutations().add(Values.factory().createStatement(iri("s42"), iri("name"),
Values.factory().createLiteral("name42"), iri("g")));
StorageManagerProducer producer = new StorageManagerProducer(storage);
- Query query = query("?s :name \"name42\"");
+ QueryPlan query = query("?s :name \"name42\"");
Edge edge = edges(query.getBody()).getFirst();
assertEquals(1, producer.estimateCardinality(query, null, edge));
@@ -262,12 +262,12 @@ void estimatesHonorDefaultNamedAndExplicitEmptyDatasets() {
@Test
void graphScopeIsRestoredBeforePlanningDefaultGraphPatterns() {
- Query query = query("GRAPH :g { ?s :type :Person . ?s :name \"name42\" } "
+ QueryPlan query = query("GRAPH :g { ?s :type :Person . ?s :name \"name42\" } "
+ "?x :type :Person . ?x :name \"name42\"");
List graphs = new ArrayList<>();
StatisticsProducer producer = new StatisticsProducer(Map.of()) {
@Override
- public long estimateCardinality(Query scope, Node graph, Edge edge) {
+ public long estimateCardinality(QueryPlan scope, Node graph, Edge edge) {
graphs.add(graph);
return 1;
}
@@ -280,7 +280,7 @@ public long estimateCardinality(Query scope, Node graph, Edge edge) {
@Test
void statisticsUseTheExistingSessionSnapshot() {
try (var reader = storage.openSession(); var transaction = reader.transactions().beginTransaction()) {
- Query query = query("?s :name \"name42\"");
+ QueryPlan query = query("?s :name \"name42\"");
Edge edge = edges(query.getBody()).getFirst();
StorageManagerProducer producer = new StorageManagerProducer(reader);
assertEquals(1, producer.estimateCardinality(query, null, edge));
@@ -308,7 +308,7 @@ void countFailuresRemainQueryDomainErrorsWithOriginalCause() {
@Test
void selectiveFilterPushdownSeedsComparisonEdgeFirst() {
String sparql = "?x :type :Teaching_Unit . ?e :type :Evaluation . ?e :evaluatesTeachingUnit ?x . ?e :hasMark ?y . FILTER (?y < 3)";
- Query query = query(sparql);
+ QueryPlan query = query(sparql);
query.complete(new StorageManagerProducer(storage));
assertEquals(List.of("urn:bench:hasMark", "urn:bench:type", "urn:bench:evaluatesTeachingUnit", "urn:bench:type"),
predicates(query));
@@ -358,10 +358,10 @@ void scaledCostsRetainAdjacentLongPrecision() {
@Test
void variablePredicateDoesNotBecomeSingleTripleProbe() {
- Query query = query("?s ?p ?o . ?s :scan ?x . ?s :seed ?o");
+ QueryPlan query = query("?s ?p ?o . ?s :scan ?x . ?s :seed ?o");
query.complete(new StatisticsProducer(Map.of("urn:bench:scan", 5000L, "urn:bench:seed", 1L)) {
@Override
- public long estimateCardinality(Query scope, Node graph, Edge edge) {
+ public long estimateCardinality(QueryPlan scope, Node graph, Edge edge) {
return edge.getEdgeVariable() == null ? super.estimateCardinality(scope, graph, edge) : 1000000;
}
});
@@ -373,7 +373,7 @@ public long estimateCardinality(Query scope, Node graph, Edge edge) {
@Test
void enclosingScopeVariablesReduceLookupCost() {
- Query query = query("?x :object ?s . ?s :subject ?y");
+ QueryPlan query = query("?x :object ?s . ?s :subject ?y");
CardinalityPatternOrdering.sort(query, null, query.getBody(), List.of("s"), List.of(),
new StatisticsProducer(Map.of("urn:bench:object", 500L, "urn:bench:subject", 5000L)));
assertEquals(List.of("urn:bench:subject", "urn:bench:object"), predicates(query));
@@ -381,7 +381,7 @@ void enclosingScopeVariablesReduceLookupCost() {
@Test
void zeroCardinalityRemainsCheaperThanFullyBoundProbe() {
- Query query = query("?s :probe ?o . ?s :empty ?o");
+ QueryPlan query = query("?s :probe ?o . ?s :empty ?o");
CardinalityPatternOrdering.sort(query, null, query.getBody(), List.of("s", "o"), List.of(),
new StatisticsProducer(Map.of("urn:bench:probe", 1L, "urn:bench:empty", 0L)));
assertEquals(List.of("urn:bench:empty", "urn:bench:probe"), predicates(query));
@@ -390,12 +390,12 @@ void zeroCardinalityRemainsCheaperThanFullyBoundProbe() {
private static void assertPlan(String body, Map counts, List expected) {
Map qualified = new java.util.HashMap<>();
counts.forEach((key, value) -> qualified.put("urn:bench:" + key, value));
- Query query = query(body);
+ QueryPlan query = query(body);
query.complete(new StatisticsProducer(qualified));
assertEquals(expected.stream().map(name -> "urn:bench:" + name).toList(), predicates(query));
}
- private static Query query(String body) {
+ private static QueryPlan query(String body) {
return new CoreseAstQueryBuilder().toNextQuery((SelectQueryAst) new SparqlParser()
.parse(PREFIX + "SELECT * { " + body + " }"));
}
@@ -404,7 +404,7 @@ private static IRI iri(String local) {
return Values.factory().createIRI("urn:bench:" + local);
}
- private static List predicates(Query query) {
+ private static List predicates(QueryPlan query) {
return edges(query.getBody()).stream().map(edge -> edge.getEdgeLabel()).toList();
}
@@ -434,7 +434,7 @@ void joinOrderingUsesPredicateStatisticsWhenAvailable() {
lowDistinctIri.stringValue(), new PredicateStatistics(lowDistinctIri, 1000, 2, 100),
highDistinctIri.stringValue(), new PredicateStatistics(highDistinctIri, 1000, 500, 100));
- Query query = query("?s :seed 1 . ?s :lowDistinct ?o1 . ?s :highDistinct ?o2");
+ QueryPlan query = query("?s :seed 1 . ?s :lowDistinct ?o1 . ?s :highDistinct ?o2");
query.complete(new StatisticsProducer(counts, pStats));
List plan = predicates(query);
@@ -458,7 +458,7 @@ void joinOrderingUsesPredicateStatisticsWhenObjectIsBound() {
lowDistinctIri.stringValue(), new PredicateStatistics(lowDistinctIri, 1000, 100, 2),
highDistinctIri.stringValue(), new PredicateStatistics(highDistinctIri, 1000, 100, 500));
- Query query = query("?x :seed ?shared . ?s1 :lowDistinctObj ?shared . ?s2 :highDistinctObj ?shared");
+ QueryPlan query = query("?x :seed ?shared . ?s1 :lowDistinctObj ?shared . ?s2 :highDistinctObj ?shared");
query.complete(new StatisticsProducer(counts, pStats));
List plan = predicates(query);
@@ -507,7 +507,7 @@ void joinOrderingWithIndexStatisticsAvoidsIntermediateCartesianExplosion() {
assertEquals(10000, statsHigh.distinctObjects());
// High selectivity (high distinct objects = small match count per bound object) is placed first
- Query plannedQuery = query("?x :seed ?t . ?s1 :lowSel ?t . ?s2 :highSel ?t");
+ QueryPlan plannedQuery = query("?x :seed ?t . ?s1 :lowSel ?t . ?s2 :highSel ?t");
plannedQuery.complete(new StorageManagerProducer(benchStorage));
List optimalPlan = predicates(plannedQuery);
assertEquals(List.of(seed.stringValue(), highSel.stringValue(), lowSel.stringValue()), optimalPlan);
@@ -538,12 +538,12 @@ private StatisticsProducer(Map counts, Map());
when(mockQuery.getOrderBy()).thenReturn(new ArrayList<>());
when(mockQuery.getGroupBy()).thenReturn(new ArrayList<>());
@@ -63,7 +63,7 @@ void testCreateEmptyMappings() {
void testCreateMappingsWithQuery() {
Mappings m = Mappings.create(mockQuery);
assertNotNull(m, "Mappings should not be null");
- assertEquals(mockQuery, m.getQuery(), "Query should match");
+ assertEquals(mockQuery, m.getQuery(), "QueryPlan should match");
}
@Test
@@ -201,22 +201,22 @@ void testEmptyIterator() {
}
@Nested
- @DisplayName("Query Management Tests")
+ @DisplayName("QueryPlan Management Tests")
class QueryManagementTests {
@Test
@DisplayName("Should get query")
void testGetQuery() {
- Query result = mappings.getQuery();
+ QueryPlan result = mappings.getQuery();
assertEquals(mockQuery, result, "Should return query");
}
@Test
@DisplayName("Should set query")
void testSetQuery() {
- Query newQuery = mock(Query.class);
+ QueryPlan newQuery = mock(QueryPlan.class);
mappings.setQuery(newQuery);
- assertEquals(newQuery, mappings.getQuery(), "Query should be updated");
+ assertEquals(newQuery, mappings.getQuery(), "QueryPlan should be updated");
}
}
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java
index 738f678b3..8de1574bf 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/solution/MemoryTest.java
@@ -2,7 +2,7 @@
import fr.inria.corese.core.next.query.impl.engine.eval.Eval;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.model.BindingContext;
import fr.inria.corese.core.next.query.impl.engine.model.ExpType;
@@ -34,7 +34,7 @@ class MemoryTest {
private Matcher mockMatcher;
private Evaluator mockEvaluator;
private Node mockNode;
- private Query mockQuery;
+ private QueryPlan mockQuery;
private Eval mockEval;
@BeforeEach
@@ -42,7 +42,7 @@ void setUp() {
mockMatcher = mock(Matcher.class);
mockEvaluator = mock(Evaluator.class);
mockNode = mock(Node.class);
- mockQuery = mock(Query.class);
+ mockQuery = mock(QueryPlan.class);
mockEval = mock(Eval.class);
memory = new Memory(mockMatcher, mockEvaluator);
@@ -115,7 +115,7 @@ void testGetVisitor() {
}
@Nested
- @DisplayName("Query Management Tests")
+ @DisplayName("QueryPlan Management Tests")
class QueryManagementTests {
@Test
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/ContextSelectionTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/ContextSelectionTest.java
index bb8cc95e0..89bba8592 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/ContextSelectionTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/ContextSelectionTest.java
@@ -1,6 +1,6 @@
package fr.inria.corese.core.next.query.impl.engine.storage;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.spi.Environment;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -24,7 +24,7 @@ class ContextSelectionTest {
private static Environment envWith(boolean datasetSpecified) {
Environment env = mock(Environment.class);
- Query query = mock(Query.class);
+ QueryPlan query = mock(QueryPlan.class);
when(env.getQuery()).thenReturn(query);
when(query.isDatasetSpecified()).thenReturn(datasetSpecified);
return env;
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java
index 234723f21..560301399 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/storage/StorageManagerProducerTest.java
@@ -19,7 +19,7 @@
import fr.inria.corese.core.next.query.impl.engine.eval.Eval;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
import fr.inria.corese.core.next.query.impl.engine.solution.Mappings;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.eval.RdfTermMatcher;
import fr.inria.corese.core.next.query.impl.engine.eval.SparqlKgramEvaluator;
import fr.inria.corese.core.next.storage.impl.memory.MemoryStorageManager;
@@ -202,7 +202,7 @@ void evalExecutesSelectStarSpoOverStorageManagerProducer() throws Exception {
Node s = variable("s");
Node p = variable("p");
Node o = variable("o");
- Query query = selectStarSpoQuery(s, p, o);
+ QueryPlan query = selectStarSpoQuery(s, p, o);
Eval eval = Eval.create(producer, new SparqlKgramEvaluator(), new RdfTermMatcher());
Mappings mappings = eval.query(query);
@@ -216,7 +216,7 @@ void evalExecutesSelectStarSpoOverStorageManagerProducer() throws Exception {
void parserBridgeExecutesSelectStarSpoOverStorageManagerProducer() throws Exception {
QueryAst ast = new SparqlParser().parse("SELECT * WHERE { ?s ?p ?o }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = new CoreseAstQueryBuilder().toNextQuery(select);
+ QueryPlan query = new CoreseAstQueryBuilder().toNextQuery(select);
Eval eval = Eval.create(producer, new SparqlKgramEvaluator(), new RdfTermMatcher());
Mappings mappings = eval.query(query);
@@ -231,7 +231,7 @@ void producerMaterializesBgpMappings() {
Node s = variable("s");
Node p = variable("p");
Node o = variable("o");
- Query query = selectStarSpoQuery(s, p, o);
+ QueryPlan query = selectStarSpoQuery(s, p, o);
Environment environment = mock(Environment.class);
when(environment.getQuery()).thenReturn(query);
@@ -251,7 +251,7 @@ void producerJoinsBgpMappingsAcrossRepeatedVariables() {
Node s = variable("s");
Node o = variable("o");
Node name = variable("name");
- Query query = selectKnowsNameQuery(s, o, name);
+ QueryPlan query = selectKnowsNameQuery(s, o, name);
Environment environment = mock(Environment.class);
when(environment.getQuery()).thenReturn(query);
@@ -314,23 +314,23 @@ private static Node literal(String label) {
return NodeImpl.forLiteral(label, null, null);
}
- private static Query selectStarSpoQuery(Node s, Node p, Node o) {
+ private static QueryPlan selectStarSpoQuery(Node s, Node p, Node o) {
Exp bgp = Exp.create(Type.BGP);
bgp.add(Exp.create(Type.EDGE, new TestQueryEdge(s, KgramNodes.rootProperty(), p, o)));
return selectQuery(bgp);
}
- private static Query selectKnowsNameQuery(Node s, Node o, Node name) {
+ private static QueryPlan selectKnowsNameQuery(Node s, Node o, Node name) {
Exp bgp = Exp.create(Type.BGP);
bgp.add(Exp.create(Type.EDGE, new TestQueryEdge(s, resource(KNOWS), null, o)));
bgp.add(Exp.create(Type.EDGE, new TestQueryEdge(o, resource(NAME), null, name)));
return selectQuery(bgp);
}
- private static Query selectQuery(Exp bgp) {
+ private static QueryPlan selectQuery(Exp bgp) {
Exp body = Exp.create(Type.AND);
body.add(bgp);
- Query query = Query.create(body);
+ QueryPlan query = QueryPlan.create(body);
query.collect();
List select = query.selectNodesFromPattern();
query.setSelect(select);
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java
index d4b4ab696..91fa1e3ec 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderAskTest.java
@@ -20,7 +20,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.ExprType;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -46,11 +46,11 @@ private static GroupGraphPatternAst whereOneTriple() {
}
@Test
- @DisplayName("Query body is the compiled WHERE and the query is flagged as ASK")
+ @DisplayName("QueryPlan body is the compiled WHERE and the query is flagged as ASK")
void buildsBodyAndAskFlag() {
AskQueryAst ask = new AskQueryAst(DatasetClauseAst.none(), whereOneTriple());
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertNotNull(query.getBody(), "body set from WHERE");
assertTrue(query.getBody().isAnd(), "group compiles to AND");
@@ -60,12 +60,12 @@ void buildsBodyAndAskFlag() {
}
@Test
- @DisplayName("Parser -> AskQueryAst -> Query keeps the ASK form")
+ @DisplayName("Parser -> AskQueryAst -> QueryPlan keeps the ASK form")
void buildsQueryFromParsedAsk() {
SparqlParser parser = newParserDefault();
AskQueryAst ask = assertInstanceOf(AskQueryAst.class, parser.parse("ASK WHERE { ?s ?p ?o . }"));
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.isAsk());
assertFalse(query.isSelect());
@@ -83,33 +83,33 @@ void buildsAskWithFilter() {
filter));
AskQueryAst ask = new AskQueryAst(DatasetClauseAst.none(), where);
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.isAsk());
assertTrue(query.getBody().get(1).isFilter(), "FILTER compiled into the body");
}
@Test
- @DisplayName("FROM graphs are copied onto the next Query dataset")
+ @DisplayName("FROM graphs are copied onto the next QueryPlan dataset")
void appliesFromClause() {
DatasetClauseAst dataset = new DatasetClauseAst(
Set.of(new IriAst("http://example.org/g")), Set.of());
AskQueryAst ask = new AskQueryAst(dataset, whereOneTriple());
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertEquals(List.of("http://example.org/g"), labels(query.getFrom()));
assertTrue(query.getNamed().isEmpty());
}
@Test
- @DisplayName("FROM NAMED graphs are copied onto the next Query dataset")
+ @DisplayName("FROM NAMED graphs are copied onto the next QueryPlan dataset")
void appliesFromNamedClause() {
DatasetClauseAst dataset = new DatasetClauseAst(
Set.of(), Set.of(new IriAst("http://example.org/g")));
AskQueryAst ask = new AskQueryAst(dataset, whereOneTriple());
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.getFrom().isEmpty());
assertEquals(List.of("http://example.org/g"), labels(query.getNamed()));
@@ -123,7 +123,7 @@ void compilesValuesClause() {
AskQueryAst ask = new AskQueryAst(
DatasetClauseAst.none(), whereOneTriple(), null, null, values);
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.getBody().isJoin());
assertTrue(query.getBody().rest().isValues());
}
@@ -140,7 +140,7 @@ void buildsAskWithEmptyWhere() {
AskQueryAst ask = new AskQueryAst(DatasetClauseAst.none(),
new GroupGraphPatternAst(List.of()));
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertNotNull(query.getBody());
assertTrue(query.getBody().isAnd());
@@ -154,7 +154,7 @@ void appliesLimitAndOffset() {
SolutionModifierAst mod = SolutionModifierAst.withoutGroupBy(false, false, List.of(), 10L, 3L);
AskQueryAst ask = new AskQueryAst(DatasetClauseAst.none(), whereOneTriple(), mod, null, null);
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertEquals(10, query.getLimit());
assertEquals(3, query.getOffset());
@@ -166,7 +166,7 @@ void appliesOrderBy() {
AskQueryAst ask = assertInstanceOf(AskQueryAst.class,
newParserDefault().parse("ASK WHERE { ?s ?p ?o . } ORDER BY ?s"));
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertEquals(1, query.getOrderBy().size());
assertEquals("s", query.getOrderBy().getFirst().getNode().getLabel());
@@ -184,7 +184,7 @@ void filterExistsInAskWhere() {
filter));
AskQueryAst ask = new AskQueryAst(DatasetClauseAst.none(), where);
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.isAsk());
Exp filterExp = findFilter(query.getBody());
@@ -199,7 +199,7 @@ void parsedAskWithFilterNotExists() {
AskQueryAst ask = assertInstanceOf(AskQueryAst.class,
newParserDefault().parse("ASK WHERE { ?s ?p ?o . FILTER NOT EXISTS { ?s ?t } }"));
- Query query = builder.toNextQuery(ask);
+ QueryPlan query = builder.toNextQuery(ask);
assertTrue(query.isAsk());
Exp filterExp = findFilter(query.getBody());
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java
index 3c8ac0d53..1c5392e1e 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderConstructTest.java
@@ -10,7 +10,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.Expr;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -44,7 +44,7 @@ private static ConstructTemplateAst template(TriplePatternAst... triples) {
void templateCompiledAsBgp() {
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))), whereSPO());
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertFalse(query.getConstructNodes().isEmpty(), "construct nodes populated");
assertTrue(query.isConstruct(), "query flagged as CONSTRUCT");
assertFalse(query.isSelect(), "CONSTRUCT should not also report itself as SELECT");
@@ -56,12 +56,12 @@ void templateCompiledAsBgp() {
}
@Test
- @DisplayName("Parser -> ConstructQueryAst -> Query keeps the CONSTRUCT form")
+ @DisplayName("Parser -> ConstructQueryAst -> QueryPlan keeps the CONSTRUCT form")
void buildsQueryFromParsedConstruct() {
SparqlParser parser = newParserDefault();
ConstructQueryAst construct = assertInstanceOf(ConstructQueryAst.class, parser.parse("CONSTRUCT { ?x ?p ?o } WHERE { ?x ?p ?o }"));
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.isConstruct());
assertFalse(query.isSelect());
@@ -75,7 +75,7 @@ void buildsQueryFromParsedConstruct() {
void templateWithTwoTriples() {
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new IriAst("http://example.org/p"), new VarAst("o")), new TriplePatternAst(new VarAst("x"), new IriAst("http://example.org/q"), new VarAst("o"))), whereSPO());
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertEquals(2, query.getConstruct().size());
}
@@ -85,7 +85,7 @@ void templateWithTwoTriples() {
void templateVariableResolvesToBodyNode() {
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))), whereSPO());
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
Edge edge = query.getConstruct().first().getEdge();
assertSame(query.getExtNode("x"), edge.getNode(0), "template ?x is the body node");
@@ -97,7 +97,7 @@ void templateVariableResolvesToBodyNode() {
void templateOnlyVariableStaysFresh() {
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("newVar"))), whereSPO());
- Query query = assertDoesNotThrow(() -> builder.toNextQuery(construct));
+ QueryPlan query = assertDoesNotThrow(() -> builder.toNextQuery(construct));
assertNull(query.getExtNode("newVar"), "template-only variable is not injected into the body");
Node object = query.getConstruct().first().getEdge().getNode(1);
@@ -111,7 +111,7 @@ void templateMinusOnlyVariableStaysFresh() {
template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("z"))),
whereWithMinusOnlyZ());
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
Node minusNode = query.getQueryNode("z");
Node templateNode = query.getConstruct().first().getEdge().getNode(1);
@@ -125,7 +125,7 @@ void templateMinusOnlyVariableStaysFresh() {
void templateWithFixedResources() {
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new IriAst("http://example.org/s"), new IriAst("http://example.org/p"), new VarAst("o"))), whereSPO());
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
Edge edge = query.getConstruct().first().getEdge();
assertFalse(edge.getNode(0).isVariable(), "fixed subject IRI");
@@ -140,7 +140,7 @@ void appliesDatasetLimitOffset() {
SolutionModifierAst mod = SolutionModifierAst.withoutGroupBy(false, false, List.of(), 5L, 2L);
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))), dataset, whereSPO(), mod);
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertEquals(List.of("http://example.org/g"), query.getFrom().stream().map(Node::getLabel).toList(), "FROM applied");
assertEquals(List.of("http://example.org/n"), query.getNamed().stream().map(Node::getLabel).toList(), "FROM NAMED applied");
@@ -154,7 +154,7 @@ void appliesOrderBy() {
SolutionModifierAst mod = SolutionModifierAst.withoutGroupBy(false, false, List.of(new OrderConditionAst(ASTConstants.OrderDirection.ASC, new VarAst("x"))), null, null);
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))), DatasetClauseAst.none(), whereSPO(), mod);
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertFalse(query.getOrderBy().isEmpty(), "ORDER BY applied");
}
@@ -165,7 +165,7 @@ void compilesValuesClause() {
ValuesAst values = new ValuesAst(List.of(new ValueMappingAst(Map.of(new VarAst("x"), new IriAst("http://example.org/v")))));
ConstructQueryAst construct = new ConstructQueryAst(template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))), DatasetClauseAst.none(), whereSPO(), null, null, values);
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.getBody().isJoin());
assertTrue(query.getBody().rest().isValues());
}
@@ -190,7 +190,7 @@ void filterExistsInConstructWhere() {
template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))),
where);
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.isConstruct(), "query is CONSTRUCT");
Exp filterExp = findFilter(query.getBody());
@@ -213,7 +213,7 @@ void filterNotExistsInConstructWhere() {
template(new TriplePatternAst(new VarAst("x"), new VarAst("p"), new VarAst("o"))),
where);
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.isConstruct(), "query is CONSTRUCT");
Exp filterExp = findFilter(query.getBody());
@@ -232,7 +232,7 @@ void parsedConstructWithFilterExists() {
ConstructQueryAst construct = assertInstanceOf(ConstructQueryAst.class,
parser.parse("CONSTRUCT { ?x ?p ?o } WHERE { ?x ?p ?o . FILTER EXISTS { ?x ?t } }"));
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.isConstruct());
Exp filterExp = findFilter(query.getBody());
@@ -247,7 +247,7 @@ void parsedConstructWithFilterNotExists() {
ConstructQueryAst construct = assertInstanceOf(ConstructQueryAst.class,
parser.parse("CONSTRUCT { ?x ?p ?o } WHERE { ?x ?p ?o . FILTER NOT EXISTS { ?x ?t } }"));
- Query query = builder.toNextQuery(construct);
+ QueryPlan query = builder.toNextQuery(construct);
assertTrue(query.isConstruct());
Exp filterExp = findFilter(query.getBody());
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java
index 641f5f772..28be0408b 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderDescribeTest.java
@@ -9,7 +9,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.ExprType;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -39,13 +39,13 @@ private static GroupGraphPatternAst whereWithMinusOnlyZ() {
}
@Test
- @DisplayName("Parser -> DescribeQueryAst -> Query lowers DESCRIBE to a construct-like query")
+ @DisplayName("Parser -> DescribeQueryAst -> QueryPlan lowers DESCRIBE to a construct-like query")
void parserDescribeAstToQuery() {
SparqlParser parser = new SparqlParser();
DescribeQueryAst describe = (DescribeQueryAst) parser.parse(
"DESCRIBE ?x WHERE { ?x ?p ?o }");
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 1);
assertTrue(query.getBody().isAnd());
@@ -59,7 +59,7 @@ void describesVariableResolvedAgainstBody() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), whereBindingX());
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 1);
assertTrue(query.getBody().isAnd(), "WHERE compiled into the body");
@@ -75,7 +75,7 @@ void describesFixedResourceWithoutWhere() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new IriAst("")), null);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 1);
assertTrue(query.getBody().isAnd(), "body remains an AND");
@@ -89,7 +89,7 @@ void describeAllUsesInScopeVariables() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(), whereBindingX());
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 3);
assertEquals(3, describeOptionalCount(query));
@@ -129,7 +129,7 @@ void appliesDatasetClause() {
DescribeQueryAst describe = new DescribeQueryAst(
dataset, List.of(new VarAst("x")), whereBindingX());
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertEquals(1, query.getFrom().size(), "FROM applied");
assertEquals(1, query.getNamed().size(), "FROM NAMED applied");
@@ -143,7 +143,7 @@ void appliesLimitAndOffset() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), whereBindingX(), mod);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertEquals(5, query.getLimit(), "LIMIT applied");
assertEquals(2, query.getOffset(), "OFFSET applied");
@@ -159,7 +159,7 @@ void appliesOrderBy() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), whereBindingX(), mod);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertFalse(query.getOrderBy().isEmpty(), "ORDER BY applied");
}
@@ -176,7 +176,7 @@ void filterExistsInDescribeWhere() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), where);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 1);
Exp filterExp = findFilter(query.getBody());
@@ -198,7 +198,7 @@ void filterNotExistsInDescribeWhere() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), where);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertLoweredDescribeConstruct(query, 1);
Exp filterExp = findFilter(query.getBody());
@@ -227,7 +227,7 @@ void compilesValuesClause() {
DescribeQueryAst describe = new DescribeQueryAst(
DatasetClauseAst.none(), List.of(new VarAst("x")), whereBindingX(), null, null, values);
- Query query = builder.toNextQuery(describe);
+ QueryPlan query = builder.toNextQuery(describe);
assertTrue(query.getBody().isJoin());
assertTrue(query.getBody().rest().isValues());
}
@@ -249,7 +249,7 @@ void rejectsNull() {
assertThrows(NullPointerException.class, () -> builder.toNextQuery((DescribeQueryAst) null));
}
- private static void assertLoweredDescribeConstruct(Query query, int describedNodeCount) {
+ private static void assertLoweredDescribeConstruct(QueryPlan query, int describedNodeCount) {
assertTrue(query.isConstruct(), "DESCRIBE is lowered to the construct runtime path");
assertFalse(query.isSelect(), "a lowered DESCRIBE must not report itself as SELECT");
assertNotNull(query.getConstruct(), "construct template created");
@@ -262,7 +262,7 @@ private static void assertLoweredDescribeConstruct(Query query, int describedNod
* Counts the DESCRIBE-generated {@code OPTIONAL { outgoing UNION incoming }} patterns directly
* under the body — independently of how the parser shaped the original WHERE.
*/
- private static long describeOptionalCount(Query query) {
+ private static long describeOptionalCount(QueryPlan query) {
Exp body = query.getBody();
long count = 0;
for (int i = 0; i < body.size(); i++) {
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java
index ab2b14e94..37b0f9143 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderMinusScopeTest.java
@@ -3,7 +3,7 @@
import fr.inria.corese.core.next.query.impl.sparql.ast.*;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -32,7 +32,7 @@ void minusRightSideVariablesStayOutOfOuterScope() {
bgp("s", "p", "o"),
new MinusAst(new GroupGraphPatternAst(List.of(bgp("s", "q", "z")))))));
- Query query = Query.create(body);
+ QueryPlan query = QueryPlan.create(body);
query.collect();
// WHERE pattern variables are in scope (pattern nodes)
@@ -55,7 +55,7 @@ void optionalVariablesAreInOuterScope() {
bgp("s", "p", "o"),
new OptionalAst(new GroupGraphPatternAst(List.of(bgp("s", "q", "z")))))));
- Query query = Query.create(body);
+ QueryPlan query = QueryPlan.create(body);
query.collect();
assertTrue(hasLabel(query.getPatternNodes(), "s"), "?s from WHERE is a pattern node");
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java
index f9697c309..0362e52ea 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilderTest.java
@@ -22,7 +22,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.ExprType;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.api.exception.QuerySyntaxException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -47,7 +47,7 @@ class CoreseAstQueryBuilderTest extends AbstractSparqlParserFeatureTest {
void buildsMinimalSelectStarQuery() {
SelectQueryAst select = new SelectQueryAst(group(singleTriple()));
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertTrue(query.getBody().isAnd(), "the query body should be an AND group");
assertEquals(1, query.getBody().size(), "the WHERE should contain one compiled element");
@@ -59,12 +59,12 @@ void buildsMinimalSelectStarQuery() {
}
@Test
- @DisplayName("Parser -> SelectQueryAst -> Query keeps the SELECT * path executable")
+ @DisplayName("Parser -> SelectQueryAst -> QueryPlan keeps the SELECT * path executable")
void buildsQueryFromParsedSelectStar() {
QueryAst ast = newParserDefault().parse("SELECT * WHERE { ?s ?p ?o . }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(List.of("s", "p", "o"), labels(query.getSelect()));
assertTrue(query.getBody().get(0).isBGP());
@@ -78,7 +78,7 @@ void expandsPrefixesInQuery() {
"PREFIX ex: " +
"SELECT * WHERE { ?s :p ex:o . }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp bgp = query.getBody().get(0);
Edge edge = bgp.get(0).getEdge();
@@ -112,7 +112,7 @@ void preservesAngleBracketedIrisWithoutPrefixExpansion() {
"PREFIX rdf: " +
"SELECT * WHERE { ?s ?o . }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp bgp = query.getBody().get(0);
Edge edge = bgp.get(0).getEdge();
@@ -136,7 +136,7 @@ void preservesNormalizedDatatypesWithConflictingPrefix() {
"PREFIX http: " +
"SELECT * WHERE { ?s ?p true . }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp bgp = query.getBody().get(0);
Edge edge = bgp.get(0).getEdge();
@@ -152,7 +152,7 @@ void expandsUrnAndFilePrefixes() {
"PREFIX file: " +
"SELECT * WHERE { ?s urn:p \"val\"^^file:type . }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp bgp = query.getBody().get(0);
Edge edge = bgp.get(0).getEdge();
@@ -168,7 +168,7 @@ void buildsExplicitProjection() {
null,
group(singleTriple()));
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(List.of("o", "s"), labels(query.getSelect()));
}
@@ -178,7 +178,7 @@ void buildsExplicitProjection() {
void selectStarExcludesMinusOnlyVariables() {
SelectQueryAst select = parseSelect("SELECT * WHERE { ?s ?p ?o . MINUS { ?s ?q ?z } }");
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(List.of("s", "p", "o"), labels(query.getSelect()),
"MINUS-only variables are stored separately and must not be visible to SELECT *");
@@ -204,7 +204,7 @@ void explicitProjectionRejectsMinusOnlyVariable() {
void selectStarIncludesOptionalVariables() {
SelectQueryAst select = parseSelect("SELECT * WHERE { ?s ?p ?o . OPTIONAL { ?s ?q ?z } }");
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(List.of("s", "p", "o", "q", "z"), labels(query.getSelect()),
"OPTIONAL variables remain visible in the outer query scope");
@@ -219,7 +219,7 @@ void appliesSimpleSolutionModifiers() {
group(singleTriple()),
SolutionModifierAst.withoutGroupBy(true, false, List.of(), 10L, 3L));
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertTrue(query.isDistinct());
assertEquals(10, query.getLimit());
@@ -238,7 +238,7 @@ void appliesVariableOrderBy() {
null,
null));
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(1, query.getOrderBy().size());
assertEquals("s", query.getOrderBy().getFirst().getNode().getLabel());
@@ -251,7 +251,7 @@ void appliesDescendingOrderBy() {
QueryAst ast = newParserDefault().parse("SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(1, query.getOrderBy().size());
assertEquals("o", query.getOrderBy().getFirst().getNode().getLabel());
@@ -264,7 +264,7 @@ void appliesExpressionOrderBy() {
QueryAst ast = newParserDefault().parse("SELECT * WHERE { ?s ?p ?o . } ORDER BY STR(?o)");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(1, query.getOrderBy().size());
assertNotNull(query.getOrderBy().getFirst().getFilter(),
@@ -294,14 +294,14 @@ void orderByRejectsMinusOnlyVariable() {
void orderByAcceptsOptionalVariable() {
SelectQueryAst select = parseSelect("SELECT * WHERE { ?s ?p ?o . OPTIONAL { ?s ?q ?z } } ORDER BY ?z");
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(1, query.getOrderBy().size());
assertEquals("z", query.getOrderBy().getFirst().getNode().getLabel());
}
@Test
- @DisplayName("FROM and FROM NAMED are copied onto the next Query dataset")
+ @DisplayName("FROM and FROM NAMED are copied onto the next QueryPlan dataset")
void appliesDatasetClauses() {
DatasetClauseAst dataset = new DatasetClauseAst(
Set.of(new IriAst("http://example.org/default")),
@@ -311,7 +311,7 @@ void appliesDatasetClauses() {
dataset,
group(singleTriple()));
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
assertEquals(List.of("http://example.org/default"), labels(query.getFrom()));
assertEquals(List.of("http://example.org/named"), labels(query.getNamed()));
@@ -360,7 +360,7 @@ void rejectsUnknownOrderByVariable() {
void filterExistsInSelectWhere() {
SelectQueryAst select = getSelectQueryAst();
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp filterExp = findFilter(query.getBody());
assertNotNull(filterExp, "FILTER is in the compiled body");
@@ -385,7 +385,7 @@ void parsedSelectWithFilterNotExists() {
"SELECT * WHERE { ?s ?p ?o . FILTER NOT EXISTS { ?s ?t } }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp filterExp = findFilter(query.getBody());
assertNotNull(filterExp, "FILTER NOT EXISTS compiled into body");
@@ -402,7 +402,7 @@ void parsedSelectWithNegatedExists() {
"SELECT * WHERE { ?s ?p ?o . FILTER(!EXISTS { ?s ?t }) }");
SelectQueryAst select = assertInstanceOf(SelectQueryAst.class, ast);
- Query query = builder.toNextQuery(select);
+ QueryPlan query = builder.toNextQuery(select);
Exp filterExp = findFilter(query.getBody());
assertNotNull(filterExp, "FILTER !EXISTS compiled into body");
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/DirectGroupAggregationTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/DirectGroupAggregationTest.java
index bbec4d74c..3e7628cb1 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/DirectGroupAggregationTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/DirectGroupAggregationTest.java
@@ -6,7 +6,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.model.ExpType.Type;
import fr.inria.corese.core.next.query.impl.engine.solution.Mapping;
import fr.inria.corese.core.next.query.impl.engine.solution.Mappings;
@@ -30,7 +30,7 @@ class DirectGroupAggregationTest {
@Test
void aggregatesAllScalarsOnFirstRepresentative() {
- Query query = query();
+ QueryPlan query = query();
Mappings mappings = Mappings.create(query);
Mapping first = row("a", integer(10));
mappings.add(first);
@@ -53,7 +53,7 @@ void aggregatesAllScalarsOnFirstRepresentative() {
@Test
void allUnboundValuesAndUnboundGroupKey() {
- Query query = query();
+ QueryPlan query = query();
Mappings mappings = Mappings.create(query);
Mapping first = row(null, null);
mappings.add(first);
@@ -70,7 +70,7 @@ void allUnboundValuesAndUnboundGroupKey() {
@Test
void numericErrorDoesNotAffectOtherAggregates() {
- Query query = query();
+ QueryPlan query = query();
Mappings mappings = Mappings.create(query);
Mapping first = row("a", integer(10));
mappings.add(first);
@@ -84,7 +84,7 @@ void numericErrorDoesNotAffectOtherAggregates() {
@Test
void promotesMixedNumericTypesAndPreservesLargeIntegers() {
- Query query = query();
+ QueryPlan query = query();
Mappings mappings = Mappings.create(query);
Mapping first = row("a", integer(1));
mappings.add(first);
@@ -104,7 +104,7 @@ void promotesMixedNumericTypesAndPreservesLargeIntegers() {
@Test
void emptyGroupedInputProducesNoRepresentative() {
- Query query = query();
+ QueryPlan query = query();
Mappings mappings = Mappings.create(query);
assertTrue(DirectGroupAggregation.tryAggregate(query, mappings));
assertEquals(0, mappings.size());
@@ -112,7 +112,7 @@ void emptyGroupedInputProducesNoRepresentative() {
@Test
void usesAllGroupKeysAndPreparedGroupValues() {
- Query query = query();
+ QueryPlan query = query();
Node secondKey = NodeImpl.forVariable("?second");
query.addGroupBy(secondKey);
Mappings mappings = Mappings.create(query);
@@ -134,7 +134,7 @@ void usesAllGroupKeysAndPreparedGroupValues() {
@Test
void rejectsDistinctWithoutChangingInput() {
- Query query = query();
+ QueryPlan query = query();
query.getSelectFun().add(projection("?distinct", AggregateFunction.COUNT, true, new VarAst("?v")));
Mappings mappings = Mappings.create(query);
Mapping first = row("a", integer(1));
@@ -147,7 +147,7 @@ void rejectsDistinctWithoutChangingInput() {
@Test
void rejectsUnsupportedModifiersAndAggregateArguments() {
- Query query = query();
+ QueryPlan query = query();
query.addOrderBy(GROUP);
assertFalse(DirectGroupAggregation.isEligible(query));
query = query();
@@ -161,8 +161,8 @@ void rejectsUnsupportedModifiersAndAggregateArguments() {
assertFalse(DirectGroupAggregation.isEligible(query));
}
- private static Query query() {
- Query query = Query.create();
+ private static QueryPlan query() {
+ QueryPlan query = QueryPlan.create();
query.addGroupBy(GROUP);
query.addSelect(GROUP);
query.getSelectFun().add(projection("?all", AggregateFunction.COUNT, false, null));
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java
index a319e4c74..36534ad07 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompilerExistsTest.java
@@ -8,7 +8,7 @@
import fr.inria.corese.core.next.query.impl.engine.model.Expr;
import fr.inria.corese.core.next.query.impl.engine.model.ExprType;
import fr.inria.corese.core.next.query.impl.engine.pattern.Exp;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -104,7 +104,7 @@ void existsVariablesAreCollectedInExistsScope() {
FilterAst filter = new FilterAst(new ExistsAst(group(bgp("s", "q", "z"))));
Exp body = compiler.compile(group(bgp("s", "p", "o"), filter));
- Query query = Query.create(body);
+ QueryPlan query = QueryPlan.create(body);
query.collect();
assertTrue(query.getPatternNodes().stream().anyMatch(n -> "o".equals(n.getLabel())));
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelectorTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelectorTest.java
index 15867d6a3..c78b202b9 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelectorTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/sparql/execution/TopKSelectorTest.java
@@ -5,7 +5,7 @@
import fr.inria.corese.core.next.query.impl.engine.event.ProcessVisitor;
import fr.inria.corese.core.next.query.impl.engine.model.Node;
import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.solution.Mapping;
import org.junit.jupiter.api.Test;
@@ -20,7 +20,7 @@
class TopKSelectorTest {
@Test
void theHeapNeverRetainsMoreThanLimitPlusOffsetAndReleasesDiscardedSlots() throws ReflectiveOperationException {
- Query query = Query.create();
+ QueryPlan query = QueryPlan.create();
query.setLimit(5);
query.setOffset(2);
query.addOrderBy(NodeImpl.forVariable("key"));
@@ -42,7 +42,7 @@ void theHeapNeverRetainsMoreThanLimitPlusOffsetAndReleasesDiscardedSlots() throw
@Test
void officialComparatorVisitorOverridesAreUsedForSelectionAndFinalOrdering() {
- Query query = Query.create();
+ QueryPlan query = QueryPlan.create();
query.setLimit(2);
query.addOrderBy(NodeImpl.forVariable("key"));
Eval eval = mock(Eval.class);
diff --git a/src/test/java/fr/inria/corese/core/next/storage/impl/memory/ProducerDeduplicationTest.java b/src/test/java/fr/inria/corese/core/next/storage/impl/memory/ProducerDeduplicationTest.java
index 80fd98833..0f08dcde5 100644
--- a/src/test/java/fr/inria/corese/core/next/storage/impl/memory/ProducerDeduplicationTest.java
+++ b/src/test/java/fr/inria/corese/core/next/storage/impl/memory/ProducerDeduplicationTest.java
@@ -6,7 +6,7 @@
import fr.inria.corese.core.next.data.api.term.SimpleIRI;
import fr.inria.corese.core.next.query.impl.engine.model.Edge;
import fr.inria.corese.core.next.query.impl.engine.model.NodeImpl;
-import fr.inria.corese.core.next.query.impl.engine.pattern.Query;
+import fr.inria.corese.core.next.query.impl.engine.pattern.QueryPlan;
import fr.inria.corese.core.next.query.impl.engine.spi.Environment;
import fr.inria.corese.core.next.query.impl.engine.storage.StorageManagerEdge;
import fr.inria.corese.core.next.query.impl.engine.storage.StorageManagerProducer;
@@ -38,11 +38,11 @@ class ProducerDeduplicationTest {
private static Statement row(int i, Resource graph) {
return Values.factory().createStatement(new SimpleIRI("urn:s" + i), new SimpleIRI("urn:p"), new SimpleIRI("urn:o"), graph);
}
- private static Query query(String dataset) {
+ private static QueryPlan query(String dataset) {
return new CoreseAstQueryBuilder().toNextQuery((SelectQueryAst) new SparqlParser()
.parse("SELECT * " + dataset + " WHERE { ?s ?p ?o }"));
}
- private static Iterable edges(StorageManagerProducer producer, Query query) {
+ private static Iterable edges(StorageManagerProducer producer, QueryPlan query) {
Environment env = mock(Environment.class); when(env.getQuery()).thenReturn(query);
return producer.getEdges(null, query.getFrom(), query.getBody().first().first().getEdge(), env);
}
From 710580896088b5dc4dc3503436e1bbaf03020d90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20C=C3=A9r=C3=A8s?=
Date: Mon, 26 Oct 2026 15:36:30 +0100
Subject: [PATCH 2/2] refactor(engine): address review feedback on Javadoc
links, layout isolation, and delegation (#643)
---
.../impl/engine/filter/FilterOptimizer.java | 2 +-
.../engine/pattern/CompiledQueryPlan.java | 2 +-
.../query/impl/engine/pattern/QueryPlan.java | 26 +++----------------
.../impl/engine/pattern/VariableLayout.java | 22 +++++++++-------
.../sparql/bridge/ConstructQueryCompiler.java | 4 +--
.../sparql/bridge/CoreseAstQueryBuilder.java | 12 ++++-----
.../bridge/SolutionModifierCompiler.java | 2 +-
.../impl/sparql/bridge/WhereCompiler.java | 2 +-
.../sparql/execution/SparqlQueryExecutor.java | 2 +-
.../engine/pattern/VariableLayoutTest.java | 3 +--
10 files changed, 29 insertions(+), 48 deletions(-)
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterOptimizer.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterOptimizer.java
index a554b885b..092ca79cc 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterOptimizer.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/filter/FilterOptimizer.java
@@ -16,7 +16,7 @@
* Filter Exp Compiler for Optimizations
* If Filter leads to optimization, we tag the Filter Exp
* with e.g. a BIND(?x = ?y)
- * Query.bind() will handle later this tag BIND
+ * QueryPlan.bind() will handle later this tag BIND
* (1)
* x p t . y p z . filter(y = x)
* ->
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlan.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlan.java
index 24ed380a9..cea74eb43 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlan.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/CompiledQueryPlan.java
@@ -7,7 +7,7 @@
/**
* Immutable compilation image, enforced by exclusive ownership rather than by
- * reusing an executable Query. Capture detaches every mutable component from
+ * reusing an executable QueryPlan. Capture detaches every mutable component from
* the compiler. The private image is never evaluated or exposed; each execution
* receives another independent graph. Only immutable syntax, RDF values and
* private read-only prologue lookups are shared. No producer, storage cursor,
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlan.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlan.java
index c635eb841..43c6027d1 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlan.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/QueryPlan.java
@@ -153,8 +153,7 @@ private QueryPlan(QueryPlan source, PlanCopy copies) {
super(Type.QUERY);
copies.remember(source, this);
source.copyPlanFields(this, copies);
- layout = new VariableLayout();
- layout.copyFrom(source.layout, copies);
+ layout = source.layout.copyPlan(copies);
querySorter = null;
compiler = null;
this.limit = source.limit;
@@ -462,7 +461,7 @@ public boolean isDatasetSpecified() {
return datasetSpecified;
}
- public VariableLayout getLayout() {
+ VariableLayout getLayout() {
return layout;
}
@@ -1003,26 +1002,7 @@ public Node getExtNode(String name) {
}
public Node getExtNode(String name, boolean select) {
- Node node = getPatternNode(name);
- if (node != null) {
- return node;
- }
- if (select) {
- node = getSelectNode(name);
- if (node != null) {
- return node;
- }
- }
- node = getQueryNode(name);
- if (node != null) {
- return node;
- }
- node = getPatternSelectNode(name);
- if (node != null) {
- return node;
- }
- node = getQuerySelectNode(name);
- return node;
+ return layout.getExtNode(name, select, select ? getSelectNode(name) : null);
}
void store(Node node, boolean exist, boolean select) {
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayout.java b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayout.java
index e1185f710..d6bff2532 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayout.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayout.java
@@ -25,16 +25,18 @@ public VariableLayout() {
// Default constructor initializing empty variable collections and layout counters.
}
- public void copyFrom(VariableLayout source, PlanCopy copies) {
- this.nodeIndex = source.nodeIndex;
- this.edgeIndex = source.edgeIndex;
- this.patternNodes = copies.copy(source.patternNodes);
- this.patternSelectNodes = copies.copy(source.patternSelectNodes);
- this.queryNodes = copies.copy(source.queryNodes);
- this.querySelectNodes = copies.copy(source.querySelectNodes);
- this.bindingNodes = copies.copy(source.bindingNodes);
- this.constructNodes = copies.copy(source.constructNodes);
- this.argList = copies.copy(source.argList);
+ VariableLayout copyPlan(PlanCopy copies) {
+ VariableLayout copy = new VariableLayout();
+ copy.nodeIndex = this.nodeIndex;
+ copy.edgeIndex = this.edgeIndex;
+ copy.patternNodes = copies.copy(this.patternNodes);
+ copy.patternSelectNodes = copies.copy(this.patternSelectNodes);
+ copy.queryNodes = copies.copy(this.queryNodes);
+ copy.querySelectNodes = copies.copy(this.querySelectNodes);
+ copy.bindingNodes = copies.copy(this.bindingNodes);
+ copy.constructNodes = copies.copy(this.constructNodes);
+ copy.argList = copies.copy(this.argList);
+ return copy;
}
public int allocateNodeIndex() {
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/ConstructQueryCompiler.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/ConstructQueryCompiler.java
index 3b2dd7ace..659edfb95 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/ConstructQueryCompiler.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/ConstructQueryCompiler.java
@@ -16,7 +16,7 @@
import java.util.Objects;
/**
- * Compiles a {@link ConstructQueryAst} template and modifiers into a runtime {@link Query}.
+ * Compiles a {@link ConstructQueryAst} template and modifiers into a runtime {@link QueryPlan}.
*/
final class ConstructQueryCompiler {
@@ -58,7 +58,7 @@ private static void rejectUnsupportedConstructClauses(ConstructQueryAst construc
/**
* Compiles a {@code CONSTRUCT} template into a KGRAM {@link Exp} (a BGP of edges), kept separate
- * from the {@code WHERE} body and carried by {@link Query#setConstruct(Exp)}.
+ * from the {@code WHERE} body and carried by {@link QueryPlan#setConstruct(Exp)}.
*/
private static Exp compileConstructTemplate(
QueryPlan query, ConstructTemplateAst template, WhereCompiler compiler) {
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java
index d36571dc7..80a990772 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/CoreseAstQueryBuilder.java
@@ -28,7 +28,7 @@
* This bridge sits between the parsed SPARQL AST and the KGRAM runtime query model:
* it does not execute queries, it translates syntax-level query forms ({@code ASK},
* {@code SELECT}, {@code DESCRIBE}, {@code CONSTRUCT}) into runtime-ready
- * {@link Query}/{@link Exp} structures.
+ * {@link QueryPlan}/{@link Exp} structures.
*/
public final class CoreseAstQueryBuilder {
@@ -52,7 +52,7 @@ public CoreseAstQueryBuilder() {
}
/**
- * Builds a KGRAM {@link Query} from a SPARQL {@code ASK} query AST.
+ * Builds a KGRAM {@link QueryPlan} from a SPARQL {@code ASK} query AST.
*
* The bridge maps the query body and the modifiers that already have a direct
* runtime representation ({@code FROM}, {@code FROM NAMED}, {@code ORDER BY},
@@ -76,7 +76,7 @@ public QueryPlan toNextQuery(AskQueryAst askQueryAst) {
}
/**
- * Builds a KGRAM {@link Query} from a {@link SelectQueryAst}.
+ * Builds a KGRAM {@link QueryPlan} from a {@link SelectQueryAst}.
*
*
The bridge maps the compiled {@code WHERE} body, plain projection,
* dataset clauses, and solution modifiers that already have a direct runtime
@@ -107,7 +107,7 @@ public QueryPlan toNextQuery(SelectQueryAst selectQueryAst) {
}
/**
- * Builds a KGRAM {@link Query} from a {@link DescribeQueryAst}.
+ * Builds a KGRAM {@link QueryPlan} from a {@link DescribeQueryAst}.
*
*
Reuses the shared query shell (compiled {@code WHERE} body, dataset, LIMIT/OFFSET) and
* {@code ORDER BY} like the other forms, then lowers {@code DESCRIBE} to the construct-like
@@ -133,7 +133,7 @@ public QueryPlan toNextQuery(DescribeQueryAst describeQueryAst) {
}
/**
- * Builds a KGRAM {@link Query} from a {@link ConstructQueryAst}.
+ * Builds a KGRAM {@link QueryPlan} from a {@link ConstructQueryAst}.
*
*
Reuses the shared query shell (compiled {@code WHERE} body, dataset, LIMIT/OFFSET) and
* {@code ORDER BY} like the other forms, then compiles the {@code CONSTRUCT} template into a
@@ -206,7 +206,7 @@ private static void rejectUnsupportedDescribeClauses(DescribeQueryAst describeQu
}
/**
- * Creates the runtime {@link Query} shell shared by every query form handled here.
+ * Creates the runtime {@link QueryPlan} shell shared by every query form handled here.
*
*
The compiled {@code WHERE} body comes first, then the builder copies dataset
* and limit/offset information, and finally collects visible nodes so later clauses
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/SolutionModifierCompiler.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/SolutionModifierCompiler.java
index a25fa035e..67d3f11eb 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/SolutionModifierCompiler.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/SolutionModifierCompiler.java
@@ -27,7 +27,7 @@
/**
* Compiles SPARQL solution modifiers (projection, GROUP BY, HAVING, ORDER BY, LIMIT/OFFSET)
- * onto a runtime {@link Query}.
+ * onto a runtime {@link QueryPlan}.
*/
final class SolutionModifierCompiler {
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java
index df1d4e95e..9308b4a2c 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/bridge/WhereCompiler.java
@@ -96,7 +96,7 @@ Set inScopeVariables() {
/**
* Compiles a full SPARQL {@code WHERE} clause into the runtime body carried by a
- * KGRAM {@link Query}.
+ * KGRAM {@link QueryPlan}.
*
* This is the main entry point of the compiler. It expects the root
* {@link GroupGraphPatternAst} produced by the parser for a complete
diff --git a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/SparqlQueryExecutor.java b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/SparqlQueryExecutor.java
index 4023ddd60..0f00ac096 100644
--- a/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/SparqlQueryExecutor.java
+++ b/src/main/java/fr/inria/corese/core/next/query/impl/sparql/execution/SparqlQueryExecutor.java
@@ -705,7 +705,7 @@ private List irisToKgramNodes(Iterable iris) {
*
* Each binding entry becomes a (variable-node, value-node) pair. The variable
* node carries the variable name as its label so that
- * {@link Query#getExtNode(String)} can look it up by name during evaluation.
+ * {@link QueryPlan#getExtNode(String)} can look it up by name during evaluation.
* Bindings whose value cannot be converted to a KGRAM node are silently skipped.
*
* @return a {@link Mapping} with the converted bindings, or {@code null} when the
diff --git a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java
index 41dbded89..56f916053 100644
--- a/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java
+++ b/src/test/java/fr/inria/corese/core/next/query/impl/engine/pattern/VariableLayoutTest.java
@@ -107,8 +107,7 @@ void shouldCopyFromCleanly() {
source.allocateEdgeIndex();
PlanCopy copyContext = new PlanCopy();
- VariableLayout target = new VariableLayout();
- target.copyFrom(source, copyContext);
+ VariableLayout target = source.copyPlan(copyContext);
assertEquals(source.getNodeIndex(), target.getNodeIndex());
assertEquals(source.getEdgeIndex(), target.getEdgeIndex());