This is an automated email from the ASF dual-hosted git repository.

andy 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 0477e4d162 GH-3380: Constant triple terms as NodeValues
0477e4d162 is described below

commit 0477e4d1629cc1e5111a00cf6756f6257799a683
Author: Andy Seaborne <[email protected]>
AuthorDate: Thu Aug 14 13:10:05 2025 +0100

    GH-3380: Constant triple terms as NodeValues
---
 .../java/org/apache/jena/sparql/expr/ExprLib.java  |  4 +-
 .../org/apache/jena/sparql/expr/NodeValue.java     | 14 ++++--
 .../org/apache/jena/sparql/expr/TestExprLib.java   | 53 +++++++++++++++++++---
 .../org/apache/jena/sparql/expr/TestNodeValue.java | 36 ++++++++++-----
 4 files changed, 84 insertions(+), 23 deletions(-)

diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprLib.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprLib.java
index 63ce8e1ec3..39e180654e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/ExprLib.java
@@ -55,7 +55,7 @@ public class ExprLib
         // which overrides fillInStackTrace to be cheap but they loose the
         // general information for development.
         //
-        // Instead, pick out specal cases, the expression being a single 
variable
+        // Instead, pick out special cases, the expression being a single 
variable
         // being the important one.
         //
         // BOUND(?x) is a important case where the expression is often an 
exception
@@ -219,7 +219,7 @@ public class ExprLib
     public static Expr nodeToExpr(Node n) {
         if ( n.isVariable() )
             return new ExprVar(n);
-        if ( n.isTripleTerm() )
+        if ( n.isTripleTerm() && ! n.getTriple().isConcrete() )
             return new ExprTripleTerm(n);
         return NodeValue.makeNode(n);
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
index f4a5fe04e3..47d0d5df54 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/NodeValue.java
@@ -20,7 +20,8 @@ package org.apache.jena.sparql.expr;
 
 import static javax.xml.datatype.DatatypeConstants.*;
 import static org.apache.jena.datatypes.xsd.XSDDatatype.*;
-import static org.apache.jena.sparql.expr.ValueSpace.*;
+import static org.apache.jena.sparql.expr.ValueSpace.VSPACE_DIFFERENT;
+import static org.apache.jena.sparql.expr.ValueSpace.VSPACE_UNKNOWN;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -563,8 +564,15 @@ public abstract class NodeValue extends ExprNode
     // ---- Setting : used when a node is used to make a NodeValue
 
     private static NodeValue nodeToNodeValue(Node node) {
-        if ( node.isVariable() )
-            Log.warn(NodeValue.class, "Variable passed to 
NodeValue.nodeToNodeValue");
+        if ( ! node.isConcrete() ) {
+            String msg;
+            if ( node.isVariable() )
+                throw new ExprException("Variable passed to 
NodeValue.nodeToNodeValue: "+node);
+            if ( node.isTripleTerm() )
+                throw new ExprException("Triple term with a variable passed to 
NodeValue.nodeToNodeValue: "+node);
+            // Should not happen.
+            throw new ExprException("Node is not a constant");
+        }
 
         if ( ! node.isLiteral() )
             // Not a literal - no value to extract
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExprLib.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExprLib.java
index 727163813c..887d770722 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExprLib.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestExprLib.java
@@ -19,10 +19,14 @@
 package org.apache.jena.sparql.expr;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.junit.jupiter.api.Test;
 
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.sparql.sse.SSE;
 import org.apache.jena.sparql.util.ExprUtils;
 
 
@@ -73,16 +77,16 @@ public class TestExprLib
     @Test public void safeEquality_11()         { testSafeEquality("?x = 
'foo'^^<http://example>", true, false, false);}
     @Test public void safeEquality_12()         { testSafeEquality("?x = 
'foo'^^<http://example>", true, true, true);}
 
-    private static void testSafeEquality(String string, boolean b)
-    {
+    private static void testSafeEquality(String string, boolean result) {
         Expr expr = ExprUtils.parse(string);
-        assertEquals(b, ExprLib.isAssignmentSafeEquality(expr), 
()->"Input="+string);
+        assertEquals(result, ExprLib.isAssignmentSafeEquality(expr), () -> 
"Input=" + string);
     }
 
-    private static void testSafeEquality(String string, boolean b, boolean 
graphString, boolean graphNumber)
-    {
+    private static void testSafeEquality(String string, boolean result,
+                                         boolean graphHasStringEquality, 
boolean graphHasNumercialValueEquality) {
         Expr expr = ExprUtils.parse(string);
-        assertEquals(b, ExprLib.isAssignmentSafeEquality(expr, graphString, 
graphNumber), ()->"Input="+string);
+        assertEquals(result, ExprLib.isAssignmentSafeEquality(expr, 
graphHasStringEquality, graphHasNumercialValueEquality),
+                     () -> "Input=" + string);
     }
 
     /** E_Functions with different function IRIs must not be equals. */
@@ -92,4 +96,41 @@ public class TestExprLib
         Expr b = 
ExprUtils.parse("<http://www.opengis.net/def/function/geosparql/sfContains>(?a, 
?b)");
         assertNotEquals(a, b);
     }
+
+    private static PrefixMapping prefixMap = SSE.getPrefixMapRead();
+
+    @Test
+    public void nodeToExpr_01() {
+        String string = ":s";
+        Expr expr = ExprUtils.parse(string, prefixMap);
+        assertTrue(expr.isConstant());
+    }
+
+    @Test
+    public void nodeToExpr_02() {
+        String string = "<<( :s :p :o )>>";
+        Expr expr = ExprUtils.parse(string, prefixMap);
+        assertTrue(expr.isConstant());
+    }
+
+    @Test
+    public void nodeToExpr_03() {
+        String string = "<<( :s :p <<( :x :y :z )>> )>>";
+        Expr expr = ExprUtils.parse(string, prefixMap);
+        assertTrue(expr.isConstant());
+    }
+
+    @Test
+    public void nodeToExpr_04() {
+        String string = "<<( :s :p ?var )>>";
+        Expr expr = ExprUtils.parse(string, prefixMap);
+        assertFalse(expr.isConstant());
+    }
+
+    @Test
+    public void nodeToExpr_05() {
+        String string = "<<( :s :p <<( :x :y ?var )>> )>>";
+        Expr expr = ExprUtils.parse(string, prefixMap);
+        assertFalse(expr.isConstant());
+    }
 }
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
index 848781110c..3fca3f018e 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestNodeValue.java
@@ -45,18 +45,6 @@ import org.apache.jena.sparql.util.NodeFactoryExtra;
  */
 public class TestNodeValue
 {
-
-//
-//static void assertTrue(boolean b, String msg) {}
-//static void assertFalse(boolean b, String msg) {}
-//static void assertEquals(Object a,  Object b, String msg) {}
-//
-//static void assertTrue(boolean b) {}
-//static void assertFalse(boolean b) {}
-//static void assertEquals(Object a, Object b) {}
-//
-
-
     static final double doubleAccuracy = 0.00000001d;
     static boolean warningSetting;
 
@@ -1275,4 +1263,28 @@ public class TestNodeValue
         int x = NodeValue.compareAlways(nv1, nv2);
         assertEquals(Expr.CMP_GREATER, x);
     }
+
+    @Test
+    public void testBadNodeValue1() {
+        assertThrows(ExprException.class, ()-> {
+            Node n = SSE.parseNode("?variable");
+            NodeValue.makeNode(n);
+        });
+    }
+
+    @Test
+    public void testBadNodeValue2() {
+        assertThrows(ExprException.class, ()-> {
+            Node n = SSE.parseNode("<<(:s :p ?variable)>>");
+            NodeValue.makeNode(n);
+        });
+    }
+
+    @Test
+    public void testBadNodeValue3() {
+        assertThrows(ExprException.class, ()-> {
+            Node n = SSE.parseNode("<<( :s :p <<( :x :y ?variable )>> )>>");
+            NodeValue.makeNode(n);
+        });
+    }
 }

Reply via email to