- From: Eric Prud'hommeaux <eric@w3.org>
- Date: Fri, 10 Dec 2004 19:14:18 -0500
- To: "Seaborne, Andy" <andy.seaborne@hp.com>
- Cc: public-rdf-dawg@w3.org
- Message-ID: <20041211001418.GA30414@w3.org>
On Fri, Dec 10, 2004 at 06:45:52PM +0000, Seaborne, Andy wrote:
>
>
>
> Eric Prud'hommeaux wrote:
> >In response to a thread on UNSAID in the comments list [1], I've
> >drafted a section on UNSAID [2]. Andy asked about implementing it on
> >an SQL-accessed triple store. I thought I'd share the answer with the
> >WG. I test for default negation by doing an outer join to the triple
> >in the positive and then constraining that part of that triple is
> >NULL:
> >
> >
> >CREATE TABLE holds (id INTEGER NOT NULL AUTO_INCREMENT,
> > s VARCHAR(80), p VARCHAR(80), o VARCHAR(80),
> > PRIMARY KEY(id));
> >
> >-- _:a foaf:name "Alice" .
> >-- _:a foaf:page <http://work.example/alice> .
> >-- _:a foaf:workplaceHomepage <http://work.example/alice> .
> >-- _:b foaf:name "Bob" .
> >-- _:c foaf:name "Eve" .
> >-- _:c foaf:page <http://isp.example/eve> .
> >-- _:c foaf:workplaceHomepage <http://work.example/eve> .
> >
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:name', '"Alice"');
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:page',
> >'<http://work.example/alice>');
> >INSERT INTO holds (s, p, o) VALUES ('_:a', 'foaf:workplaceHomepage',
> >'<http://work.example/alice>');
> >INSERT INTO holds (s, p, o) VALUES ('_:b', 'foaf:name', '"Bob"');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:name', '"Eve"');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:page',
> >'<http://isp.example/eve>');
> >INSERT INTO holds (s, p, o) VALUES ('_:c', 'foaf:workplaceHomepage',
> >'<http://work.example/eve>');
> >
> >-- SELECT ?name
> >-- WHERE ( ?x foaf:name ?name )
> >-- UNSAID ( ?x foaf:mbox ?mbox )
>
> That is query 1 from the doc but that runs on a different dataset.
>
> I'm guessing but I think the query should be:
>
> SELECT ?name
> WHERE ( ?x foaf:name ?name )
> UNSAID ( ?x foaf:page ?mbox )
>
> as the SQL below uses "foaf:page"
>
> >
> >SELECT h1.o AS name
> > FROM holds AS h1
> > LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
> > WHERE h1.p="foaf:name"
> > AND h2.o IS NULL
> >
> >-- +-------+
> >-- | name |
> >-- +-------+
> >-- | "Bob" |
> >-- +-------+
>
> I get this result set.
>
> If the order is reversed
>
> i.e.
>
> SELECT ?name
> WHERE UNSAID ( ?x foaf:page ?mbox )
> ( ?x foaf:name ?name )
>
> I get:
> --------
> | name |
> ========
> --------
>
> because the UNSAID has a more general pattern (?mbox is unbound so any
> person with foaf:page is rejected - that's all of them).
>
> (My query processor executes query in the order written at the moment).
>
> >
> >-- SELECT ?name ?homepage
> >-- WHERE ( ?x foaf:name ?name )
> >-- OPTIONAL { ( ?x foaf:page ?homepage )
> >-- UNSAID ( ?x foaf:workplaceHomepage ?homepage ) }
> >
> >SELECT h1.o AS name, h2.o AS homepage
> > FROM holds AS h1
> > LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
> > LEFT OUTER JOIN holds AS h3 ON h3.s=h1.s AND
> > h3.p="foaf:workplaceHomepage" AND h2.o=h3.o
> > WHERE h1.p="foaf:name"
> > AND h3.o IS NULL
> >
> >-- +-------+--------------------------+
> >-- | name | homepage |
> >-- +-------+--------------------------+
> >-- | "Bob" | NULL |
> >-- | "Eve" | <http://isp.example/eve> |
> >-- +-------+--------------------------+
>
> This is query 2 from the doc on the second dataset.
>
> I get:
>
> --------------------------------------
> | name | homepage |
> ======================================
> | "Bob" | |
> | "Alice" | |
> | "Eve" | <http://isp.example/eve> |
> --------------------------------------
>
> which is different because I get a "Alice" row.
>
> ( ?x foaf:name ?name )
>
> gets all three people.
>
>
> Then,
> _:a foaf:page <http://work.example/alice>
> matches the first triple pattern of the optional:
> ( ?x foaf:page ?homepage )
> with ?homepage = <http://work.example/alice>
>
> Then for the UNSAID
> _:a foaf:workplaceHomepage <http://work.example/alice>
> exists, UNSAID is false, reject OPTIONAL. But that leaves ?name = "Alice"
>
> I expect:
> ( ?x foaf:name ?name ) OPTIONAL anything
> to pick ?name = "Alice" (and "Bob" and "Eve").
>
> What ever is in "anything" does not influence outside the OPTIONAL.
>
> What am I missing?
The fact that I screwed up and didn't try it:
eric@unagi:~/sources/public/perl/modules/W3C/Rdf/bin$ ./algae @../test/SPARQL-UNSAID-1-alg.sh
+-------+------------------------+
| name| homepage|
|-------|------------------------|
| "Bob"| NULL|
|"Alice"| NULL|
| "Eve"|<http://isp.example/eve>|
+-------+------------------------+
yeah, SQL for this requires thinking of the UNSAID as part of the
OPTIONAL (which I should have picked up before) and moving the
constraint to the report clause, e.g.
SELECT h1.o AS name, if (h2.o=h3.o, NULL, h2.o) AS homepage
FROM holds AS h1
LEFT OUTER JOIN holds AS h2 ON h2.s=h1.s AND h2.p="foaf:page"
LEFT OUTER JOIN holds AS h3 ON h3.s=h1.s AND h3.p="foaf:workplaceHomepage" AND h2.o=h3.o
WHERE h1.p="foaf:name";
+---------+--------------------------+
| name | homepage |
+---------+--------------------------+
| "Alice" | NULL |
| "Bob" | NULL |
| "Eve" | <http://isp.example/eve> |
+---------+--------------------------+
> >[1]
> >http://lists.w3.org/Archives/Public/public-rdf-dawg-comments/2004Nov/thread.html#16
> >[2] http://www.w3.org/2001/sw/DataAccess/rq23/#unsaid
>
--
-eric
office: +81.466.49.1170 W3C, Keio Research Institute at SFC,
Shonan Fujisawa Campus, Keio University,
5322 Endo, Fujisawa, Kanagawa 252-8520
JAPAN
+1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA
cell: +1.857.222.5741 (does not work in Asia)
(eric@w3.org)
Feel free to forward this message to any list for any purpose other than
email address distribution.
Received on Saturday, 11 December 2004 00:14:20 UTC