Hello Aldo,
That's technically possible but the compilation may seriously differ
from expectations of an average developer.
The problem is that SQL is not a procedural language, but people tend to
write with some left-to-right order in mind, probably because they're
writing it in that direction. Magic predicate collide with this
illusion :)
Consider
sparql select * where { <urn:someperson> sql:fullname ?fullname .
?note <resulrce> ?fullname .
?note <text> ?note_text .
}
It will become, internally,
sparql select (sql:fullname(<urn:someperson>)) as ?fullname,
?note ?note_text
where { <urn:someperson> sql:fullname ?fullname .
?note <resource> `sql:fullname(<urn:someperson>)` .
?note <text> ?note_text .
}
That in turn will become
sparql select (sql:fullname(<urn:someperson>)) as ?fullname,
?note ?note_text
where { <urn:someperson> sql:fullname ?fullname .
?note <resource> ?tmp .
?note <text> ?note_text .
filter (?tmp = sql:fullname(<urn:someperson>))
}
Looks bad but the optimizer will make something meaningful. However that
will cause funny issues if ?fullname is used as an argument to next
magic predicate --- the longer chain the longer the expression at each
replacement.
What's really bad is
{ ?X special-predicate-1 ?val . ?Y special-predicate-2 ?val }
It masquerades the fact of full table scan. It looks like a plain join,
but it is as inefficient as Cartesian product of values X and Y with
non-optimizable filter (special-predicate-1(?X) =
special-predicate-2(?Y)).
I'd say that magic predicates will be useful if predicate is declared as
a function and its inverse. In that case the filter could become
(special-predicate-1(?X) = special-predicate-2(?Y))
or
(?X = special-predicate-1-INVERSE (special-predicate-2(?Y)))
or
(special-predicate-2-INVERSE(special-predicate-1(?X)) = ?Y)
depending on optimizer's decision.
I guess that this feature can be implemented not earlier than good
support of arbitrary inverse functions in the SQL optimizer. So this is
definitely not for Virtuoso 6.2, but maybe for some later release.
Best Regards,
Ivan Mikhailov
OpenLink Software
http://virtuoso.openlinksw.com
On Thu, 2010-06-17 at 16:57 -0400, Aldo Bucchi wrote:
> Hi,
>
> If I have the following procedure
>
> create procedure fullname( in uri varchar ) returns varchar {
> for ( sparql select bif:concat( ?name, ' ', ?lastname ) as ?fullname
> where { ?:uri foaf:name ?name ; foaf:lastName ?lastname } )
> do { return fullname ; }
> };
>
> I know I can do the following:
>
> sparql select (sql:fullname( ?person )) as ?fullname where { ... }
>
> But, any plans to implement the following way of calling the function?
>
> sparql select * where { <urn:someperson> sql:fullname ?fullname }
>
> Regards,
> A
>