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");
+    }
+}

Reply via email to