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 d5f72d2ab2cd618dea298356d2e9e59d2b5feed8
Author: Andy Seaborne <[email protected]>
AuthorDate: Mon Jan 13 21:45:53 2025 +0000

    GH-2799: Return substitutions -- QueryTransformOps.syntaxSubstitute
---
 .../org/apache/jena/http/sys/ExecHTTPBuilder.java  |   2 +-
 .../org/apache/jena/sparql/core/VarExprList.java   |  11 ++
 .../jena/sparql/exec/QueryExecDatasetBuilder.java  |   2 +-
 .../syntaxtransform/QueryScopeException.java}      |  23 ++--
 .../QuerySyntaxSubstituteScope.java                | 116 ++++++++++++++++++++
 .../syntax/syntaxtransform/QueryTransformOps.java  |  66 ++++++++++--
 .../org/apache/jena/riot/system/TS_RiotSystem.java |   3 -
 .../org/apache/jena/sparql/syntax/TS_Syntax.java   |  24 +++--
 .../apache/jena/sparql/syntax/TestQueryParser.java |  30 +++---
 .../jena/sparql/syntax/TestSerialization.java      |   8 +-
 .../syntax/syntaxtransform/TestFlattenSyntax.java  |  38 +++----
 ...TestQueryOps.java => TestQueryShallowCopy.java} |   7 +-
 .../syntaxtransform/TestQuerySubstituteScope.java  | 111 +++++++++++++++++++
 .../syntaxtransform/TestQuerySyntaxSubstitute.java | 120 +++++++++++++++++++++
 ...ransform.java => TestQuerySyntaxTransform.java} |  61 +++++------
 .../shacl/engine/constraint/SparqlValidation.java  |   2 +-
 .../apache/jena/shacl/validation/EvalSparql.java   |   2 +-
 17 files changed, 518 insertions(+), 108 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/http/sys/ExecHTTPBuilder.java 
b/jena-arq/src/main/java/org/apache/jena/http/sys/ExecHTTPBuilder.java
index 9c3b032d44..a7b3f6c471 100644
--- a/jena-arq/src/main/java/org/apache/jena/http/sys/ExecHTTPBuilder.java
+++ b/jena-arq/src/main/java/org/apache/jena/http/sys/ExecHTTPBuilder.java
@@ -328,7 +328,7 @@ public abstract class ExecHTTPBuilder<X, Y> {
                     throw new QueryException("Substitution only supported for 
Query objects. Failed to parse the given string as a Query object.", e);
                 }
             }
-            queryActual = QueryTransformOps.transform(queryActual, 
substitutionMap);
+            queryActual = QueryTransformOps.replaceVars(queryActual, 
substitutionMap);
             queryStringActual = queryActual.toString();
         }
         Context cxt = contextAcc.context();
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/core/VarExprList.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/core/VarExprList.java
index 185eb23f25..7a6f1d7f09 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/VarExprList.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/VarExprList.java
@@ -158,6 +158,17 @@ public class VarExprList {
         exprs.remove(var);
     }
 
+    /**
+     * If the variable is already in the VarExprList, replace the expression.
+     * This retains the list order.
+     * Otherwise, add the variable and expression.
+     */
+    public void update(Var var, Expr newExpr) {
+        exprs.put(var, newExpr);
+        if ( ! vars.contains(var) )
+            vars.add(var);
+    }
+
     public void clear() {
         vars.clear();
         exprs.clear();
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDatasetBuilder.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDatasetBuilder.java
index f028893669..42e2dcf7f5 100644
--- 
a/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDatasetBuilder.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/exec/QueryExecDatasetBuilder.java
@@ -204,7 +204,7 @@ public class QueryExecDatasetBuilder implements 
QueryExecMod, QueryExecBuilder {
         String queryStringActual = queryString;
 
         if ( substitutionMap != null && ! substitutionMap.isEmpty() ) {
-            queryActual = QueryTransformOps.transform(query, substitutionMap);
+            queryActual = QueryTransformOps.replaceVars(query, 
substitutionMap);
             queryStringActual = null;
         }
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryScopeException.java
similarity index 57%
copy from jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java
copy to 
jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryScopeException.java
index 91764e2432..a49547a7ba 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QueryScopeException.java
@@ -16,22 +16,11 @@
  * limitations under the License.
  */
 
-package org.apache.jena.sparql.syntax;
+package org.apache.jena.sparql.syntax.syntaxtransform;
 
-import org.apache.jena.sparql.syntax.syntaxtransform.TestFlattenSyntax ;
-import org.apache.jena.sparql.syntax.syntaxtransform.TestQueryOps ;
-import org.apache.jena.sparql.syntax.syntaxtransform.TestQuerySyntaxTransform ;
-import org.junit.runner.RunWith ;
-import org.junit.runners.Suite ;
-import org.junit.runners.Suite.SuiteClasses ;
+import org.apache.jena.query.QueryException;
 
-@RunWith(Suite.class)
-@SuiteClasses( {
-    TestQueryParser.class
-    , TestSerialization.class
-    , TestQueryOps.class
-    , TestQuerySyntaxTransform.class
-    , TestFlattenSyntax.class
-})
-
-public class TS_Syntax {}
+public class QueryScopeException extends QueryException {
+    public QueryScopeException(String msg) { super(msg) ; }
+    public QueryScopeException(String msg, Throwable cause) { super(msg, 
cause) ; }
+}
diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QuerySyntaxSubstituteScope.java
 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QuerySyntaxSubstituteScope.java
new file mode 100644
index 0000000000..923396daab
--- /dev/null
+++ 
b/jena-arq/src/main/java/org/apache/jena/sparql/syntax/syntaxtransform/QuerySyntaxSubstituteScope.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.syntax.syntaxtransform;
+
+import java.util.Collection;
+
+import org.apache.jena.query.Query;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.core.VarExprList;
+import org.apache.jena.sparql.syntax.*;
+
+/**
+ *  Variable usage check for {@link QueryTransformOps#transform}.
+ */
+public class QuerySyntaxSubstituteScope {
+
+    /**
+     * Check that the query can be transformed by replacing the variables with 
values.
+     * For example, an assigned variables ({@code AS ?var}) can not be replace 
by a value.
+     */
+    public static void scopeCheck(Query query, Collection<Var> vars) {
+        checkLevel(query, vars);
+        checkPattern(query.getQueryPattern(), vars);
+    }
+
+    public static void checkPattern(Element element, Collection<Var> vars) {
+        ElementVisitor visitor = new SubstituteScopeVisitor(vars);
+        ElementWalker.walk(element, visitor);
+    }
+
+    private static void checkLevel(Query query, Collection<Var> vars) {
+        checkAssignments("Query project expression", vars, query.getProject());
+        checkAssignments("GROUP BY ", vars, query.getGroupBy());
+        query.getAggregators().forEach(agg->{
+            checkAssignment("Aggregator", vars, agg.getVar());
+        });
+    }
+
+    private static void checkAssignments(String context, Collection<Var> vars, 
VarExprList varExprList) {
+        varExprList.forEachVarExpr((v,e)->{
+            if ( e != null )
+                checkAssignment(context, vars, v);
+        });
+    }
+
+    private static void checkAssignment(String context, Collection<Var> vars, 
Var assignedVar) {
+        if ( vars.contains(assignedVar) )
+            reject("BIND", assignedVar);
+    }
+
+    private static void reject(String elementName, Var badVar) {
+        throw new QueryScopeException("Can not use "+badVar+" in this query");
+    }
+
+    private static class SubstituteScopeVisitor  extends ElementVisitorBase {
+
+        private Collection<Var> vars;
+
+        SubstituteScopeVisitor(Collection<Var> vars) {
+            this.vars = vars;
+        }
+
+        // BOUND(?x) with no ?x in scope.
+//    @Override
+//    public void visit(ElementFilter el)         {
+//        Set<Var> mentioned = el.getExpr().getVarsMentioned();
+//        // EXISTS
+//    }
+
+        @Override
+        public void visit(ElementAssign el)         {
+            Var assignedVar = el.getVar();
+            checkAssignment("LET", vars, assignedVar);
+        }
+
+        @Override
+        public void visit(ElementBind el) {
+            Var assignedVar = el.getVar();
+            checkAssignment("BIND", vars, assignedVar);
+        }
+
+        @Override
+        public void visit(ElementData el)           {
+            var assignedVars = el.getVars();
+            assignedVars.forEach(v->checkAssignment("VALUES", vars, v));
+        }
+
+//    @Override
+//    public void visit(ElementExists el)         { }
+//
+//    @Override
+//    public void visit(ElementNotExists el)      { }
+
+        @Override
+        public void visit(ElementSubQuery el)       {
+            // Check project
+            el.getQuery().getQueryPattern().visit(this);
+        }
+    }
+}
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 b4f987a3bf..34081c0fae 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
@@ -18,6 +18,8 @@
 
 package org.apache.jena.sparql.syntax.syntaxtransform;
 
+import static 
org.apache.jena.sparql.syntax.syntaxtransform.QuerySyntaxSubstituteScope.scopeCheck;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -43,24 +45,73 @@ import org.apache.jena.sparql.syntax.*;
 
 /** Support for transformation of query abstract syntax. */
 public class QueryTransformOps {
-    /** Transform a query based on a mapping from {@link Var} variable to 
replacement {@link Node}. */
+
+    /**
+     * Replace variables in a query by RDF terms.
+     * The replacements are added to the return queries SELECT clause (if a 
SELECT query).
+     * <p>
+     * @throws QueryScopeException if the query contains variables used in a
+     *   way that does not allow substitution (.e.g {@code AS ?var} or used in
+     *   {@code VALUES}).
+     */
+    public static Query syntaxSubstitute(Query input, Map<Var, Node> 
substitutions) {
+        scopeCheck(input, substitutions.keySet());
+        Query output = transformTopLevel(input, substitutions);
+        return output;
+    }
+
+    // Call transform, add in the substitutions as top-level SELECT 
expressions/
+    private static Query transformTopLevel(Query query, Map<Var, Node> 
substitutions) {
+        Query query2 = transformSubstitute(query, substitutions);
+        // Include substitutions
+        if ( query.isSelectType() ) {
+            query2.setQueryResultStar(false);
+            substitutions.forEach((v, n) -> {
+                var nv = NodeValue.makeNode(n);
+                query2.getProject().update(v, NodeValue.makeNode(n));
+            });
+        }
+        return query2;
+    }
+
+    /** @deprecated Use {@link #queryReplaceVars} */
+    @Deprecated
     public static Query transform(Query query, Map<Var, ? extends Node> 
substitutions) {
-        ElementTransform eltrans = new ElementTransformSubst(substitutions);
-        NodeTransform nodeTransform = new NodeTransformSubst(substitutions);
-        ExprTransform exprTrans = new ExprTransformNodeElement(nodeTransform, 
eltrans);
-        return transform(query, eltrans, exprTrans);
+        return replaceVars(query, substitutions);
+    }
+
+    /** Transform a query based on a mapping from {@link Var} variable to 
replacement {@link Node}. */
+    public static Query replaceVars(Query query, Map<Var, ? extends Node> 
substitutions) {
+        return transformSubstitute(query, substitutions);
+    }
+
+
+    /** @deprecated Use {@link #queryReplaceVars} */
+    @Deprecated
+    public static Query transformQuery(Query query, Map<String, ? extends 
RDFNode> substitutions)    {
+        return queryReplaceVars(query, substitutions);
     }
 
     /**
      * Transform a query based on a mapping from variable name to replacement
      * {@link RDFNode} (a {@link Resource} (or blank node) or a {@link 
Literal}).
      */
-    public static Query transformQuery(Query query, Map<String, ? extends 
RDFNode> substitutions) {
+    public static Query queryReplaceVars(Query query, Map<String, ? extends 
RDFNode> substitutions) {
         // Must have a different name because of Java's erasure of 
parameterised types.
         Map<Var, Node> map = TransformElementLib.convert(substitutions);
-        return transform(query, map);
+        return replaceVars(query, map);
+    }
+
+    private static Query transformSubstitute(Query query, Map<Var, ? extends 
Node> substitutions) {
+        scopeCheck(query, substitutions.keySet());
+        ElementTransform eltrans = new ElementTransformSubst(substitutions);
+        NodeTransform nodeTransform = new NodeTransformSubst(substitutions);
+        ExprTransform exprTrans = new ExprTransformNodeElement(nodeTransform, 
eltrans);
+        return transform(query, eltrans, exprTrans);
     }
 
+    // ----------------
+
     /**
      * Transform a query using {@link ElementTransform} and {@link 
ExprTransform}.
      * It is the responsibility of these transforms to transform to a legal 
SPARQL query.
@@ -68,7 +119,6 @@ public class QueryTransformOps {
     public static Query transform(Query query, ElementTransform transform, 
ExprTransform exprTransform) {
         Query q2 = QueryTransformOps.shallowCopy(query);
         // Mutate the q2 structures which are already allocated and no other 
code can access yet.
-
         mutateByQueryType(q2, exprTransform);
         mutateVarExprList(q2.getGroupBy(), exprTransform);
         mutateExprList(q2.getHavingExprs(), exprTransform);
diff --git 
a/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java 
b/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
index b796647e77..097202a815 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/system/TS_RiotSystem.java
@@ -18,9 +18,6 @@
 
 package org.apache.jena.riot.system;
 
-
-
-// 2024-10 Using Junit5 can confuse Eclipse testing.
 // Test classes get missed
 import org.junit.platform.suite.api.SelectClasses;
 import org.junit.platform.suite.api.Suite;
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java
index 91764e2432..4394c0e035 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TS_Syntax.java
@@ -18,19 +18,25 @@
 
 package org.apache.jena.sparql.syntax;
 
-import org.apache.jena.sparql.syntax.syntaxtransform.TestFlattenSyntax ;
-import org.apache.jena.sparql.syntax.syntaxtransform.TestQueryOps ;
-import org.apache.jena.sparql.syntax.syntaxtransform.TestQuerySyntaxTransform ;
-import org.junit.runner.RunWith ;
-import org.junit.runners.Suite ;
-import org.junit.runners.Suite.SuiteClasses ;
+import org.junit.platform.suite.api.SelectClasses;
+import org.junit.platform.suite.api.Suite;
 
-@RunWith(Suite.class)
-@SuiteClasses( {
+import org.apache.jena.sparql.syntax.syntaxtransform.*;
+
+@Suite
+@SelectClasses({
+
+//import org.junit.runner.RunWith;
+//import org.junit.runners.Suite;
+//import org.junit.runners.Suite.SuiteClasses;
+//@RunWith(Suite.class)
+//@SuiteClasses({
     TestQueryParser.class
     , TestSerialization.class
-    , TestQueryOps.class
+    , TestQueryShallowCopy.class
+    , TestQuerySubstituteScope.class
     , TestQuerySyntaxTransform.class
+    , TestQuerySyntaxSubstitute.class
     , TestFlattenSyntax.class
 })
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestQueryParser.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestQueryParser.java
index 8e25334fc2..4b93c8dcca 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestQueryParser.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestQueryParser.java
@@ -18,11 +18,14 @@
 
 package org.apache.jena.sparql.syntax;
 
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
 import org.apache.jena.atlas.logging.LogCtl;
 import org.apache.jena.query.QueryFactory;
 import org.apache.jena.query.QueryParseException;
 import org.apache.jena.sparql.lang.QueryParserBase;
-import org.junit.Test;
 import org.slf4j.Logger;
 
 /**
@@ -49,34 +52,33 @@ public class TestQueryParser {
         testParseIRIs("<http://[::1]/abc>");
     }
 
-    @Test(expected = QueryParseException.class)
+    @Test
     public void syntax_uri_brace_1() {
-        testParseIRIs("<http://example/{}>");
+        assertThrows(QueryParseException.class, 
()->testParseIRIs("<http://example/{}>"));
     }
 
-    @Test(expected = QueryParseException.class)
-    public void syntax_uri_brace_2() {
-        testParseIRIs("<http://example/#{}>");
+    @Test public void syntax_uri_brace_2() {
+        assertThrows(QueryParseException.class, 
()->testParseIRIs("<http://example/#{}>"));
     }
 
-    @Test(expected = QueryParseException.class)
+    @Test
     public void syntax_uri_space_1() {
-        testParseIRIs("<http://example/abc def>");
+        assertThrows(QueryParseException.class, 
()->testParseIRIs("<http://example/abc def>"));
     }
 
-    @Test(expected = QueryParseException.class)
+    @Test
     public void syntax_uri_space_2() {
-        testParseIRIs("<http://example/abc?q= def>");
+        assertThrows(QueryParseException.class, 
()->testParseIRIs("<http://example/abc?q= def>"));
     }
 
-    @Test(expected = QueryParseException.class)
+    @Test
     public void syntax_uri_space_3() {
-        testParseIRIs("< http://example/abc>");
+        assertThrows(QueryParseException.class, ()->testParseIRIs("< 
http://example/abc>"));
     }
 
-    @Test(expected = QueryParseException.class)
+    @Test
     public void syntax_uri_space_4() {
-        testParseIRIs("<http://example/abc >");
+        assertThrows(QueryParseException.class, 
()->testParseIRIs("<http://example/abc >"));
     }
 
     // Test that a URI string can be used in Turtle data
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestSerialization.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestSerialization.java
index 6efb1eaef4..ba3b0f1eba 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestSerialization.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/TestSerialization.java
@@ -18,7 +18,12 @@
 
 package org.apache.jena.sparql.syntax;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.junit.jupiter.api.Test;
 
 import org.apache.jena.query.Query ;
 import org.apache.jena.query.QueryFactory ;
@@ -29,7 +34,6 @@ import org.apache.jena.sparql.algebra.Op ;
 import org.apache.jena.sparql.algebra.OpAsQuery ;
 import org.apache.jena.sparql.sse.SSE ;
 import org.apache.jena.sparql.util.FmtUtils ;
-import org.junit.Test ;
 
 public class TestSerialization
 {
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestFlattenSyntax.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestFlattenSyntax.java
index cbf28f0afd..204284b2df 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestFlattenSyntax.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestFlattenSyntax.java
@@ -18,19 +18,21 @@
 
 package org.apache.jena.sparql.syntax.syntaxtransform;
 
-import static org.junit.Assert.assertEquals;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
 
 import org.apache.jena.query.Query ;
 import org.apache.jena.query.QueryFactory ;
 import org.apache.jena.query.Syntax ;
 import org.apache.jena.sparql.algebra.Algebra ;
 import org.apache.jena.sparql.algebra.Op ;
-import org.junit.Test ;
 
 public class TestFlattenSyntax {
     static String PRE = "PREFIX : <http://example/>\n" ;
-    
-    @Test public void test_flatten_basic_01() 
+
+    @Test public void test_flatten_basic_01()
     { test(":s0 :p :o .", null) ; }
 
     @Test public void test_flatten_basic_02()
@@ -42,7 +44,7 @@ public class TestFlattenSyntax {
     @Test public void test_flatten_basic_04()
     { test("{{{ :s3 :p :o }}}", ":s3 :p :o") ;  }
 
-    @Test public void test_flatten_filter_01() 
+    @Test public void test_flatten_filter_01()
     { test(":s0 :p :o .{FILTER(?x)}", null) ; }
 
     @Test public void test_flatten_fileter_02()
@@ -53,19 +55,19 @@ public class TestFlattenSyntax {
 
     @Test public void test_flatten_optional_01()
     { test("OPTIONAL{ ?s1 :q ?z }", null) ;  }
-    
+
     @Test public void test_flatten_optional_02()
     { test("OPTIONAL{{?s2 :q ?z}}", "OPTIONAL{?s2 :q ?z}") ;  }
-    
+
     @Test public void test_flatten_optional_03()
     { test("OPTIONAL{?s1f :q ?z FILTER(?z) }", null) ;  }
-    
+
     @Test public void test_flatten_optional_04()
     { test("OPTIONAL{{?S2 :q ?z FILTER(?z) }}", null);  }
-    
+
     @Test public void test_flatten_optional_05()
     { test("OPTIONAL{{{?S3 :q ?z FILTER(?z) }}}", "OPTIONAL{{?S3 :q ?z 
FILTER(?z) }}") ; }
-    
+
     @Test public void test_flatten_optional_06()
     { test("OPTIONAL{?sx :q ?z {FILTER(?z)} }", null) ;  }
 
@@ -74,7 +76,7 @@ public class TestFlattenSyntax {
 
     @Test public void test_flatten_pattern_02()
     { test("{{?s :q ?z}} UNION {?s :q ?z }", "{?s :q ?z} UNION {?s :q ?z }") ; 
 }
-    
+
     @Test public void test_flatten_pattern_03()
     { test("{ ?s :q ?z} UNION {{?s :q ?z}}", "{?s :q ?z} UNION {?s :q ?z }") ; 
 }
 
@@ -92,26 +94,26 @@ public class TestFlattenSyntax {
 
     @Test public void test_flatten_arq_02()
     { test("EXISTS {{ :s :p :o }}", "EXISTS { :s :p :o }") ;  }
-    
+
     private static void test(String input, String expected) {
         if ( expected == null )
             expected = input ;
         String qs = gen(PRE, input) ;
         String qsExpected = gen(PRE, expected) ;
-        
+
         Query query = QueryFactory.create(qs, Syntax.syntaxARQ) ;
         Query query2 = QueryTransformOps.transform(query, new 
ElementTransformCleanGroupsOfOne()) ;
         Query queryExpected = QueryFactory.create(qsExpected, 
Syntax.syntaxARQ) ;
-        
+
         Op op1 = Algebra.compile(query) ;
         Op op2 = Algebra.compile(query2) ;
-        assertEquals("Algebra different", op1, op2) ;
-        
+        assertEquals(op1, op2, "Algebra different") ;
+
         boolean modified = ! query.equals(query2) ;
         boolean expectModification = !queryExpected.equals(query) ;
-        assertEquals("Expect query modifed?", expectModification, modified) ;
+        assertEquals(expectModification, modified, "Expect query modifed?") ;
     }
-    
+
     private static String gen(String PRE, String string) {
         return PRE+"\nSELECT * { "+string+"\n}" ;
     }
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryOps.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryShallowCopy.java
similarity index 94%
rename from 
jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryOps.java
rename to 
jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryShallowCopy.java
index 0604b5fca7..740a961313 100644
--- 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryOps.java
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQueryShallowCopy.java
@@ -18,13 +18,14 @@
 
 package org.apache.jena.sparql.syntax.syntaxtransform;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
 
-import org.junit.Test ;
 import org.apache.jena.query.Query ;
 import org.apache.jena.query.QueryFactory ;
 
-public class TestQueryOps
+public class TestQueryShallowCopy
 {
     @Test public void queryOp_01() { testShallowCopy("SELECT * { }") ; }
 
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySubstituteScope.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySubstituteScope.java
new file mode 100644
index 0000000000..55aa5183a1
--- /dev/null
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySubstituteScope.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.syntax.syntaxtransform;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+
+import org.junit.jupiter.api.Test;
+
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.sparql.core.Var;
+
+/**
+ * Variable usage for {@link QueryTransformOps}.
+ */
+public class TestQuerySubstituteScope {
+
+    private Var varX = Var.alloc("X");
+    private Var varY = Var.alloc("Y");
+    private Var varZ = Var.alloc("Z");
+
+    @Test public void valid_scope_01() {
+        testScopeRestriction("SELECT * {}");
+    }
+
+    @Test public void valid_scope_02() {
+        testScopeRestriction("SELECT * {}", varX);
+    }
+
+    @Test public void valid_scope_03() {
+        testScopeRestriction("SELECT * { ?s ?p ?X}", varX);
+    }
+
+    @Test public void valid_scope_04() {
+        testScopeRestriction("SELECT * { ?s ?p ?o BIND(123 AS ?n)}", varZ);
+    }
+
+    @Test public void valid_scope_05() {
+        testScopeRestriction("SELECT * { VALUES ?z { 123 } }", varZ);
+    }
+
+    @Test public void valid_scope_06() {
+        testScopeRestriction("SELECT * { VALUES ?z { 123 } } GROUP BY (str(?z) 
AS ?str)", varZ);
+    }
+
+    @Test public void valid_scope_07() {
+        testScopeRestriction("SELECT (?z + 1 AS ?z2) { VALUES ?z { 123 } }", 
varX);
+    }
+
+    @Test public void valid_scope_08() {
+        testScopeRestriction("SELECT ?X  { ?s ?p ?o }", varX);
+    }
+
+    @Test public void valid_scope_10() {
+        testScopeRestriction("SELECT * { ?s ?p ?o { SELECT ?X { ?a ?b ?c }}}", 
varX, varY, varZ);
+    }
+
+    // subquery
+
+    @Test public void invalid_scope_01() {
+        testScopeRestrictionBad("SELECT * { BIND(123 AS ?X) }", varX);
+    }
+
+    @Test public void invalid_scope_02() {
+        testScopeRestrictionBad("SELECT (123 AS ?X) { ?s ?p ?o }", varX);
+    }
+
+    @Test public void invalid_scope_03() {
+        testScopeRestrictionBad("SELECT * { VALUES ?X { 123 } ?s ?p ?o }", 
varX);
+    }
+
+    @Test public void invalid_scope_04() {
+        testScopeRestrictionBad("SELECT * { ?s ?p ?o } GROUP BY (str(?p) AS 
?X)", varX);
+    }
+
+    @Test public void invalid_scope_05() {
+        testScopeRestrictionBad("SELECT (count(*) as ?Z) { ?s ?p ?o } GROUP BY 
?s", varX, varY, varZ);
+    }
+
+    @Test public void invalid_scope_06() {
+        testScopeRestriction("SELECT * { ?s ?p ?o { SELECT (?c +1 AS ?X) { ?a 
?b ?c }}}", varX, varY, varZ);
+    }
+
+    private void testScopeRestriction(String queryString, Var...vars ) {
+        var query = QueryFactory.create(queryString);
+        var varsList = Arrays.asList(vars);
+        QuerySyntaxSubstituteScope.scopeCheck(query, varsList);
+    }
+
+    private void testScopeRestrictionBad(String queryString, Var...vars ) {
+        assertThrows(QueryScopeException.class, 
()->testScopeRestriction(queryString, vars));
+    }
+
+}
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxSubstitute.java
 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxSubstitute.java
new file mode 100644
index 0000000000..03af530ff9
--- /dev/null
+++ 
b/jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxSubstitute.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.syntax.syntaxtransform;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.sparql.core.Var;
+
+public class TestQuerySyntaxSubstitute {
+
+    private static Map<Var, Node> substitutions1 = Map.of(Var.alloc("x"), 
NodeFactory.createURI("http://example/xxx";));
+    private static Map<Var, Node> substitutions2 = Map.of(Var.alloc("x"), 
NodeFactory.createURI("http://example/xxx";),
+                                                          Var.alloc("y"), 
NodeFactory.createURI("http://example/yyy";));
+
+    @Test public void syntaxSubstitue_01() {
+        testSubstitue("SELECT * { ?x :p ?z }", substitutions1,
+                      "SELECT ?z (:xxx AS ?x) { :xxx :p ?z }"
+                      );
+    }
+
+    @Test public void syntaxSubstitue_02() {
+        testSubstitue("SELECT ?x { ?x :p ?z }", substitutions1,
+                      "SELECT (:xxx AS ?x) { :xxx :p ?z }"
+                      );
+    }
+
+    @Test public void syntaxSubstitue_03() {
+        testSubstitue("SELECT ?z { :a :p ?z }", substitutions1,
+                      "SELECT ?z (:xxx AS ?x) { :a :p ?z }"
+                      );
+    }
+
+    @Test public void syntaxSubstitue_04() {
+        testSubstitue("SELECT ?x ?z { ?x :p ?z }", substitutions1,
+                      "SELECT (:xxx AS ?x) ?z { :xxx :p ?z }"
+                      );
+    }
+
+    @Test public void syntaxSubstitue_10() {
+        testSubstitue("SELECT ?y ?x { ?x :p ?y }", substitutions2,
+                      "SELECT (:yyy AS ?y) (:xxx AS ?x) { :xxx :p :yyy }"
+                      );
+    }
+
+    @Test public void syntaxSubstitue_11() {
+        testSubstitue("SELECT ?y ?p ?x { ?x ?p ?y }", substitutions2,
+                      "SELECT (:yyy AS ?y) ?p (:xxx AS ?x) { :xxx ?p :yyy }"
+                      );
+    }
+
+    // GH-2799: Sub-queries not yet ready.
+//    // Sub-query visible variable.
+//    @Test public void syntaxSubstitue_12() {
+//        testSubstitue("SELECT * { ?s ?p ?o { SELECT ?x { ?x :p ?y } } }", 
substitutions1,
+//                      "SELECT (:yyy AS ?y) ?p (:xxx AS ?x) { ?s ?p ?o { 
SELECT * { :xxx :p ?y } }}"
+//                      );
+//    }
+//
+//    // Sub-query hidden variable.
+//    @Test public void syntaxSubstitue_13() {
+//        testSubstitue("SELECT * { ?s ?p ?o { SELECT ?y { ?x :p ?y } } }", 
substitutions1,
+//                      "SELECT ?s ?p ?o (:xxx AS ?x) { ?s ?p ?o { SELECT * { 
:xxx :p ?y } }}"
+//                      );
+//    }
+//
+//    // Multi-level variable.
+//    @Test public void syntaxSubstitue_14() {
+//        testSubstitue("SELECT * { ?x ?p ?o { SELECT * { ?x :p ?y } } }", 
substitutions2,
+//                      "" //"SELECT (:yyy AS ?y) ?p (:xxx AS ?x) { ?s ?p ?o { 
SELECT * { :xxx :p ?y } }}"
+//                      );
+//    }
+
+    @Test public void syntaxSubstitue_50() {
+        assertThrows(QueryScopeException.class, ()->
+            testSubstitue("SELECT (456 AS ?x) { ?y :p ?z }",  substitutions1,
+                          ""
+                          ));
+    }
+
+    @Test public void syntaxSubstitue_51() {
+        assertThrows(QueryScopeException.class, ()->
+            testSubstitue("SELECT * { ?y :p ?z BIND(789 AS ?x)}", 
substitutions1,
+                          ""
+                          ));
+    }
+
+    private void testSubstitue(String qs, Map<Var, Node> substitutions, String 
outcome) {
+        String prologue = "PREFIX : <http://example/> ";
+        String queryString = prologue+qs;
+        Query query = QueryFactory.create(queryString);
+        Query query2 = QueryTransformOps.syntaxSubstitute(query, 
substitutions);
+        Query queryOutcome = QueryFactory.create(prologue+outcome);
+        assertEquals(queryOutcome,  query2);
+    }
+}
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/TestQuerySyntaxTransform.java
similarity index 84%
rename from 
jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestSyntaxTransform.java
rename to 
jena-arq/src/test/java/org/apache/jena/sparql/syntax/syntaxtransform/TestQuerySyntaxTransform.java
index 510692c340..7c7e4cd8c2 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/TestQuerySyntaxTransform.java
@@ -18,11 +18,13 @@
 
 package org.apache.jena.sparql.syntax.syntaxtransform;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.HashMap;
 import java.util.Map;
 
+import org.junit.jupiter.api.Test;
+
 import org.apache.jena.graph.Node;
 import org.apache.jena.query.Query;
 import org.apache.jena.query.QueryFactory;
@@ -32,153 +34,152 @@ 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.junit.Test;
 
 /** Test of variable replaced by value */
 public class TestQuerySyntaxTransform
 {
-    @Test public void subst_query_01() {
+    @Test public void transformTransformReplace_01() {
         testQuery("SELECT * { }",
                   "SELECT * {}",
                   "o", "1"); }
 
-    @Test public void subst_query_02() {
+    @Test public void transformTransformReplace_02() {
         testQuery("SELECT ?x { }",
                   "SELECT ?x {}",
                   "o", "1"); }
 
-    @Test public void subst_query_03() {
+    @Test public void transformTransformReplace_03() {
         testQuery("SELECT ?o { }",
                   "SELECT (1 as ?o) {}",
                   "o", "1"); }
 
-    @Test public void subst_query_04() {
+    @Test public void transformTransformReplace_04() {
         testQuery("SELECT (?o AS ?z) { }",
                   "SELECT (1 AS ?z) {}",
                   "o", "1"); }
 
-    @Test public void subst_query_05() {
+    @Test public void transformTransformReplace_05() {
         testQuery("SELECT (?o+2 AS ?z) { }",
                   "SELECT (1+2 AS ?z) {}",
                   "o", "1");
     }
 
-    @Test public void subst_query_09() {
+    @Test public void transformTransformReplace_09() {
         testQuery("SELECT * {?s ?p ?o}",
                   "SELECT * {?s ?p 1}",
                   "o", "1");
     }
 
-    @Test public void subst_query_10() {
+    @Test public void transformTransformReplace_10() {
         testQuery("SELECT * { SELECT ?o {} }",
                   "SELECT * { SELECT (1 as ?o) {}}",
                   "o", "1");
     }
 
-    @Test public void subst_query_11() {
+    @Test public void transformTransformReplace_11() {
         testQuery("SELECT * { ?s ?p ?o { SELECT ?x { ?x ?p ?o } } }",
                   "SELECT * { ?s ?p 1  { SELECT ?x { ?x ?p 1 } } }",
                   "o", "1"); }
 
-    @Test public void subst_query_20() {
+    @Test public void transformTransformReplace_20() {
         testQuery("SELECT * { ?s ?p ?g GRAPH ?g { ?s ?p ?g } }",
                   "SELECT * { ?s ?p <urn:ex:graph> GRAPH <urn:ex:graph> { ?s 
?p <urn:ex:graph> } }",
                   "g", "<urn:ex:graph>"); }
 
-    @Test public void subst_query_21() {
+    @Test public void transformTransformReplace_21() {
         testQuery("SELECT * { ?s ?p ?srv SERVICE ?srv { ?s ?p ?srv}}",
                   "SELECT * { ?s ?p <urn:ex:service> SERVICE <urn:ex:service> 
{ ?s ?p <urn:ex:service>}}",
                   "srv", "<urn:ex:service>"); }
 
-    @Test public void subst_query_30() {
+    @Test public void transformTransformReplace_30() {
         testQuery("SELECT * { ?s ?p ?o } ORDER BY ?s",
                   "SELECT * { <urn:ex:z> ?p ?o } ORDER BY (<urn:ex:z>)",
                 "s", "<urn:ex:z>");
     }
 
     // GH-2650
-    @Test public void subst_query_31() {
+    @Test public void transformTransformReplace_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() {
+    @Test public void transformTransformReplace_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() {
+    @Test public void transformTransformReplace_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() {
+    @Test public void transformTransformReplace_model_2() {
         testQueryModel("SELECT * { ?s ?p ?o } ORDER BY ?s",
                        "SELECT * { <urn:ex:z> ?p ?o } ORDER BY (<urn:ex:z>)",
                        "s", "<urn:ex:z>");
     }
 
-    @Test public void subst_query_40() {
+    @Test public void transformTransformReplace_40() {
         testQueryModel("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }",
                        "CONSTRUCT { <urn:ex:z> ?p ?o } WHERE { <urn:ex:z> ?p 
?o }",
                        "s", "<urn:ex:z>");
     }
 
-    @Test public void subst_query_41() {
+    @Test public void transformTransformReplace_41() {
         testQueryModel("CONSTRUCTWHERE { ?s ?p ?o }",
                        "CONSTRUCT { <urn:ex:z> ?p ?o } WHERE { <urn:ex:z> ?p 
?o }",
                        "s", "<urn:ex:z>");
     }
 
-    @Test public void subst_query_42() {
+    @Test public void transformTransformReplace_42() {
         testQueryModel("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }",
                        "CONSTRUCT { <urn:ex:z> ?p 57 } WHERE { <urn:ex:z> ?p 
57 }",
                        "s", "<urn:ex:z>", "o", "57");
     }
 
-    @Test public void subst_query_43() {
+    @Test public void transformTransformReplace_43() {
         testQueryModel("CONSTRUCT { GRAPH ?g {?s ?p ?o } } WHERE { GRAPH ?g 
{?s ?p ?o } }",
                        "CONSTRUCT { GRAPH <urn:ex:g> { <urn:ex:z> ?p ?o } } 
WHERE { GRAPH <urn:ex:g> { <urn:ex:z> ?p ?o } }",
                        "s", "<urn:ex:z>", "g", "<urn:ex:g>");
     }
 
-    @Test public void subst_query_44() {
+    @Test public void transformTransformReplace_44() {
         testQueryModel("CONSTRUCTWHERE { GRAPH ?g {?s ?p ?o } }",
                        "CONSTRUCT { GRAPH <urn:ex:g> { <urn:ex:z> ?p ?o } } 
WHERE { GRAPH <urn:ex:g> { <urn:ex:z> ?p ?o } }",
                        "s", "<urn:ex:z>", "g", "<urn:ex:g>");
     }
 
-    @Test public void subst_update_01() {
+    @Test public void transformSubstituteupdate_01() {
         testUpdate("DELETE { ?s <urn:ex:p> ?x } WHERE {}",
                    "DELETE { ?s <urn:ex:p> <urn:ex:z> } WHERE {}",
                    "x", "<urn:ex:z>");
     }
 
-    @Test public void subst_update_02() {
+    @Test public void transformSubstituteupdate_02() {
         testUpdate("DELETE { ?s <urn:ex:p> ?x } WHERE { ?s <urn:ex:p> ?x }",
                    "DELETE { ?s <urn:ex:p> <urn:ex:z> } WHERE { ?s <urn:ex:p> 
<urn:ex:z> }",
                    "x", "<urn:ex:z>");
     }
 
-    @Test public void subst_update_03() {
+    @Test public void transformSubstituteupdate_03() {
         testUpdate("DELETE { ?s <urn:ex:p> ?x } INSERT { ?s <urn:ex:p> ?x } 
WHERE { ?s <urn:ex:p> ?x }",
                    "DELETE { ?s <urn:ex:p> <urn:ex:z> } INSERT { ?s <urn:ex:p> 
<urn:ex:z> } WHERE { ?s <urn:ex:p> <urn:ex:z> }",
                    "x", "<urn:ex:z>");
     }
 
-    @Test public void subst_update_09() {
+    @Test public void transformSubstituteupdate_09() {
         testUpdate("DELETE WHERE { ?s <urn:ex:p> ?x }",
                    "DELETE WHERE { ?s <urn:ex:p> <urn:ex:z> }",
                    "x", "<urn:ex:z>");
     }
 
-    @Test public void subst_update_10() {
+    @Test public void transformSubstituteupdate_10() {
         testUpdateModel("DELETE WHERE { ?s <urn:ex:p> ?x }",
                         "DELETE WHERE { ?s <urn:ex:p> <urn:ex:z> }",
                            "x", "<urn:ex:z>");
@@ -195,7 +196,7 @@ public class TestQuerySyntaxTransform
         Map<Var, Node> map = new HashMap<>();
         map.put(Var.alloc(varStr), SSE.parseNode(valStr));
 
-        Query qTrans = QueryTransformOps.transform(q1, map);
+        Query qTrans = QueryTransformOps.replaceVars(q1, map);
 
         if ( ! qExpected.equals(qTrans) ) {
             System.out.println(qExpected.getProject());
@@ -212,7 +213,7 @@ public class TestQuerySyntaxTransform
         Query qExpected = QueryFactory.create(PREFIX+output);
 
         Map<String, RDFNode> map = Map.of(varStr, fromString(valStr));
-        Query qTrans = QueryTransformOps.transformQuery(q1, map) ;
+        Query qTrans = QueryTransformOps.queryReplaceVars(q1, map) ;
         assertEquals(qExpected, qTrans) ;
     }
 
@@ -222,7 +223,7 @@ public class TestQuerySyntaxTransform
 
         Map<String, RDFNode> map = Map.of(varStr1, fromString(valStr1), 
varStr2, fromString(valStr2));
 
-        Query qTrans = QueryTransformOps.transformQuery(q1, map) ;
+        Query qTrans = QueryTransformOps.queryReplaceVars(q1, map) ;
         assertEquals(qExpected, qTrans) ;
 
     }
diff --git 
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
 
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
index 47f3dc4bc0..6f4a725010 100644
--- 
a/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
+++ 
b/jena-shacl/src/main/java/org/apache/jena/shacl/engine/constraint/SparqlValidation.java
@@ -115,7 +115,7 @@ import org.apache.jena.sparql.util.ModelUtils;
             Map<Var, Node> substitutions = 
parameterMapToSyntaxSubstitutions(parameterMap, focusNode, path);
             if ( query.isAskType() )
                 addSubstition(substitutions, "value", valueNode);
-            Query query2 = QueryTransformOps.transform(query, substitutions);
+            Query query2 = QueryTransformOps.replaceVars(query, substitutions);
             qExec = QueryExecutionFactory.create(query2, model);
         } else {
             // Done with pre-binding.
diff --git 
a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/EvalSparql.java 
b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/EvalSparql.java
index 26375f6027..67e6302d56 100644
--- a/jena-shacl/src/main/java/org/apache/jena/shacl/validation/EvalSparql.java
+++ b/jena-shacl/src/main/java/org/apache/jena/shacl/validation/EvalSparql.java
@@ -62,7 +62,7 @@ public class EvalSparql {
             // Done with QueryTransformOps.transform
             DatasetGraph dsg = DatasetGraphFactory.wrap(data);
             Map<Var, Node> substitutions = 
parametersToSyntaxSubstitutions(data, node, sparqlComponent.getParams());
-            Query query2 = QueryTransformOps.transform(query, substitutions);
+            Query query2 = QueryTransformOps.replaceVars(query, substitutions);
             try ( QueryExecution qExec = QueryExecutionFactory.create(query2, 
dsg)) {
                 return evalSparqlOneVar(qExec);
             }


Reply via email to