Peter,

The bug is fixed and the fix will appear in the next release of Virtuoso
Open Source. For your convenience, the patch for this particlular bug
is in the attachment. The patch is for VOS 5.0.9 and not tested on
previous versions, including release candidates of VOS 5.0.9

Best Regards,

Ivan Mikhailov
OpenLink Software
http://virtuoso.openlinksw.com

On Sun, 2008-11-23 at 21:06 -0800, Peter Ansell wrote:
> Hi all,
> 
> I am not an expert of the semantics of how OPTIONAL works in SPARQL but I am 
> a little surprised at some results I am getting. I am executing the following 
> queries on a copy of the database which is normally at 
> http://go.bio2rdf.org/sparql although it is down at the moment.
> 
> No results query:
> 
> SELECT * WHERE {  GRAPH <http://bio2rdf.org/go> { OPTIONAL { 
> <http://go.bio2rdf.org/go:0032283> 
> <http://www.w3.org/2000/01/rdf-schema#label> ?label . } OPTIONAL { 
> <http://go.bio2rdf.org/go:0032283> <http://purl.org/dc/elements/1.1/title> 
> ?title . }  OPTIONAL { <http://go.bio2rdf.org/go:0032283> 
> <http://owl.bio2rdf.org/go#name> ?goName }  }  }
> 
> Results query:
> 
> SELECT * WHERE {  GRAPH <http://bio2rdf.org/go> { OPTIONAL { 
> <http://go.bio2rdf.org/go:0032283> <http://owl.bio2rdf.org/go#name> ?goName } 
>  }  }
> 
> The only difference between the queries is that I take out two of the 
> optional statements and it returns the result which should have matched in 
> the first one... Or am I doing something wrong? 
> 
> For reference, I am trying to efficiently seek a label for a given item 
> without knowing beforehand which predicate will be there, as the subject URI 
> is generated from a query on the bio2rdf software which in turn generates the 
> SPARQL query (I am actually using a CONSTRUCT internally but the behaviour is 
> the same as the SELECT)
> 
> Cheers,
> 
> Peter
> 
> 
> 
>       Start your day with Yahoo!7 and win a Sony Bravia TV. Enter now 
> http://au.docs.yahoo.com/homepageset/?p1=other&p2=au&p3=tagline
> 
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> Virtuoso-users mailing list
> Virtuoso-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/virtuoso-users
--- vos-5.0.9/libsrc/Wi/sparql2sqltext.c	2008-10-23 04:53:41.000000000 +0700
+++ vos-5.0.9-fix/libsrc/Wi/sparql2sqltext.c	2008-11-25 17:17:04.000000000 +0600
@@ -1159,25 +1159,27 @@
         }
       session_buffered_write (ses, mopen_hit, tail - mopen_hit);
     }
   res = strses_string (ses);
   dk_free_box (ses);
   tres = t_box_dv_short_string (res);
   dk_free_box (res);
   return tres;
 }
 
+#ifndef spar_sqlprint_error_impl
 void
 spar_sqlprint_error_impl (spar_sqlgen_t *ssg, const char *msg)
   {
     ssg_putchar ('!'); ssg_puts (msg); ssg_putchar ('!');
   }
+#endif
 
 void
 ssg_prin_id (spar_sqlgen_t *ssg, const char *name)
 {
 #if 0
   char tmp[1000 + 1];
 
   sprintf_escaped_id (name, tmp, NULL);
   ssg_puts (tmp);
 #else
@@ -6317,20 +6319,29 @@
           char buf[105]; /* potentialy 100 chars long see sparp_clone_id etc. */
           ssg_newline (0);
           snprintf (buf, sizeof (buf), "stub-%s", member->_.gp.selid);
           if (SSG_PRINT_UNION_NONEMPTY_STUB & head_flags)
             ssg_puts ("(SELECT TOP 1 1 AS __stub FROM DB.DBA.RDF_QUAD) AS ");
           else
             ssg_puts ("(SELECT TOP 1 1 AS __stub FROM DB.DBA.RDF_QUAD WHERE 0) AS ");
           ssg_prin_id (ssg, buf);
           goto end_of_table_list; /* see below */
         }
+      if (OPTIONAL_L == member->_.gp.members[0]->_.gp.subtype)
+        {
+          char buf[105]; /* potentialy 100 chars long see sparp_clone_id etc. */
+          ssg_newline (0);
+          snprintf (buf, sizeof (buf), "lojstub-%s", member->_.gp.selid);
+          ssg_puts ("(SELECT TOP 1 1 AS __stub FROM DB.DBA.RDF_QUAD) AS ");
+          ssg_prin_id (ssg, buf);
+          ssg_puts (" LEFT OUTER JOIN");
+        }
       for (itm_idx = 0; itm_idx < itm_count; itm_idx++)
         {
           SPART *itm = member->_.gp.members [itm_idx];
           ccaddr_t itm_alias;
           int itm_is_opt = 0;
           itm_alias = ssg_id_of_gp_or_triple (itm);
           first_tabexpn_itm_idx = itm_idx;
 #if 0
           ssg_puts (t_box_sprintf (100, " /* alias %s #%d */", itm_alias, first_tabexpn_itm_idx));
 #endif
@@ -6382,20 +6393,24 @@
                 }
               if (0 == ssg->ssg_where_l_printed)
                 ssg_puts ("1");
               ssg->ssg_indent--;
               ssg_puts (")");
               ssg->ssg_where_l_printed = save_where_l_printed;
               ssg->ssg_where_l_text = save_where_l_text;
             }
           prev_itm_alias = itm_alias;
         }
+      if (OPTIONAL_L == member->_.gp.members[0]->_.gp.subtype)
+        {
+          ssg_puts (" ON (1)");
+        }
 
 end_of_table_list: ;
       ssg->ssg_indent--;
       save_where_l_printed = ssg->ssg_where_l_printed;
       save_where_l_text = ssg->ssg_where_l_text;
       ssg->ssg_where_l_printed = 0;
       ssg->ssg_where_l_text = "\bWHERE";
       ssg->ssg_indent++;
       if ((0 == gp->_.gp.subtype) || (WHERE_L == gp->_.gp.subtype) || (1 >= itm_count))
         {

Reply via email to