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 389f458afc6ba6f6962fcccf70c0c57955cf1f16
Author: Andy Seaborne <[email protected]>
AuthorDate: Tue Mar 10 11:43:41 2026 +0000

    Update CSV & TSV results for triple terms
---
 .../jena/riot/rowset/rw/RowSetWriterCSV.java       | 11 +++++----
 .../apache/jena/sparql/util/NodeFactoryExtra.java  | 28 +++++++++++++++++++---
 .../jena/riot/resultset/TestResultSetIO.java       | 14 +++++++++--
 .../apache/jena/sparql/resultset/TS_ResultSet.java |  4 ++--
 ...ltSetFormat2.java => TestResultSetParsing.java} |  2 +-
 ...ltSetFormat1.java => TestResultSetWriting.java} | 26 ++++++++++----------
 6 files changed, 61 insertions(+), 24 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java 
b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java
index 615700022a..d8b5eee45d 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/rowset/rw/RowSetWriterCSV.java
@@ -40,6 +40,7 @@ import org.apache.jena.sparql.engine.binding.Binding;
 import org.apache.jena.sparql.exec.RowSet;
 import org.apache.jena.sparql.resultset.ResultSetException;
 import org.apache.jena.sparql.util.Context;
+import org.apache.jena.sparql.util.FmtUtils;
 
 public class RowSetWriterCSV implements RowSetWriter {
 
@@ -125,8 +126,8 @@ public class RowSetWriterCSV implements RowSetWriter {
     }
 
     private static void output(AWriter w, Node n, NodeToLabel bnodes) {
-        // String str = FmtUtils.stringForNode(n) ;
-        String str = "?";
+        String str;
+        // Without quotes.
         if ( n.isLiteral() )
             str = n.getLiteralLexicalForm();
         else if ( n.isURI() )
@@ -134,9 +135,11 @@ public class RowSetWriterCSV implements RowSetWriter {
         else if ( n.isBlank() ) {
             str = bnodes.get(null, n);
             // Comes with leading "_:"
-            str = str.substring(2);
+        } else if ( n.isTripleTerm() ) {
+            str = FmtUtils.stringForNode(n) ;
+        } else {
+            str = "?";
         }
-
         str = csvSafe(str);
         w.write(str);
         w.flush();
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java
index 3a74b18056..00d55f820f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/NodeFactoryExtra.java
@@ -27,11 +27,13 @@ import org.apache.jena.atlas.lib.DateTimeUtils ;
 import org.apache.jena.datatypes.xsd.XSDDatatype ;
 import org.apache.jena.graph.Node ;
 import org.apache.jena.graph.NodeFactory ;
+import org.apache.jena.graph.Triple;
 import org.apache.jena.graph.impl.LiteralLabel ;
 import org.apache.jena.riot.RiotException ;
 import org.apache.jena.riot.system.PrefixMap ;
 import org.apache.jena.riot.system.Prefixes;
 import org.apache.jena.riot.tokens.Token ;
+import org.apache.jena.riot.tokens.TokenType;
 import org.apache.jena.riot.tokens.Tokenizer ;
 import org.apache.jena.riot.tokens.TokenizerText;
 import org.apache.jena.sparql.sse.SSE ;
@@ -68,15 +70,24 @@ public class NodeFactoryExtra {
      */
     public static Node parseNode(String nodeString, PrefixMap pmap) {
         Tokenizer tokenizer = 
TokenizerText.create().fromString(nodeString).build();
+        Node node = parseNode(nodeString, tokenizer, pmap);
+        if ( tokenizer.hasNext() )
+            throw new RiotException("Trailing characters in string: " + 
nodeString) ;
+        return node;
+    }
+
+    private static Node parseNode(String nodeString, Tokenizer tokenizer, 
PrefixMap pmap) {
         if ( !tokenizer.hasNext() )
             throw new RiotException("Empty RDF term") ;
         Token token = tokenizer.next() ;
+        if ( token.hasType(TokenType.L_TRIPLE) ) {
+            // Triple term.
+            Node n = parseTripleTerm(nodeString, tokenizer, pmap);
+            return n;
+        }
         Node node = token.asNode(pmap) ;
         if ( node == null )
             throw new RiotException("Bad RDF Term: " + nodeString) ;
-
-        if ( tokenizer.hasNext() )
-            throw new RiotException("Trailing characters in string: " + 
nodeString) ;
         if ( node.isURI() ) {
             // Lightly test for bad URIs.
             String x = node.getURI() ;
@@ -86,6 +97,17 @@ public class NodeFactoryExtra {
         return node ;
     }
 
+    private static Node parseTripleTerm(String nodeString, Tokenizer 
tokenizer, PrefixMap pmap) {
+        Node s = parseNode(nodeString, tokenizer, pmap);
+        Node p = parseNode(nodeString, tokenizer, pmap);
+        Node o = parseNode(nodeString, tokenizer, pmap);
+        Token tok = tokenizer.next();
+        if ( ! tok.hasType(TokenType.R_TRIPLE) )
+            throw new RiotException("Bad triple term: " + nodeString) ;
+        Triple t = Triple.create(s, p, o);
+        return NodeFactory.createTripleTerm(t);
+    }
+
     /**
      * Node to int
      *
diff --git 
a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java 
b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
index 6eeaec367e..2ff6831faf 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/resultset/TestResultSetIO.java
@@ -110,8 +110,18 @@ public class TestResultSetIO {
         ResultSetMgr.write(out2, rsw, lang);
         rsw.reset();
         in = new ByteArrayInputStream(out2.toByteArray());
-        ResultSet rs2 = ResultSetMgr.read(in, lang);
-        assertTrue(ResultsCompare.equalsByTerm(rsw, rs2));
+        ResultSetRewindable rsw2 = ResultSetMgr.read(in, lang).rewindable();
+
+//        if ( ! ResultsCompare.equalsByTerm(rsw, rsw2) ) {
+//            ResultSetMgr.write(System.out, rsw, ResultSetLang.RS_JSON);
+//            System.out.println("--");
+//            ResultSetMgr.write(System.out, rsw2, ResultSetLang.RS_JSON);
+//        }
+
+        rsw.reset();
+        rsw2.reset();
+
+        assertTrue(ResultsCompare.equalsByTerm(rsw, rsw2));
     }
 }
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java
index 757ddea7dd..f0d13db30c 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TS_ResultSet.java
@@ -27,8 +27,8 @@ import org.junit.platform.suite.api.Suite;
 @Suite
 @SelectClasses({
     TestResultSet.class
-    , TestResultSetFormat1.class
-    , TestResultSetFormat2.class
+    , TestResultSetWriting.class
+    , TestResultSetParsing.class
 })
 public class TS_ResultSet
 {
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java
similarity index 99%
rename from 
jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java
rename to 
jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java
index 6009c7bf19..4106bf8534 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat2.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetParsing.java
@@ -43,7 +43,7 @@ import org.apache.jena.sparql.exec.RowSet;
 import org.apache.jena.sparql.util.Context;
 import org.apache.jena.sys.JenaSystem;
 
-public class TestResultSetFormat2 {
+public class TestResultSetParsing {
 
     static { JenaSystem.init(); }
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java
similarity index 92%
rename from 
jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
rename to 
jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java
index 05a0ecc35a..f3863b6233 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetFormat1.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/resultset/TestResultSetWriting.java
@@ -25,8 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.stream.Stream;
 
@@ -54,7 +52,7 @@ import org.apache.jena.vocabulary.XSD;
 
 @ParameterizedClass
 @MethodSource("provideArgs")
-public class TestResultSetFormat1
+public class TestResultSetWriting
 {
     static { JenaSystem.init(); }
 
@@ -100,7 +98,7 @@ public class TestResultSetFormat1
        """
        +"  (row (?x <" + RDF.type.toString() + ">))\n"
        +"  (row (?x <" + RDFS.label.toString() + ">))\n"
-        +"    (row (?x <" + XSD.integer.toString() + ">))\n"
+        +"  (row (?x <" + XSD.integer.toString() + ">))\n"
         +"  (row (?x <" + OWL.sameAs.toString() + ">))\n"
        +"""
          (row )
@@ -111,7 +109,7 @@ public class TestResultSetFormat1
 
     static String $rs8 = """
        (resultset (?x)
-         (row (?x \"has \\t tab character\"))
+         (row (?x "has \\t tab character"))
        )
        """;
 
@@ -123,28 +121,32 @@ public class TestResultSetFormat1
 
     static String $rs10 = """
        (resultset (?x)
-         (row (?x \"Includes a raw     tab character\"))
+         (row (?x "Includes a raw      tab character"))
        )
        """;
 
     static String $rs11 = """
        (resultset (?x)
-         (row (?x \"Includes \\n new line\"))
+         (row (?x "Includes \\n new line"))
        )
        """;
 
+    static String $rs12 = "(resultset (?x) (row (?x 'abc'@en--ltr)) )";
+
+    static String $rs13 = """
+            (resultset (?x)
+               (row (?x <<( <x:s> <x:p> <x:o> )>> ))
+            )
+            """;
+
 
     private static Stream<Arguments> provideArgs() {
         List<Arguments> x = List.of(Arguments.of($rs0), Arguments.of($rs1), 
Arguments.of($rs2), Arguments.of($rs3), Arguments.of($rs4),
                                     Arguments.of($rs5), Arguments.of($rs6), 
Arguments.of($rs7), Arguments.of($rs8), Arguments.of($rs9),
-                                    Arguments.of($rs10), Arguments.of($rs11));
+                                    Arguments.of($rs10), Arguments.of($rs11), 
Arguments.of($rs12), Arguments.of($rs13) );
         return x.stream();
     }
 
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] { {$rs0}, {$rs1}, {$rs2}, {$rs3}, 
{$rs4}, {$rs5}, {$rs6}, {$rs7}, {$rs8}, {$rs9}, {$rs10}, {$rs11} } );
-    }
-
     @Parameter(0)
     String $rs;
 

Reply via email to