Rob Vesse created JENA-1275:
-------------------------------

             Summary: TransformScopeRename does the wrong thing with FILTER NOT 
EXISTS
                 Key: JENA-1275
                 URL: https://issues.apache.org/jira/browse/JENA-1275
             Project: Apache Jena
          Issue Type: Bug
          Components: ARQ
    Affects Versions: Jena 3.1.1
            Reporter: Rob Vesse


I have produced the following minimal query from an originally much larger 
query. When the optimise is applied to this it incorrectly double renames the 
variables inside of the {{FILTER NOT EXISTS}} clause leading to incorrect 
algebra.

Query:

{noformat}
SELECT ?triangles ?openTriplets
  {
    {
      #subQ2: calculate #open-triplets
      SELECT (COUNT(?x) as ?openTriplets)
      WHERE {
        ?x ?a ?y .
        ?y ?b ?z .
        FILTER NOT EXISTS {?z ?c ?x}
      }
    }
  }
{noformat}

Output:

{noformat}
(project (?triangles ?openTriplets)
  (project (?openTriplets)
    (extend ((?openTriplets ?/.0))
      (group () ((?/.0 (count ?/x)))
        (filter (notexists
                   (quadpattern (quad <urn:x-arq:DefaultGraphNode> ?//z ?//c 
?//x)))
          (quadpattern
            (quad <urn:x-arq:DefaultGraphNode> ?/x ?/a ?/y)
            (quad <urn:x-arq:DefaultGraphNode> ?/y ?/b ?/z)
          ))))))
{noformat}

Note that we apply the quad transformation prior to applying the optimiser. 

Strangely enough I cannot reproduce the problem using pure Jena command line 
tools i.e. {{qparse}} although I note from the code that it applies quad 
transformation after applying optimisation. This suggests that it is a bug in 
how TransformScopeRename applies to quad form algebra.

I can reproduce it with a unit test like so:

{noformat}
    @Test
    public void filter_not_exists_scoping_03() {
        //@formatter:off
        Op orig = SSE.parseOp(StrUtils.strjoinNL("(project (?triangles 
?openTriplets)",
                                       "  (project (?openTriplets)",
                                       "    (extend ((?openTriplets ?.0))",
                                       "      (group () ((?.0 (count ?x)))",
                                       "        (filter (notexists",
                                       "                   (quadpattern (quad 
<urn:x-arq:DefaultGraphNode> ?z ?c ?x)))",
                                       "          (quadpattern",
                                       "            (quad 
<urn:x-arq:DefaultGraphNode> ?x ?a ?y)",
                                       "            (quad 
<urn:x-arq:DefaultGraphNode> ?y ?b ?z)",
                                       "          ))))))"));
        Op expected = SSE.parseOp(StrUtils.strjoinNL("(project (?triangles 
?openTriplets)",
                "  (project (?openTriplets)",
                "    (extend ((?openTriplets ?/.0))",
                "      (group () ((?/.0 (count ?/x)))",
                "        (filter (notexists",
                "                   (quadpattern (quad 
<urn:x-arq:DefaultGraphNode> ?/z ?/c ?/x)))",
                "          (quadpattern",
                "            (quad <urn:x-arq:DefaultGraphNode> ?/x ?/a ?/y)",
                "            (quad <urn:x-arq:DefaultGraphNode> ?/y ?/b ?/z)",
                "          ))))))"));
        //@formatter:on
        
        Op transformed = TransformScopeRename.transform(orig);
        
        Assert.assertEquals(transformed, expected);
    }
    
    @Test
    public void filter_not_exists_scoping_04() {
        //@formatter:off
        Op orig = SSE.parseOp(StrUtils.strjoinNL(
                                       "  (project (?openTriplets)",
                                       "    (extend ((?openTriplets ?.0))",
                                       "      (group () ((?.0 (count ?x)))",
                                       "        (filter (notexists",
                                       "                   (quadpattern (quad 
<urn:x-arq:DefaultGraphNode> ?z ?c ?x)))",
                                       "          (quadpattern",
                                       "            (quad 
<urn:x-arq:DefaultGraphNode> ?x ?a ?y)",
                                       "            (quad 
<urn:x-arq:DefaultGraphNode> ?y ?b ?z)",
                                       "          )))))"));
        Op expected = SSE.parseOp(StrUtils.strjoinNL(
                "  (project (?openTriplets)",
                "    (extend ((?openTriplets ?.0))",
                "      (group () ((?.0 (count ?x)))",
                "        (filter (notexists",
                "                   (quadpattern (quad 
<urn:x-arq:DefaultGraphNode> ?z ?c ?x)))",
                "          (quadpattern",
                "            (quad <urn:x-arq:DefaultGraphNode> ?x ?a ?y)",
                "            (quad <urn:x-arq:DefaultGraphNode> ?y ?b ?z)",
                "          )))))"));
        //@formatter:on
        
        Op transformed = TransformScopeRename.transform(orig);
        
        Assert.assertEquals(transformed, expected);
    }
{noformat}

The first test fails while the second passes. This implies that you need 2 
levels of projection to hit the bug.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to