You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Andy Seaborne <an...@apache.org> on 2014/09/01 10:34:22 UTC

Re: How to parse queries top-down?

On 01/09/14 06:40, Wei Zhang wrote:
> Hi All,
>
> I want to parse the SPARQL query and get every element of a query and all the features in order to rewrite the query. So I need to know all the triple patterns and their level in the query.
> For example, for a query like:
> select * where {
> { bgp1}
> UNION
> { bgp2.
>    bgp3}
> OPTIONAL
> { bgp4}
> }
> I want to get bgp1-4, and also the relationships between them. e.g.  bgp2 and bgp3 is the conjunctive relationship.  bgp1 and { bgp2. bgp3} are union relationship.
> Using algebra cannot get their relationships.

yes it can otherwise the query could not be executed.

SELECT  *
WHERE
   { {   { ?s1 ?p1 ?o1 }
       UNION
         { ?s2 ?p2 ?o2 .
           ?s3 ?p3 ?o3
         }
       OPTIONAL
         { ?s4 ?p4 ?o4 }
     }
   }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(leftjoin
   (union
     (bgp (triple ?s1 ?p1 ?o1))
     (bgp
       (triple ?s2 ?p2 ?o2)
       (triple ?s3 ?p3 ?o3)
     ))
   (bgp (triple ?s4 ?p4 ?o4)))

>
> Currently, I just decompose the first level as groups, then to find the pattern in each element:
>
>      Query query = QueryFactory.create(strQuery);
>      Element qp = query.getQueryPattern();
> List<Element> listElement = ((ElementGroup) qp).getElements();
>
>      for (int i = 0; i < listElement.size() ; i++){
>            Element e = listElement.get(i)
>           if  ( e instanceof ElementUnion) {...}
>           if (e instanceof ElementGroup){...}
>            ...
>       }
>
> But there are two problems:
>
> 1) I cannot get further level of elements.

You need to recusive call your inspection code.  It's need to do type 
testing every time there is an Element.

> Take the query example, {
> bgp2. bgp3} is considered as one element and cannot be decomposed
> further. But what I want is bgp2, bgp3 and their conjunctive relationship

It's an ElementPathBlock which has getPattern() to get the PathBlock 
whch has .getList()

Everything is a path (a triple is a path of one step) in the grammar. 
The algebra conversion sorts that out.

>
> 2) I cannot get subquery in this way. I found Andy said
> ElementSubQuery can be used to get subquery
> (https://www.mail-archive.com/dev@jena.apache.org/msg06993.html) but I
> cannot find more detailed documents or examples regarding to how to use
> ElementSubQuery.

Its easier to look at the code - the syntax tree isn't complicated  as 
it's just a datastructure with very little algorithm.

ElementSubQuery.getQuery() -> Query

then call recursively, you code for looking in a query.

	Andy

>
> Could anyone help on this or give me any reference to use ElementSubQuery?
>
> Thank you very much for your time and help!
>
> Best Regards,
> Wei Zhang
>


RE: How to parse queries top-down?

Posted by Wei Zhang <we...@adelaide.edu.au>.
Hi Andy,

Thank you very much for your help!

Best Regards,
Wei Zhang


-----Original Message-----
From: Andy Seaborne [mailto:andy@apache.org] 
Sent: Monday, 1 September 2014 6:04 PM
To: users@jena.apache.org
Subject: Re: How to parse queries top-down?

On 01/09/14 06:40, Wei Zhang wrote:
> Hi All,
>
> I want to parse the SPARQL query and get every element of a query and all the features in order to rewrite the query. So I need to know all the triple patterns and their level in the query.
> For example, for a query like:
> select * where {
> { bgp1}
> UNION
> { bgp2.
>    bgp3}
> OPTIONAL
> { bgp4}
> }
> I want to get bgp1-4, and also the relationships between them. e.g.  bgp2 and bgp3 is the conjunctive relationship.  bgp1 and { bgp2. bgp3} are union relationship.
> Using algebra cannot get their relationships.

yes it can otherwise the query could not be executed.

SELECT  *
WHERE
   { {   { ?s1 ?p1 ?o1 }
       UNION
         { ?s2 ?p2 ?o2 .
           ?s3 ?p3 ?o3
         }
       OPTIONAL
         { ?s4 ?p4 ?o4 }
     }
   }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (leftjoin
   (union
     (bgp (triple ?s1 ?p1 ?o1))
     (bgp
       (triple ?s2 ?p2 ?o2)
       (triple ?s3 ?p3 ?o3)
     ))
   (bgp (triple ?s4 ?p4 ?o4)))

>
> Currently, I just decompose the first level as groups, then to find the pattern in each element:
>
>      Query query = QueryFactory.create(strQuery);
>      Element qp = query.getQueryPattern(); List<Element> listElement = 
> ((ElementGroup) qp).getElements();
>
>      for (int i = 0; i < listElement.size() ; i++){
>            Element e = listElement.get(i)
>           if  ( e instanceof ElementUnion) {...}
>           if (e instanceof ElementGroup){...}
>            ...
>       }
>
> But there are two problems:
>
> 1) I cannot get further level of elements.

You need to recusive call your inspection code.  It's need to do type testing every time there is an Element.

> Take the query example, {
> bgp2. bgp3} is considered as one element and cannot be decomposed 
> further. But what I want is bgp2, bgp3 and their conjunctive 
> relationship

It's an ElementPathBlock which has getPattern() to get the PathBlock whch has .getList()

Everything is a path (a triple is a path of one step) in the grammar. 
The algebra conversion sorts that out.

>
> 2) I cannot get subquery in this way. I found Andy said 
> ElementSubQuery can be used to get subquery
> (https://www.mail-archive.com/dev@jena.apache.org/msg06993.html) but I 
> cannot find more detailed documents or examples regarding to how to 
> use ElementSubQuery.

Its easier to look at the code - the syntax tree isn't complicated  as it's just a datastructure with very little algorithm.

ElementSubQuery.getQuery() -> Query

then call recursively, you code for looking in a query.

	Andy

>
> Could anyone help on this or give me any reference to use ElementSubQuery?
>
> Thank you very much for your time and help!
>
> Best Regards,
> Wei Zhang
>