This is an automated email from the ASF dual-hosted git repository. afs pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit 2af738faceb8351c7ab3e2d584cc53fb4ad1986c Author: Andy Seaborne <[email protected]> AuthorDate: Tue Aug 4 12:44:29 2026 +0100 GH-4094: Consolidate setting 'now' for query execution --- .../apache/jena/sparql/engine/QueryEngineBase.java | 12 +++-- .../jena/sparql/engine/main/QueryEngineMain.java | 8 ++-- .../apache/jena/sparql/exec/QueryExecDataset.java | 2 - .../org/apache/jena/sparql/engine/TS_Engine.java | 1 + .../apache/jena/sparql/engine/TestQueryEngine.java | 56 ++++++++++++++++++++++ 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java index f60bf0e5ae..01a3372c4d 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java @@ -56,9 +56,9 @@ public abstract class QueryEngineBase implements OpEval, Closeable this(dsg, input, cxt); this.query = query; query.ensureResultVars(); + dataset = prepareDataset(dsg, query); // Unoptimized so far. setOp(createOp(query)); - dataset = prepareDataset(dsg, query); } private DatasetGraph prepareDataset(DatasetGraph originalDataset, Query query) { @@ -96,8 +96,7 @@ public abstract class QueryEngineBase implements OpEval, Closeable // Ensure context setup - usually done in QueryExecutionBase // so it can be changed after initialization. if ( context == null ) - context = Context.setupContextForDataset(context, dataset); - Context.setCurrentDateTimeIfUndef(context); + context = Context.setupContextForDataset(cxt, dataset); this.query = null; setOp(op); } @@ -113,6 +112,12 @@ public abstract class QueryEngineBase implements OpEval, Closeable this.startBinding = input; } + // Call this after context is set. + private static void currentDateTime(Context context) { + if ( context != null ) + Context.setCurrentDateTimeIfUndef(context); + } + public Plan getPlan() { if ( plan == null ) plan = createPlan(); @@ -120,6 +125,7 @@ public abstract class QueryEngineBase implements OpEval, Closeable } protected Plan createPlan() { + currentDateTime(context); // Decide the algebra to actually execute. Op op = queryOp; if ( !startBinding.isEmpty() ) { diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/QueryEngineMain.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/QueryEngineMain.java index eabdf1e2b8..2282a3e266 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/QueryEngineMain.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/main/QueryEngineMain.java @@ -40,11 +40,11 @@ public class QueryEngineMain extends QueryEngineBase static public void register() { QueryEngineRegistry.addFactory(factory) ; } static public void unregister() { QueryEngineRegistry.removeFactory(factory) ; } - public QueryEngineMain(Op op, DatasetGraph dataset, Binding input, Context context) - { super(op, dataset, input, context) ; } + public QueryEngineMain(Op op, DatasetGraph dataset, Binding input, Context context) { + super(op, dataset, input, context); + } - public QueryEngineMain(Query query, DatasetGraph dataset, Binding input, Context context) - { + public QueryEngineMain(Query query, DatasetGraph dataset, Binding input, Context context) { super(query, dataset, input, context) ; } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDataset.java b/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDataset.java index 7c23f1b829..e02bbf099d 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDataset.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDataset.java @@ -106,7 +106,6 @@ public class QueryExecDataset implements QueryExec this.timeout2 = timeout.overallTimeoutMillis(); // See also query substitution handled in QueryExecBuilder this.initialBinding = initialToEngine; - // Cancel signal may originate from e.g. an update execution. this.cancelSignal = Context.getOrSetCancelSignal(context); @@ -114,7 +113,6 @@ public class QueryExecDataset implements QueryExec } private void init() { - Context.setCurrentDateTimeIfUndef(context); if ( query != null ) context.put(ARQConstants.sysCurrentQuery, query); } diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/TS_Engine.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/TS_Engine.java index bb19c90183..4e4a3b3ace 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/engine/TS_Engine.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/TS_Engine.java @@ -28,6 +28,7 @@ import org.junit.platform.suite.api.Suite; @SelectClasses({ TestQueryEngineMultiThreaded.class , TestQueryEngineFromContext.class + , TestQueryEngine.class , TestJsonEval.class }) diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/engine/TestQueryEngine.java b/jena-arq/src/test/java/org/apache/jena/sparql/engine/TestQueryEngine.java new file mode 100644 index 0000000000..dc957734bc --- /dev/null +++ b/jena-arq/src/test/java/org/apache/jena/sparql/engine/TestQueryEngine.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.apache.jena.sparql.engine; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import org.apache.jena.graph.Node; +import org.apache.jena.query.ARQ; +import org.apache.jena.sparql.ARQConstants; +import org.apache.jena.sparql.core.DatasetGraph; +import org.apache.jena.sparql.core.DatasetGraphFactory; +import org.apache.jena.sparql.exec.QueryExec; +import org.apache.jena.sparql.sse.SSE; +import org.apache.jena.sparql.util.Context; + +/** Tests for query setup and execution not covered by tests elsewhere */ +public class TestQueryEngine { + + @Test public void fixed_now() { + String fixedNowStr = "'1970-01-01T00:00:00Z'^^xsd:dateTime"; + String queryString = + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"+ + "ASK { FILTER ( NOW() = "+fixedNowStr+") }"; + Node fixedNow = SSE.parseNode(fixedNowStr); + Context context = ARQ.getContext().copy(); + context.set(ARQConstants.sysCurrentTime, fixedNow); + DatasetGraph dsg = DatasetGraphFactory.empty(); + + boolean result = QueryExec.dataset(dsg) + .query(queryString) + .context(context) + .ask(); + assertTrue(result, "NOW() not the expected fixed setting"); + } +}
