- 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