Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE in OpAsQuery #2883

Open
Aklakan opened this issue Dec 7, 2024 · 3 comments · May be fixed by #2884
Open

NPE in OpAsQuery #2883

Aklakan opened this issue Dec 7, 2024 · 3 comments · May be fixed by #2884
Labels

Comments

@Aklakan
Copy link
Contributor

Aklakan commented Dec 7, 2024

Version

5.3.0-SNAPSHOT

What happened?

The following query fails an OpAsQuery roundtrip due to an NPE:

@Test
public void testAlgebra04() {
    String queryStr = """
        SELECT * {
          LATERAL {
              SELECT * {
                ?s a ?t
                FILTER EXISTS { SELECT * { ?s a ?c } }
              } LIMIT 1
          }
        }
        """;
    test_roundTripAlegbra(queryStr, Syntax.syntaxARQ);
  }

image

Relevant output and stacktrace

java.lang.NullPointerException: Cannot invoke "org.apache.jena.sparql.expr.ExprTransform.transform(org.apache.jena.sparql.expr.ExprVar)" because "exprTransform" is null
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.transformVarExprList(QueryTransformOps.java:238)
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.mutateVarExprList(QueryTransformOps.java:208)
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.mutateByQueryType(QueryTransformOps.java:143)
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.transform(QueryTransformOps.java:72)
	at org.apache.jena.sparql.syntax.syntaxtransform.ApplyElementTransformVisitor.visit(ApplyElementTransformVisitor.java:222)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:200)
	at org.apache.jena.sparql.syntax.ElementSubQuery.visit(ElementSubQuery.java:52)
	at org.apache.jena.sparql.syntax.ElementWalker.walk(ElementWalker.java:37)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.applyTransformation(ElementTransformer.java:80)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:74)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:65)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transform(ElementTransformer.java:57)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transform(ElementTransformer.java:47)
	at org.apache.jena.sparql.syntax.syntaxtransform.ExprTransformApplyElementTransform.transform(ExprTransformApplyElementTransform.java:46)
	at org.apache.jena.sparql.expr.ExprFunctionOp.apply(ExprFunctionOp.java:86)
	at org.apache.jena.sparql.algebra.walker.ApplyTransformVisitor.visit(ApplyTransformVisitor.java:426)
	at org.apache.jena.sparql.expr.ExprFunctionOp.visit(ExprFunctionOp.java:85)
	at org.apache.jena.sparql.algebra.walker.WalkerVisitor.visit(WalkerVisitor.java:279)
	at org.apache.jena.sparql.expr.ExprFunctionOp.visit(ExprFunctionOp.java:85)
	at org.apache.jena.sparql.algebra.walker.WalkerVisitor.walk(WalkerVisitor.java:91)
	at org.apache.jena.sparql.algebra.walker.Walker.walk$(Walker.java:104)
	at org.apache.jena.sparql.algebra.walker.Walker.walk$(Walker.java:100)
	at org.apache.jena.sparql.algebra.walker.Walker.walk(Walker.java:95)
	at org.apache.jena.sparql.algebra.walker.Walker.transform(Walker.java:211)
	at org.apache.jena.sparql.algebra.walker.Walker.transform(Walker.java:200)
	at org.apache.jena.sparql.algebra.walker.Walker.transform(Walker.java:194)
	at org.apache.jena.sparql.expr.ExprTransformer.transform(ExprTransformer.java:27)
	at org.apache.jena.sparql.syntax.syntaxtransform.ApplyElementTransformVisitor.transformExpr(ApplyElementTransformVisitor.java:241)
	at org.apache.jena.sparql.syntax.syntaxtransform.ApplyElementTransformVisitor.visit(ApplyElementTransformVisitor.java:77)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:75)
	at org.apache.jena.sparql.syntax.ElementFilter.visit(ElementFilter.java:35)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:121)
	at org.apache.jena.sparql.syntax.ElementGroup.visit(ElementGroup.java:120)
	at org.apache.jena.sparql.syntax.ElementWalker.walk(ElementWalker.java:37)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.applyTransformation(ElementTransformer.java:80)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:74)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:65)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transform(ElementTransformer.java:52)
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.mutateQueryPattern(QueryTransformOps.java:90)
	at org.apache.jena.sparql.syntax.syntaxtransform.QueryTransformOps.transform(QueryTransformOps.java:77)
	at org.apache.jena.sparql.syntax.syntaxtransform.ApplyElementTransformVisitor.visit(ApplyElementTransformVisitor.java:222)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:200)
	at org.apache.jena.sparql.syntax.ElementSubQuery.visit(ElementSubQuery.java:52)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:121)
	at org.apache.jena.sparql.syntax.ElementGroup.visit(ElementGroup.java:120)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:139)
	at org.apache.jena.sparql.syntax.ElementLateral.visit(ElementLateral.java:59)
	at org.apache.jena.sparql.syntax.ElementWalker$EltWalker.visit(ElementWalker.java:121)
	at org.apache.jena.sparql.syntax.ElementGroup.visit(ElementGroup.java:120)
	at org.apache.jena.sparql.syntax.ElementWalker.walk(ElementWalker.java:37)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.applyTransformation(ElementTransformer.java:80)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:74)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transformation(ElementTransformer.java:65)
	at org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer.transform(ElementTransformer.java:52)
	at org.apache.jena.sparql.algebra.OpAsQuery$Converter.fixupGroupsOfOne(OpAsQuery.java:438)
	at org.apache.jena.sparql.algebra.OpAsQuery$Converter.processQueryPattern(OpAsQuery.java:409)
	at org.apache.jena.sparql.algebra.OpAsQuery$Converter.convertInner(OpAsQuery.java:229)
	at org.apache.jena.sparql.algebra.OpAsQuery$Converter.convert(OpAsQuery.java:207)
	at org.apache.jena.sparql.algebra.OpAsQuery.asQuery(OpAsQuery.java:81)
	at org.apache.jena.sparql.algebra.TestOpAsQuery.queryToQuery(TestOpAsQuery.java:674)
	at org.apache.jena.sparql.algebra.TestOpAsQuery.test_roundTripAlegbra(TestOpAsQuery.java:650)
	at org.apache.jena.sparql.algebra.TestOpAsQuery.testAlgebra04(TestOpAsQuery.java:574)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)

Are you interested in making a pull request?

Yes

@Aklakan Aklakan added the bug label Dec 7, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 7, 2024
@Aklakan Aklakan linked a pull request Dec 7, 2024 that will close this issue
3 tasks
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 8, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 8, 2024
@afs
Copy link
Member

afs commented Dec 8, 2024

The example has several moving parts:

  @Test
  public void testSubQuery01() {
      test_roundTripQuery("SELECT ?z { SELECT ?x {  } }");
  }

focuses on the subquery part.

Aklakan added a commit to Aklakan/jena that referenced this issue Dec 8, 2024
@Aklakan
Copy link
Contributor Author

Aklakan commented Dec 9, 2024

The example has several moving parts: [...]

I added your query to the PR but it was not failing before.

The issue seems to be related to (NOT) EXISTS.

I found more strange things going on (tested with the PR applied which only passes on an expr transform which otherwise might result in NPE):

# TestOpAsQuery.java

    @Test
    public void testExists08a() {
        String queryStr = """
            SELECT * {
              FILTER NOT EXISTS { SELECT * { ?s a ?t } LIMIT 2 }
            }
            """;
        Query inputQuery = QueryFactory.create(queryStr);
        Op op = Algebra.compile(inputQuery);
        System.out.println("Original Op: " + op);
        // Output looks OK to me:
        // (filter (notexists
        //            (slice _ 2
        //              (bgp (triple ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?t))))
        //   (table unit))

        Query queryFromOriginalOp = OpAsQuery.asQuery(op);
        System.out.println("Query from original op: " + queryFromOriginalOp);        
        // Output looks OK to me - Note that an empty graph pattern was injected but that should be fine:
        // SELECT  * WHERE { {  }
        //   FILTER NOT EXISTS { SELECT  * WHERE { ?s  a  ?t } LIMIT   2 } }

        Op parsedOp = SSE.parseOp(op.toString());
        System.out.println("Parse op " + parsedOp);        
        // Output looks OK to me:
        // (filter (notexists
        //            (slice _ 2
        //              (bgp (triple ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?t))))
        //   (table unit))

        Query queryFromParsedOp = OpAsQuery.asQuery(parsedOp);
        System.out.println("Query from parsed op: " + queryFromParsedOp);
        // Now there is a warning and the SLICE 2 got lost
        // WARN  ElementTransformer :: Attempt to transform a null element - ignored
        // Query from parsed op: SELECT  *
        // WHERE
        //   { {  }
        //     FILTER NOT EXISTS { ?s  a  ?t }
        //   }
    }

😮

So something seems to break with the Op/Element duality in ExprFunctionOp.

Also:

    @Test
    public void testExists08b() {
        String opStr = """
            (filter (notexists
                      (slice _ 2
                        (bgp (triple ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?t))))
              (table unit)
            )
            """;
        test_AlgebraToQuery(opStr, "SELECT * { { } FILTER NOT EXISTS { SELECT * { ?s a ?t } LIMIT 2 } }");
    }

gives

java.lang.NullPointerException: Cannot invoke "org.apache.jena.sparql.syntax.Element.equals(Object)" because the return value of "org.apache.jena.sparql.expr.E_NotExists.getElement()" is null
	at org.apache.jena.sparql.expr.E_NotExists.equals(E_NotExists.java:88)
	at org.apache.jena.sparql.expr.ExprNode.equalsBySyntax(ExprNode.java:82)
	at org.apache.jena.sparql.syntax.ElementFilter.equalTo(ElementFilter.java:48)
	at org.apache.jena.sparql.syntax.ElementGroup.equalTo(ElementGroup.java:113)
	at org.apache.jena.sparql.core.QueryCompare.visitQueryPattern(QueryCompare.java:122)
	at org.apache.jena.query.Query.visit(Query.java:757)
	at org.apache.jena.sparql.core.QueryCompare.equals(QueryCompare.java:44)
	at org.apache.jena.query.Query.equals(Query.java:826)
	at org.junit.Assert.isEquals(Assert.java:133)
	at org.junit.Assert.equalsRegardingNull(Assert.java:129)
	at org.junit.Assert.assertEquals(Assert.java:112)
	at org.junit.Assert.assertEquals(Assert.java:146)
	at org.apache.jena.sparql.algebra.TestOpAsQuery.test_AlgebraToQuery(TestOpAsQuery.java:716)
	at org.apache.jena.sparql.algebra.TestOpAsQuery.testExists08c(TestOpAsQuery.java:548)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)

Aklakan added a commit to Aklakan/jena that referenced this issue Dec 10, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 10, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 11, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 11, 2024
Aklakan added a commit to Aklakan/jena that referenced this issue Dec 11, 2024
@Aklakan
Copy link
Contributor Author

Aklakan commented Dec 11, 2024

The aforementioned issue #2883 (comment) should now be fixed in the proposed PR.

Aklakan added a commit to Aklakan/jena that referenced this issue Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants