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
commit 8f265909ffe648808001b7117c1e6240415fd762 Author: Andy Seaborne <[email protected]> AuthorDate: Wed Jan 7 15:15:32 2026 +0000 Implement SameVALUE (ARQ keyword) --- .../org/apache/jena/sparql/expr/E_SameValue.java | 25 ++++++++++++---- .../org/apache/jena/sparql/expr/NodeValue.java | 4 +-- .../sparql/expr/TestSparqlKeywordFunctions.java | 34 +++++++++++++++++----- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SameValue.java b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SameValue.java index 231760e9ce..30f7530643 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SameValue.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/expr/E_SameValue.java @@ -18,7 +18,6 @@ package org.apache.jena.sparql.expr; -import org.apache.jena.sparql.ARQNotImplemented; import org.apache.jena.sparql.sse.Tags; public class E_SameValue extends ExprFunction2 { @@ -30,15 +29,29 @@ public class E_SameValue extends ExprFunction2 { @Override public NodeValue eval(NodeValue x, NodeValue y) { - throw new ARQNotImplemented("E_SameValue"); - // "strict/plain" and "extended" -// // EXCEPT NaN -// boolean b = NodeValue.sameValueAs(x, y) ; -// return NodeValue.booleanReturn(b) ; + if ( isNaN(x) ) { + if ( isNaN(y) ) + return NodeValue.TRUE; + return NodeValue.FALSE; + } + boolean b = NodeValue.sameValueAs(x, y) ; + return NodeValue.booleanReturn(b) ; } @Override public Expr copy(Expr e1, Expr e2) { return new E_SameValue(e1, e2); } + + private static boolean isNaN(NodeValue nv) { + if ( nv.isDouble() ) { + double d = nv.getDouble(); + return Double.isNaN(d); + } + if ( nv.isFloat() ) { + float f = nv.getFloat(); + return Float.isNaN(f); + } + return false; + } } 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 e127b4aaf0..f7e417ce2f 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 @@ -401,8 +401,8 @@ public abstract class NodeValue extends ExprNode // Every langtag implies another value space as well. /** - * Return true if the two NodeValues are known to be the same value return false - * if known to be different values, throw ExprEvalException otherwise + * Return true if the two NodeValues are known to be the same value. Return false + * if known to be different values, else throw ExprEvalException */ public static boolean sameValueAs(NodeValue nv1, NodeValue nv2) { return NVCompare.sameValueAs(nv1, nv2); diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSparqlKeywordFunctions.java b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSparqlKeywordFunctions.java index b4b06b6362..25f2e6150d 100644 --- a/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSparqlKeywordFunctions.java +++ b/jena-arq/src/test/java/org/apache/jena/sparql/expr/TestSparqlKeywordFunctions.java @@ -84,7 +84,7 @@ public class TestSparqlKeywordFunctions | 'NOW' NIL | 'MD5' '(' Expression ')' | 'SHA1' '(' Expression ')' - | SHA224 '(' Expression ')' + | 'SHA224' '(' Expression ')' | 'SHA256' '(' Expression ')' | 'SHA384' '(' Expression ')' | 'SHA512' '(' Expression ')' @@ -409,12 +409,32 @@ public class TestSparqlKeywordFunctions @Test public void replace30() { test("REPLACE('b'@en--ltr, '(a|b)?', 'Z')", "'Z'@en--ltr"); } @Test public void replace31() { test("REPLACE('b'@en--ltr, '(a|b)?', 'Z'@en--ltr)", "'Z'@en--ltr"); } - @Test public void sameTerm1() { test("sameTerm(1,1)", kwTRUE); } - @Test public void sameTerm2() { test("sameTerm(1,1.0)", kwFALSE); } - @Test public void sameTerm3() { test("sameTerm(1,1e0)", kwFALSE); } - @Test public void sameTerm4() { test("sameTerm(<_:a>, <_:a>)", kwTRUE); } - @Test public void sameTerm5() { test("sameTerm(<x>, <x>)", kwTRUE); } - @Test public void sameTerm6() { test("sameTerm(<x>, <y>)", kwFALSE); } + @Test public void sameTerm_01() { test("sameTerm(1,1)", kwTRUE); } + @Test public void sameTerm_02() { test("sameTerm(1,1.0)", kwFALSE); } + @Test public void sameTerm_03() { test("sameTerm(1,1e0)", kwFALSE); } + @Test public void sameTerm_04() { test("sameTerm(<_:a>, <_:a>)", kwTRUE); } + @Test public void sameTerm_05() { test("sameTerm(<x>, <x>)", kwTRUE); } + @Test public void sameTerm_06() { test("sameTerm(<x>, <y>)", kwFALSE); } + + @Test public void sameTerm_07() { test("sameTerm('abc'@en, 'abc'@EN)", kwTRUE); } + @Test public void sameTerm_08() { test("sameTerm('abc'@en--ltr, 'abc'@EN--ltr)", kwTRUE); } + @Test public void sameTerm_09() { test("sameTerm('abc'@en--ltr, 'abc'@en--rtl)", kwFALSE); } + @Test public void sameTerm_10() { test("sameTerm(<<( <x> <p> 123 )>>, <<( <x> <p> 123 )>>)", kwTRUE); } + + // 'SameValue' is not in SPARQL 1.2 as a keyword. + // However, ARQ provides access to the function. + + @Test public void sameValue_01() { test("sameValue(<x>, <x>)", kwTRUE); } + @Test public void sameValue_02() { test("sameValue(<x>, <y>)", kwFALSE); } + @Test public void sameValue_03() { test("sameValue(1, 1.0e0)", kwTRUE); } + @Test public void sameValue_04() { test("sameValue('NaN'^^xsd:double, 'NaN'^^xsd:double)", kwTRUE); } + @Test public void sameValue_05() { test("sameValue('NaN'^^xsd:float, 'NaN'^^xsd:double)", kwTRUE); } + @Test public void sameValue_06() { test("sameValue('NaN'^^xsd:double, 'NaN'^^xsd:float)", kwTRUE); } + @Test public void sameValue_07() { test("sameValue('NaN'^^xsd:float, 'NaN'^^xsd:float)", kwTRUE); } + @Test public void sameValue_08() { test("sameValue('NaN'^^xsd:float, 'INF'^^xsd:float)", kwFALSE); } + @Test public void sameValue_09() { test("sameValue(<<( <x> <p> 123 )>>, <<( <x> <p> 123.0e0 )>>)", kwTRUE); } + @Test public void sameValue_10() { test("sameValue(<<( <x> <p> 'abc'@en )>>, <<( <x> <p> 'abc'@en--ltr )>>)", kwFALSE); } + @Test public void sameValue_11() { test("sameValue(<<( <x> <p> 'abc'@en--ltr )>>, <<( <x> <p> 'abc'@en--rtl )>>)", kwFALSE); } @Test public void OneOf_01() { test("57 in (xsd:integer, '123')", kwFALSE); } @Test public void OneOf_02() { test("57 in (57)", kwTRUE); }
