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 f63360c4f052eb5e0529a1b256f7cbdcb82c0bce
Author: Andy Seaborne <[email protected]>
AuthorDate: Tue Aug 20 22:19:43 2024 +0100

    GH-2650: Fix for substitution into aggregates
---
 .../syntaxtransform/ExprTransformNodeElement.java  | 65 ++++++++++++----------
 .../syntax/syntaxtransform/QueryTransformOps.java  | 15 ++---
 .../apache/jena/sparql/algebra/TestOpAsQuery.java  | 42 +++++++-------
 .../syntaxtransform/TestSyntaxTransform.java       | 21 +++++++
 4 files changed, 84 insertions(+), 59 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/ExprTransformNodeElement.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/ExprTransformNodeElement.java
index 7da7057fd0..ea7eca93ad 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/ExprTransformNodeElement.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/ExprTransformNodeElement.java
@@ -16,72 +16,77 @@
  * limitations under the License.
  */
 
-package org.apache.jena.sparql.syntax.syntaxtransform ;
+package org.apache.jena.sparql.syntax.syntaxtransform;
 
-import org.apache.jena.atlas.lib.InternalErrorException ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.algebra.Op ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.expr.* ;
-import org.apache.jena.sparql.graph.NodeTransform ;
-import org.apache.jena.sparql.syntax.Element ;
-import org.apache.jena.sparql.syntax.ElementVisitor ;
+import org.apache.jena.atlas.lib.InternalErrorException;
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.algebra.Op;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.expr.*;
+import org.apache.jena.sparql.graph.NodeTransform;
+import org.apache.jena.sparql.syntax.Element;
+import org.apache.jena.sparql.syntax.ElementVisitor;
 
 /**
  * Special version of ExprTransform for applying a node transform on syntax
  * (Elements) only
  */
 public class ExprTransformNodeElement extends ExprTransformCopy {
-    private final NodeTransform    nodeTransform ;
-    private final ElementTransform elementTransform ;
+    private final NodeTransform    nodeTransform;
+    private final ElementTransform elementTransform;
     private final ElementVisitor beforeVisitor;
     private final ElementVisitor afterVisitor;
 
     public ExprTransformNodeElement(NodeTransform nodeTransform, 
ElementTransform eltrans) {
-        this(nodeTransform, eltrans, null, null) ;
+        this(nodeTransform, eltrans, null, null);
     }
 
     public ExprTransformNodeElement(NodeTransform nodeTransform, 
ElementTransform eltrans,
                                     ElementVisitor beforeVisitor, 
ElementVisitor afterVisitor) {
-        this.nodeTransform = nodeTransform ;
-        this.elementTransform = eltrans ;
-        this.beforeVisitor = beforeVisitor ;
-        this.afterVisitor = afterVisitor ;
+        this.nodeTransform = nodeTransform;
+        this.elementTransform = eltrans;
+        this.beforeVisitor = beforeVisitor;
+        this.afterVisitor = afterVisitor;
     }
 
     @Override
     public Expr transform(ExprVar nv) {
-        Node n = nodeTransform.apply(nv.getAsNode()) ;
+        Node n = nodeTransform.apply(nv.getAsNode());
         if ( n == nv.getAsNode() )
-            return nv ;
+            return nv;
         if ( n instanceof Var ) {
-            Var v = Var.alloc(n) ;
-            return new ExprVar(v) ;
+            Var v = Var.alloc(n);
+            return new ExprVar(v);
         }
-        return NodeValue.makeNode(n) ;
+        return NodeValue.makeNode(n);
     }
 
     @Override
     public Expr transform(NodeValue nv) {
-        Node n = nodeTransform.apply(nv.asNode()) ;
+        Node n = nodeTransform.apply(nv.asNode());
         if ( n == nv.asNode() )
-            return nv ;
-        return NodeValue.makeNode(n) ;
+            return nv;
+        return NodeValue.makeNode(n);
     }
 
     @Override
     public Expr transform(ExprFunctionOp funcOp, ExprList args, Op opArg) {
         // Syntax phased only - ignore args and opArg
-        Element elt = funcOp.getElement() ;
-        Element elt1 = ElementTransformer.transform(elt, elementTransform, 
this, beforeVisitor, afterVisitor) ;
+        Element elt = funcOp.getElement();
+        Element elt1 = ElementTransformer.transform(elt, elementTransform, 
this, beforeVisitor, afterVisitor);
         if ( elt == elt1 )
-            return funcOp ;
+            return funcOp;
         else {
             if ( funcOp instanceof E_Exists )
-                return new E_Exists(elt1) ;
+                return new E_Exists(elt1);
             if ( funcOp instanceof E_NotExists )
-                return new E_NotExists(elt1) ;
-            throw new InternalErrorException("Unknown ExprFunctionOp: " + 
funcOp.getFunctionSymbol()) ;
+                return new E_NotExists(elt1);
+            throw new InternalErrorException("Unknown ExprFunctionOp: " + 
funcOp.getFunctionSymbol());
         }
     }
+
+    @Override
+    public Expr transform(ExprAggregator eAgg) {
+        return eAgg.applyNodeTransform(nodeTransform);
+    }
 }
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 b461a0a7e0..313f75245b 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
@@ -36,10 +36,7 @@ import org.apache.jena.shared.PrefixMapping;
 import org.apache.jena.shared.impl.PrefixMappingImpl;
 import org.apache.jena.sparql.ARQException;
 import org.apache.jena.sparql.core.*;
-import org.apache.jena.sparql.expr.Expr;
-import org.apache.jena.sparql.expr.ExprTransform;
-import org.apache.jena.sparql.expr.ExprTransformer;
-import org.apache.jena.sparql.expr.ExprVar;
+import org.apache.jena.sparql.expr.*;
 import org.apache.jena.sparql.graph.NodeTransform;
 import org.apache.jena.sparql.modify.request.QuadAcc;
 import org.apache.jena.sparql.syntax.*;
@@ -82,6 +79,7 @@ public class QueryTransformOps {
             // Reset internal to only what now can be seen.
             q2.resetResultVars();
         }
+        setAggregators(q2, query, exprTransform);
         return q2;
     }
 
@@ -111,6 +109,12 @@ public class QueryTransformOps {
         }
     }
 
+    private static void setAggregators(Query newQuery, Query query, 
ExprTransform exprTransform) {
+        for (ExprAggregator aggregator : query.getAggregators()) {
+            newQuery.getAggregators().add((ExprAggregator) 
exprTransform.transform(aggregator));
+        }
+    }
+
     // Do the result form part of the cloned query.
     private static void mutateByQueryType(Query q2, ElementTransform 
transform, ExprTransform exprTransform) {
         switch(q2.queryType()) {
@@ -300,9 +304,6 @@ public class QueryTransformOps {
                 for (String x : desc.getNamedGraphURIs())
                     newQuery.addNamedGraphURI(x);
             }
-
-            // Aggregators.
-            newQuery.getAggregators().addAll(query.getAggregators());
         }
 
         @Override
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
index 0004bcc172..3d91b293b9 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestOpAsQuery.java
@@ -344,28 +344,26 @@ public class TestOpAsQuery {
 
     @Test
     public void testAggregatesInSubQuery3() {
-        //Actual test case from JENA-445 bug report
-        String queryString =
-                "PREFIX dcterms: <http://purl.org/dc/terms/> \n" +
-                "PREFIX dbpedia: <http://dbpedia.org/resource/> \n" +
-
-                "SELECT ?num_of_holidays ?celebrate_Chinese_New_Year WHERE { 
\n" +
-                "{" +
-                "SELECT ?country_cat (COUNT(?holiday) as ?num_of_holidays) \n" 
+
-                "WHERE {" +
-                "?country_cat <http://www.w3.org/2004/02/skos/core#broader> 
<http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
-                "?holiday dcterms:subject ?country_cat \n" +
-                "}GROUP by ?country_cat \n" +
-                "} \n" +
-                "{ \n" +
-                "SELECT ?country_cat (COUNT(?holiday) as 
?celebrate_Chinese_New_Year) \n" +
-                "WHERE { \n" +
-                "?country_cat <http://www.w3.org/2004/02/skos/core#broader> 
<http://dbpedia.org/resource/Category:Public_holidays_by_country>. \n" +
-                "?holiday dcterms:subject ?country_cat \n" +
-                
"FILTER(?holiday=\"http://dbpedia.org/resource/Lunar_New_Year\'s_Day\") \n" +
-                "}GROUP by ?country_cat \n" +
-                "} \n" +
-                "}\n";
+        String queryString = """
+                PREFIX dcterms: <http://purl.org/dc/terms/>
+                PREFIX dbpedia: <http://dbpedia.org/resource/>
+
+                SELECT ?num_of_holidays ?celebrate_Chinese_New_Year WHERE {
+                  {
+                    SELECT ?country_cat (COUNT(?holiday) as ?num_of_holidays) 
WHERE {
+                        ?country_cat 
<http://www.w3.org/2004/02/skos/core#broader> 
<http://dbpedia.org/resource/Category:Public_holidays_by_country>.
+                        ?holiday dcterms:subject ?country_cat
+                    } GROUP by ?country_cat
+                  }
+                  {
+                    SELECT ?country_cat (COUNT(?holiday) as 
?celebrate_Chinese_New_Year) WHERE {
+                        ?country_cat 
<http://www.w3.org/2004/02/skos/core#broader> 
<http://dbpedia.org/resource/Category:Public_holidays_by_country>.
+                        ?holiday dcterms:subject ?country_cat
+                        
FILTER(?holiday="http://dbpedia.org/resource/Lunar_New_Year's_Day")
+                    } GROUP by ?country_cat
+                  }
+                }
+                """;
         test_roundTripQuery(queryString);
     }
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestSyntaxTransform.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestSyntaxTransform.java
index 1c93d54e9d..f05e19c005 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestSyntaxTransform.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestSyntaxTransform.java
@@ -96,6 +96,27 @@ public class TestSyntaxTransform
                 "s", "<urn:ex:z>");
     }
 
+    // GH-2650
+    @Test public void subst_query_31() {
+        testQuery("PREFIX : <http://example/> SELECT (SUM(?a + ?b) AS ?c) 
WHERE { ?s :p ?a }",
+                  "PREFIX : <http://example/> SELECT (SUM(123 + ?b) AS ?c) 
WHERE { ?s :p 123 }",
+                  "a", "123");
+    }
+
+    // GH-2650
+    @Test public void subst_query_32() {
+        testQuery("PREFIX : <http://example/> SELECT (SUM(?a + ?b) AS ?c) 
WHERE { }",
+                  "PREFIX : <http://example/> SELECT (SUM(123 + ?b) AS ?c) 
WHERE { }",
+                  "a", "123");
+    }
+
+    // GH-2650
+    @Test public void subst_query_33() {
+        testQuery("SELECT * WHERE { ?s ?p ?o { SELECT (count(?a) as ?C) WHERE 
{} } }",
+                  "SELECT * WHERE { ?s ?p ?o { SELECT (count(123) as ?C) WHERE 
{} } }",
+                  "a", "123");
+    }
+
     // Same except use the Model API.
     @Test public void subst_query_model_2() {
         testQueryModel("SELECT * { ?s ?p ?o } ORDER BY ?s",

Reply via email to