Hi Jeff,
as posted a few weeks ago, SPIN RDF syntax does not support sub-
selects yet. Maybe this is what you are experiencing here?
Holger
On May 28, 2009, at 11:14 AM, Schmitz, Jeffrey A wrote:
>
> For some reason, I'm having trouble executing the "sub-query" sparql
> query using the SPIN api. Even after simplifying the query to remove
> the LET and the SPIN function, the query with sub-queries doesn't
> return
> results when it should.
>
> Specifically, when I execute the following query in my code using the
> SPIN API, as well as when I execute it from the TBC SPARQL tab, it
> works
> correctly:
>
> SELECT ?value
> WHERE {?user a ModelManagement:User .
> ?user ModelManagement:firstName ?value
> }
>
> However, when I execute the following, I think logically equivalent
> query, I get no results:
>
> SELECT ?value
> {
> {SELECT ?user
> WHERE {
> ?user a ModelManagement:User .
> }
> }
> {SELECT ?user ?value
> WHERE {
> ?user ModelManagement:firstName ?value
> }
> }
> }
>
> This query does work correctly from the TBC SPARQL tab, and I can also
> run this query in my code using just the jena/arq API and it works
> correctly.
>
> I've pasted below the code I use to execute the queries using the SPIN
> API, which seems to work for most cases. I have a feeling there's a
> more concise way to do this, but that's a topic for another post...
>
> //Create the ARQ Query from the SPARQL string.
> arqQuery = QueryFactory.create(sparqlStr,
> Syntax.syntaxARQ);
>
> //Get the ARQ2SPIN utility, specifying model to be
> queried.
> ARQ2SPIN a2s = new
> ARQ2SPIN(modelManagementInst.memModel);
>
> //Create a SPIN query from the ARQ Query
> org.topbraid.spin.model.Query spinQuery =
> a2s.createQuery(arqQuery,
> null);
>
> //Wrap up both queries in a SPIN wrapper.
> QueryWrapper wrapper = null;
> String ruleText = null;
> if (spinQuery != null) {
> StringPrintContext p = new StringPrintContext();
> spinQuery.print(p);
> if (ruleText == null) {
> ruleText = p.getString();
> }
> arqQuery =
> ARQFactory.get().createQuery(modelManagementInst.memModel,
>
> p.getStringBuilder().toString());
> wrapper = new QueryWrapper(arqQuery, ruleText,
> spinQuery,
> ruleText);
> }
>
> //Get the arq query from the wrapper
> arqQuery = wrapper.getQuery();
>
> //Get the query execution
> QueryExecution selQe =
> ARQFactory.get().createQueryExecution(
> arqQuery,
> modelManagementInst.memModel);
>
> //Execute it
> ResultSet rs = selQe.execSelect();
>
>
>> -----Original Message-----
>> From: Schmitz, Jeffrey A
>> Sent: Thursday, May 28, 2009 11:06 AM
>> To: [email protected]
>> Subject: [tbc-users] Re: [SPIN] Using FILTER with function arguments
>>
>>
>> No, that's not working in this case...
>>
>> SELECT ?user ?value
>> WHERE {
>> LET(?user := :getProjectUser("DEFAULT_PROJECT", "xxx"))
>> FILTER (bound(?user)) ?user :firstName ?value }
>>
>> Still returns everything with a firstName property.
>>
>>> -----Original Message-----
>>> From: Holger Knublauch [mailto:[email protected]]
>>> Sent: Thursday, May 28, 2009 10:22 AM
>>> To: [email protected]
>>> Subject: [tbc-users] Re: [SPIN] Using FILTER with function arguments
>>>
>>>
>>> Jeff,
>>>
>>> wouldn't it be sufficient to add a FILTER bound(?var) after the
>>> function call?
>>>
>>> Holger
>>>
>>>
>>> On May 28, 2009, at 7:06 AM, Schmitz, Jeffrey A wrote:
>>>
>>>>
>>>> "The function returns no binding and therefore ?user is
>> unbound and
>>>> will be iterating over all possible subjects of the firstName
>>>> triples."
>>>>
>>>> Hmmm, not what I was expecting. I guess I would have
>>> expected it to
>>>> act more like normal SPARQL variable chaining occurrs,
>> e.g. in the
>>>> following
>>>> query:
>>>>
>>>> SELECT ?user ?value
>>>> WHERE {?user a :NonExistantClass .
>>>> ?user :firstName ?value}
>>>>
>>>> ?user is "unbound" after the first line (NonExistantClass doesn't
>>>> really exist), and this query returns no results instead of
>>> everything
>>>> in the model with a firstName property. Even if you reverse the
>>>> order:
>>>>
>>>> SELECT ?user ?value
>>>> WHERE {?user :firstName ?value .
>>>> ?user a :NonExistantClass .
>>>> }
>>>>
>>>> You still get no results. But change it to something like:
>>>>
>>>> SELECT ?user ?value
>>>> WHERE {(LET ?user := :filterOnClass(:NonExistantClass)
>>>> ?user :firstName ?value}
>>>>
>>>> And you do get everything in the model with a firstName property.
>>>>
>>>> Be that as it may, using subqueries I think I'm able to get the
>>>> behavior I'm looking for. A little verbose, but if I understand
>>>> things, I think you'd have to do this anytime you wanted to use a
>>>> re-usable SPIN filtering function:
>>>>
>>>>
>>>> SELECT ?user ?value
>>>> {
>>>> {SELECT ?user
>>>> WHERE {
>>>> LET(?user :=
>>>> ModelManagement:getProjectUser("DEFAULT_PROJECT",
>>>> "xxx"))
>>>> }
>>>> }
>>>> {SELECT ?user ?value
>>>> WHERE {
>>>> ?user ModelManagement:firstName ?value
>>>> }
>>>> }
>>>> }
>>>>
>>>> In the above query, if the user specified in the LET
>> (xxx) doesn't
>>>> exist, nothing is returned.
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Holger Knublauch [mailto:[email protected]]
>>>>> Sent: Wednesday, May 27, 2009 9:38 PM
>>>>> To: [email protected]
>>>>> Subject: [tbc-users] Re: [SPIN] Using FILTER with function
>>> arguments
>>>>>
>>>>>
>>>>>
>>>>> On May 27, 2009, at 12:21 PM, Schmitz, Jeffrey A wrote:
>>>>>
>>>>>>
>>>>>> It's getting curiousor and curiousor...
>>>>>>
>>>>>> Using the TBC SPARQL tab, when I call a function that filters
>>>>>> according to an argument, e.g.:
>>>>>>
>>>>>> SELECT ?user
>>>>>> WHERE {
>>>>>> ?project ModelManagement:hasUser ?user .
>>>>>> ?user Common:name ?username .
>>>>>> FILTER (?username = ?arg1) .
>>>>>> }
>>>>>
>>>>> If the function returns no binding then it will be
>> comparable to a
>>>>> wildcard in the query below.
>>>>>
>>>>>>
>>>>>>
>>>>>> As long as I pass in an argument that has a match:
>>>>>>
>>>>>> SELECT ?value
>>>>>> WHERE {LET(?user := ModelManagement:getProjectUser("john"))
>>>>>> ?user ModelManagement:firstName ?value}
>>>>>>
>>>>>> the function returns just one result as expected (in this
>>> case for
>>>>>> some reason the blank result rows aren't returned).
>>> However, if I
>>>>>> pass in a value that has NO matches:
>>>>>>
>>>>>> SELECT ?value
>>>>>> WHERE {LET(?user := ModelManagement:getProjectUser("xxx"))
>>>>>> ?user ModelManagement:firstName ?value}
>>>>>>
>>>>>>
>>>>>> It acts like the FILTER statement isn't there, and all
>>>>> User's names in
>>>>>> the model are returned. I would have expected no results to be
>>>>>> returned. Btw, I'm seeing this same behavior in my code
>>> too. Am I
>>>>>> thinking about this wrong, or is there perhaps a
>> problem with how
>>>>>> FILTER works within a Function?
>>>>>
>>>>> No, the behavior is correct (as far as I understand your
>> example).
>>>>> The function returns no binding and therefore ?user is
>> unbound and
>>>>> will be iterating over all possible subjects of the firstName
>>>>> triples.
>>>>>
>>>>> In your first email, please keep in mind that the
>>> execution order of
>>>>> ARQ might be different from what you have typed it. In
>>> particular, I
>>>>> find often that LET statements are executed at the end,
>>> and therefore
>>>>> lead to more iterations than expected.
>>>>>
>>>>> Holger
>>>>>
>>>>>
>>>>>>
>>>>>
>>>>
>>>>>
>>>
>>>
>>>>
>>>
>>
>>>
>>
>
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TopBraid Composer Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/topbraid-composer-users?hl=en
-~----------~----~----~----~------~----~------~--~---