Describe the bug
The spec for the fn:doc function says that the processor should raise an error if the URI passed in via the $uri parameter cannot be retrieved.
eXist does not raise an error.
Expected behavior
The spec says:
A dynamic error is raised
err:FODC0002if the resource cannot be retrieved or cannot be parsed successfully as XML.
That error is defined as follows:
Raised by
fn:doc,fn:collection, andfn:uri-collectionto indicate that either the supplied URI cannot be dereferenced to obtain a resource, or the resource that is returned is not parseable as XML.
Given a query like doc("foo") (where doc-available("foo") returns false()), Saxon raises an I/O error and BaseX raises the expected FODC0002 error:
Stopped at /Users/joe/workspace/file, 1/4: [FODC0002] Resource '/Users/joe/workspace/foo' does not exist.
Only eXist fails to raise an error. It returns an empty sequence.
To Reproduce
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare
%test:assertError("err:FODC0002")
function t:test() {
doc("foo")
};
Context (please always complete the following information):
Additional context
conf.xml? noneI could imagine this fix breaking a lot of stuff that's out there ;-) So maybe a 6.0.0
I agree with 6.0.0 but I hope there won鈥檛 be that many instances around there relying on the broken behavior.
I am reading the spec differently: there is always the possibility of returning an empty-sequence (see signature), and there is room for implementation dependent behavior: 'One possible processing model for this function is as follows:' and then there are things that may not be spec dependent, but rather implementation dependent. Also: isnt it the case that saxon and others also return an empty sequence if a doc cannot be found? I think it would be nice if there is something to be found, but it appears to not be parseable as an xml document. I agree with @adamretter that this is going to break in a lot of places where an empty sequence is expected by the code. I'd call it a feature rather than a bug.
there is always the possibility of returning an empty-sequence
The function only returns an empty sequence if $uri is an empty sequence.
Also: isnt it the case that saxon and others also return an empty sequence if a doc cannot be found?
No. As I mentioned in the original post:
Given a query like
doc("foo")(wheredoc-available("foo")returnsfalse()), Saxon raises an I/O error and BaseX raises the expectedFODC0002error.
Regarding the implementation-dependent behavior, I agree, the spec leaves room for implementations to define the behavior of fn:doc(). I guess I could revise my original post from saying "the spec says the processor should raise an error" to "the spec says that the processor may raise an error".
Indeed, under error conditions, the spec clearly says:
A dynamic error may be raised
err:FODC0005if$uriis not a valid URI reference.
I guess I would also say that the spec's suggestion here for implementations (which Saxon and BaseX follow) makes just as good sense for eXist too. The language provides ample means such as doc-available() and try-catch to prevent URI errors from halting execution of code.
I agree that this would need a major version.
Case in point for the need for a major version for such changes: https://github.com/eXist-db/existdb-packageservice/issues/19.
Thanks for your comments @joewiz . I've tried a few tricks with Saxon running the following (10.3EE, via Oxygen):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0">
<xsl:template match="/">
<xsl:variable name="test" as="document-node()?" select="doc('file:///C:\temp\test.xml')"/>
<xsl:sequence select="exists($test)"/>
</xsl:template>
</xsl:stylesheet>
which returns 'true'.
Running the same with <xsl:sequence select="$test"/> returns C:\Temp\test.xml (The system cannot find the file specified).
So Saxon is not consistently reporting a breaking error. But that's another discussion (and maybe I am not testing correctly). I just checked in Mike Kay's XSLT 2.0 and XPath 2.0, and there too it is simple: the implementation should throw an error for doc() if it can not be mapped to one or more document-nodes with a given $url. I am just so used to the current eXist behavior that I took it for a feature.