<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><DIV><DIV>On Mar 10, 2006, at 9:57 AM, Attilio Fiandrotti wrote:</DIV><BR class="Apple-interchange-newline"><BLOCKQUOTE type="cite"><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Hi</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">i ran some tests on the OPTIONAL matching using latest librdf, raptor and rasqal libraries from SVN with the two following SPARQL queries</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 1)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">PREFIX rdf: &lt;<A href="http://www.dajobe.org/foaf.rdf">http://www.dajobe.org/foaf.rdf</A>&gt; PREFIX foaf: &lt;<A href="http://xmlns.com/foaf/0.1/">http://xmlns.com/foaf/0.1/</A>&gt; PREFIX dc: &lt;<A href="http://purl.org/dc/elements/1.1/">http://purl.org/dc/elements/1.1/</A>&gt; SELECT ?name, ?depiction_title WHERE { ?x foaf:name ?name . ?x foaf:depiction ?y . OPTIONAL { ?y dc:title ?depiction_title } }</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 2)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">PREFIX rdf: &lt;<A href="http://www.dajobe.org/foaf.rdf">http://www.dajobe.org/foaf.rdf</A>&gt; PREFIX foaf: &lt;<A href="http://xmlns.com/foaf/0.1/">http://xmlns.com/foaf/0.1/</A>&gt; PREFIX dc: &lt;<A href="http://purl.org/dc/elements/1.1/">http://purl.org/dc/elements/1.1/</A>&gt; SELECT ?name, ?depiction_title WHERE { ?x foaf:name ?name . ?x foaf:depiction ?y . OPTIONAL { ?y dc:bad_tag ?depiction_title } }</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">(note the "bad_tag" in query 2, to simulate missing title predicate for the depiction)</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">And i executed both queries in different ways</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">* Via roqet</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 1) Correct output, all variables assigned</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 2) Correct output, ?depiction_title=NULL</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">* Via C# bindings</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 1) Correct output, all variables assigned</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 2) application crashed because ?depiction_title=NULL</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">* Via Python bindings</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 1) Correct output, all variables assigned</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Query 2) application crashed because ?depiction_title=NULL</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><BR></DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">Note that if the OPTIONAL keyword is removed, then Query 2 produces empty sets of result, but i never get crashes.</DIV><DIV style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">I suppose this is a bindings problem: is this analysis corect?</DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Hi Attilio,</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-style-span">You are correct, it is a bindings problem and I encountered it a while back in the Python bindings (also with unbound nodes in bindings results). I opened a bug back then (<A href="http://bugs.librdf.org/mantis/view.php?id=59">http://bugs.librdf.org/mantis/view.php?id=59</A>) and it has recently been fixed in CVS by Dave. I assume the same problem exists for the C# (and possibly other language) bindings, especially if I look at the relevant code (<A href="http://cvs.librdf.org/cvsweb/redland/bindings/csharp/QueryResults.cs?rev=1.9&view=auto">http://cvs.librdf.org/cvsweb/redland/bindings/csharp/QueryResults.cs?rev=1.9&amp;view=auto</A><B>):</B></SPAN></DIV><DIV><B><BR class="khtml-block-placeholder"></B></DIV><BLOCKQUOTE type="cite"><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>private Hashtable MakeResultsHash ()</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>{</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>Hashtable h = new Hashtable ();</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>int c = librdf_query_results_get_bindings_count (handle);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>for (int i = 0; i &lt; c; i++) {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>IntPtr iname = librdf_query_results_get_binding_name (handle, i);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>String name = Util.UTF8PtrToString (iname);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>IntPtr v = librdf_query_results_get_binding_value (handle, i);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>h.Add (name, new Node (v));</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>}</DIV><DIV><BR></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>return h;</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN><SPAN class="Apple-tab-span" style="white-space:pre">        </SPAN>}</DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><DIV>This is basically the same method as there is in the Python bindings, here there is no check whether IntPtr v is null or not, assuming an IntPtrcan be null in C# (never worked with it myself). What would be required here (and possibly in other places) is a null check on 'v' because most likely the Node constructor does not accept null values (same thing in Python). So to fix it something like the following has to be done:</DIV><DIV><BR class="khtml-block-placeholder"></DIV><BLOCKQUOTE type="cite"><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                </SPAN>private Hashtable MakeResultsHash ()</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                </SPAN>{</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                        </SPAN>Hashtable h = new Hashtable ();</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                        </SPAN>int c = librdf_query_results_get_bindings_count (handle);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                        </SPAN>for (int i = 0; i &lt; c; i++) {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>IntPtr iname = librdf_query_results_get_binding_name (handle, i);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>String name = Util.UTF8PtrToString (iname);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>IntPtr v = librdf_query_results_get_binding_value (handle, i);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>if (v == null) {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                        </SPAN>h.Add (name, null);</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>} else {</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                        </SPAN>h.Add (name, new Node (v));</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                                </SPAN>}</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                        </SPAN>}</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                        </SPAN>return h;</DIV><DIV><SPAN class="Apple-tab-span" style="white-space:pre">                </SPAN>}</DIV></BLOCKQUOTE><DIV><BR class="khtml-block-placeholder"></DIV><BLOCKQUOTE type="cite"></BLOCKQUOTE><DIV>I have no idea whether C# hashtables accept null values, and I have no idea whether v == null works at all, like I said, never worked with C# myself but I guess the solution is clear anyway. I'd check the other language bindings as well if I had the time for it, but I don't right now :/</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Regards,</DIV><DIV>-Arjan</DIV><BLOCKQUOTE type="cite"> </BLOCKQUOTE></DIV><BR></BODY></HTML>