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


The following commit(s) were added to refs/heads/main by this push:
     new 641765ebe0 GH-4129: Fix: rdf:reifies triple dropped when a 
substitution variable is used inside an RDF 1.2 annotation
641765ebe0 is described below

commit 641765ebe08caa67fe2742223e6d1e565f46e1cf
Author: Aditya Nikam <[email protected]>
AuthorDate: Sun Aug 9 13:28:35 2026 +0530

    GH-4129: Fix: rdf:reifies triple dropped when a substitution variable is 
used inside an RDF 1.2 annotation
---
 .../syntax/syntaxtransform/QueryTransformOps.java  | 30 +++++++++++-----
 .../syntaxtransform/TestQuerySyntaxTransform.java  | 40 ++++++++++++++++++++++
 2 files changed, 62 insertions(+), 8 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryTransformOps.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryTransformOps.java
index 5ef86ea56f..e5eb167438 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryTransformOps.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryTransformOps.java
@@ -24,6 +24,7 @@ package org.apache.jena.sparql.syntax.syntaxtransform;
 import java.util.*;
 
 import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.query.Query;
 import org.apache.jena.query.QueryVisitor;
@@ -336,14 +337,27 @@ public class QueryTransformOps {
     // Transform a variable node.
     // Returns the argument java object for "no transform"
     private static Node transformOrSame(Node node, ExprTransform 
exprTransform) {
-        if ( ! Var.isVar(node) )
-            return node;
-        Expr e2 = exprTransform.transform(node);
-        if ( e2 == null )
-            return node;
-        if ( ! e2.isConstant() )
-            return node;
-        return e2.getConstant().getNode();
+        if ( Var.isVar(node) ) {
+            Expr e2 = exprTransform.transform(node);
+            if ( e2 == null )
+                return node;
+            if ( ! e2.isConstant() )
+                return node;
+            return e2.getConstant().getNode();
+        }
+        // RDF 1.2 triple term (e.g. the object of an rdf:reifies triple from 
a {| ... |}
+        // annotation) may itself contain variables. Recurse into the triple 
term
+        // and replace any variables used inside a reified triple's annotation.
+        if ( node.isTripleTerm() && ! node.isConcrete() ) {
+            Triple triple = node.getTriple();
+            Node s = transformOrSame(triple.getSubject(), exprTransform);
+            Node p = transformOrSame(triple.getPredicate(), exprTransform);
+            Node o = transformOrSame(triple.getObject(), exprTransform);
+            if ( s == triple.getSubject() && p == triple.getPredicate() && o 
== triple.getObject() )
+                return node;
+            return NodeFactory.createTripleTerm(s, p, o);
+        }
+        return node;
     }
 
     static class QueryShallowCopy implements QueryVisitor {
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxTransform.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxTransform.java
index 74f11dd142..3140eeb1f0 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxTransform.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxTransform.java
@@ -22,21 +22,27 @@
 package org.apache.jena.sparql.syntax.syntaxtransform;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.junit.jupiter.api.Test;
 
 import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
 import org.apache.jena.query.Query;
 import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.Syntax;
 import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.core.Var;
 import org.apache.jena.sparql.sse.SSE;
 import org.apache.jena.sparql.util.ModelUtils;
 import org.apache.jena.update.UpdateFactory;
 import org.apache.jena.update.UpdateRequest;
+import org.apache.jena.vocabulary.RDF;
 
 /** Test of variable replaced by value */
 public class TestQuerySyntaxTransform
@@ -158,6 +164,40 @@ public class TestQuerySyntaxTransform
                        "s", "<urn:ex:z>", "g", "<urn:ex:g>");
     }
 
+    @Test public void transformTransformReplace_reifies_01() {
+        String queryString = """
+                PREFIX ex: <http://example.com/>
+                CONSTRUCT {
+                    ?this ex:seeAlso ex:Nothing {| ex:tempTriple true |} .
+                } WHERE {}
+                """ ;
+        Query query = QueryFactory.create(queryString, Syntax.syntaxARQ);
+
+        Node thing = SSE.parseNode("<http://www.w3.org/2002/07/owl#Thing>");
+        Node seeAlso = SSE.parseNode("<http://example.com/seeAlso>");
+        Node nothing = SSE.parseNode("<http://example.com/Nothing>");
+
+        Query transformed = QueryTransformOps.replaceVars(query, 
Map.of(Var.alloc("this"), thing));
+        List<Quad> quads = transformed.getConstructTemplate().getQuads();
+
+        boolean hasBaseTriple = quads.stream().anyMatch(q ->
+                q.getSubject().equals(thing) && 
q.getPredicate().equals(seeAlso) && q.getObject().equals(nothing));
+        assertTrue(hasBaseTriple, "Base triple should have ?this substituted");
+
+        boolean hasCorrectReifiesTriple = quads.stream().anyMatch(q -> {
+            if ( ! RDF.Nodes.reifies.equals(q.getPredicate()) )
+                return false;
+            Node obj = q.getObject();
+            if ( ! obj.isTripleTerm() )
+                return false;
+            Triple reified = obj.getTriple();
+            return reified.getSubject().equals(thing)
+                && reified.getPredicate().equals(seeAlso)
+                && reified.getObject().equals(nothing);
+        });
+        assertTrue(hasCorrectReifiesTriple, "rdf:reifies triple's quoted 
triple should also have ?this substituted");
+    }
+
     @Test public void transformSubstituteupdate_01() {
         testUpdate("DELETE { ?s <urn:ex:p> ?x } WHERE {}",
                    "DELETE { ?s <urn:ex:p> <urn:ex:z> } WHERE {}",

Reply via email to