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 a3d10a79c2 Make Node and ExprTransform affect OpPropFunc arguments
a3d10a79c2 is described below
commit a3d10a79c297c9f3aa34a904c7b926d5fa0ccf60
Author: Claus Stadler <[email protected]>
AuthorDate: Wed Jun 18 16:38:02 2025 +0200
Make Node and ExprTransform affect OpPropFunc arguments
---
.../algebra/walker/ApplyTransformVisitor.java | 52 ++++++++++++++++++++++
.../algebra/walker/OpVisitorByTypeAndExpr.java | 3 ++
.../java/org/apache/jena/sparql/expr/ExprLib.java | 14 ++++++
.../jena/sparql/algebra/TestNodeTransform.java | 25 +++++++++++
4 files changed, 94 insertions(+)
diff --git
a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
index 0e9ae51129..cfa29ba325 100644
---
a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
+++
b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/ApplyTransformVisitor.java
@@ -22,6 +22,7 @@ import java.util.* ;
import org.apache.jena.atlas.lib.InternalErrorException ;
import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.graph.Node ;
import org.apache.jena.query.SortCondition ;
import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.OpVisitor ;
@@ -30,7 +31,9 @@ import org.apache.jena.sparql.algebra.op.* ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.core.VarExprList ;
import org.apache.jena.sparql.expr.* ;
+import org.apache.jena.sparql.expr.NodeValue ;
import org.apache.jena.sparql.expr.aggregate.Aggregator ;
+import org.apache.jena.sparql.pfunction.PropFuncArg ;
/** Apply the {@link Transform}, {@link ExprTransform}
* Works in conjunction with {@link WalkerVisitor}.
@@ -335,6 +338,55 @@ public class ApplyTransformVisitor implements
OpVisitorByTypeAndExpr, ExprVisito
push(opStack, f.apply(opTransform, subOp)) ;
}
+ protected PropFuncArg visitPropFuncArg(PropFuncArg arg) {
+ ExprList in = arg.asExprList() ;
+ ExprList out = collect(in);
+
+ PropFuncArg result;
+ if (out.equals(in)) {
+ result = arg;
+ } else {
+ if (arg.isNode()) {
+ Node n = ExprLib.exprToNode(out.get(0));
+ result = new PropFuncArg(n);
+ } else {
+ List<Node> nodes =
out.getList().stream().map(ExprLib::exprToNode).toList();
+ result = new PropFuncArg(nodes);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void visit(OpPropFunc opPropFunc) {
+ Op outSubOp = null;
+ Op inSubOp = opPropFunc.getSubOp();
+ if (inSubOp != null) {
+ outSubOp = pop(opStack);
+ }
+
+ // This logic would also rename the function name
+ // (update OpVistorByTypeAndExpr to put the name onto the stack).
+ // List<Expr> opProperty = collect(1);
+ // Node inP = opPropFunc.getProperty();
+ // Node outP = ExprLib.exprToNode(opProperty.get(0));
+
+ Node outP = opPropFunc.getProperty();
+
+ PropFuncArg inS = opPropFunc.getSubjectArgs();
+ PropFuncArg outS = visitPropFuncArg(inS);
+
+ PropFuncArg inO = opPropFunc.getObjectArgs();
+ PropFuncArg outO = visitPropFuncArg(inO);
+
+ OpPropFunc f = opPropFunc;
+ if (inS != outS || inO != outO || inSubOp != outSubOp /* || inP !=
outP */) {
+ f = new OpPropFunc(outP, outS, outO, outSubOp);
+ }
+
+ push(opStack, f.apply(opTransform, outSubOp)) ;
+ }
+
@Override
public void visit(OpLeftJoin op) {
Op left = null ;
diff --git
a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
index 99afca5eb2..aeaf697a45 100644
---
a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
+++
b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/walker/OpVisitorByTypeAndExpr.java
@@ -94,6 +94,9 @@ public interface OpVisitorByTypeAndExpr extends OpVisitor
@Override
public default void visit(OpPropFunc opPropFunc) {
+ visitExpr(opPropFunc.getObjectArgs().asExprList());
+ visitExpr(opPropFunc.getSubjectArgs().asExprList());
+ // visitExpr(new
ExprList(ExprLib.nodeToExpr(opPropFunc.getProperty())));
visit1(opPropFunc);
}
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 70cbc57abb..63ce8e1ec3 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
@@ -224,6 +224,20 @@ public class ExprLib
return NodeValue.makeNode(n);
}
+ /**
+ * Go from an expression to a node.
+ * If the argument cannot be converted to a node then an {@link
IllegalArgumentException} is raised.
+ */
+ public static Node exprToNode(Expr e) {
+ if (e.isConstant()) {
+ return e.getConstant().asNode();
+ } else if (e.isVariable()) {
+ return e.getExprVar().asVar();
+ } else {
+ throw new IllegalArgumentException("Cannot convert Expression to
Node: " + e);
+ }
+ }
+
public static Expr rewriteTriple(Triple t) {
Expr e1 = nodeToExpr(t.getSubject());
Expr e2 = nodeToExpr(t.getPredicate());
diff --git
a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestNodeTransform.java
b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestNodeTransform.java
index ac359b00b5..5e8f867c2c 100644
---
a/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestNodeTransform.java
+++
b/jena-arq/src/test/java/org/apache/jena/sparql/algebra/TestNodeTransform.java
@@ -20,6 +20,7 @@ package org.apache.jena.sparql.algebra;
import static org.junit.Assert.assertEquals;
+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;
@@ -109,4 +110,28 @@ public class TestNodeTransform {
? Var.alloc(n.getName() + "ZZZ")
: n;
};
+
+ @Test
+ public void transformPropFunc() {
+ Op inOp = SSE.parseOp("""
+ (propfunc <urn:p>
+ <urn:x> ("y" ?z)
+ (table unit))
+ """);
+
+ // Property function name is not affected by node transform.
+ Op expectedOp = SSE.parseOp("""
+ (propfunc <urn:p>
+ <URN:X> ("Y" ?Z)
+ (table unit))
+ """);
+
+ Op actualOp = NodeTransformLib.transform(x ->
+ x.isURI() ? NodeFactory.createURI(x.getURI().toUpperCase()) :
+ x.isVariable() ? Var.alloc(x.getName().toUpperCase()) :
+ x.isLiteral() ?
NodeFactory.createLiteralString(x.getLiteralLexicalForm().toUpperCase()) :
+ x, inOp);
+
+ assertEquals(expectedOp, actualOp);
+ }
}