This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
I'm a bit concerned by the fn:transform "saved" delivery-format. I forget the details now, but fn:put never made it into XQ31. Instead it was left in XQ Update. fn:transform with the "saved" option using a transform olong the lines of: <xsl:param name="href" /> <xsl:template match="/"> <xsl:result-document href="$href"> <xsl:copy-of select="."/> </xsl:result-document> </xsl:template> would appear to give fn:put facilities and has all the baggage of a function with side effects. If I'm not mistaken, is this wise?
I think the best answer to this might be to put suitable caveats in the spec: * implementations should not be required to support the "saved" option. * if they do support it, they may impose restrictions such as not allowing two result documents to be written to the same destination, or not allowing a destination to be read and written within the same query, etc. * users should be aware that side-effects cannot be relied upon, for example if the actual result of the fn:transform call is not used, or is only partially used, then the side-effects of the call may not happen.
In the case of an implementation NOT supporting 'saved', which error code should be raised? Arguments could be made for pretty much any of the four existing FOXT codes.
Suggested resolution is to add: The delivery format "saved" indicates that the transformation should modify the state of the external environment. This has two noteworthy consequences: (a) it create a potential security risk. (b) the fn:transform function ceases to be a pure function, because it has side-effects. Implementations may mitigate these problems in a number of ways, including the following: (i) use of the "saved" option may be disallowed, either completely or at user option (ii) the environment that the "saved" option is allowed to modify may be sand-boxed in some way. For example: resources that are created using this option may be accessible only via some special interface; the resource may become available only on completion of the execution scope in which the fn:transform function is evaluated; or the implementation may prevent access to such resources using functions such as fn:doc and fn:collection. (iii) creating multiple resources with the same URI may be disallowed. (iv) the implementation may define circumstances in which the side-effect of creating external resources does not happen as a consequence of query optimization (for example, any situation in which a query calls fn:transform but has no functional dependency on the result of the call.) (v) there may be restrictions on the URIs that can be used to identify saved resources. Add error code FOXT0007: The transformation uses delivery-format="saved" in a way that violates implementation-defined constraints on the use of this option.
The changes were accepted and have been applied.
Thanks.
In light of bug 29959 and bug 29990, I would like the working group to take a second look at this.
Some examples for discussion: (e1, e2, e3) [2] Which expressions get evaluated? e1, e2? All three? Just e2? ------------------------------------------ Equivalent? for $x in f() let $y := e1 where $x > 3 return ... vs for $x in f() where $x > 3 let $y := e1 return ... ------------------------------------------ let $x := e1 return if (c) then "hello world" else $x Can I inline the let? ------------------------------------------ for $o in orders(), $c in customers() let $x := f($c) where $o/cid eq $c/cid return ... Rewrite using a hash-join? ------------------------------------------ (e1, e2) If e2 raises a type error does e1 get evaluated? What if the type error is detected statically? If it is detected during dynamic evaluation, do side effects produced by e1 still persist? ------------------------------------------ let $dummy := e1 return 123 Does e1 get evaluated?
The answer to all the examples in comment 7 is that we decided to leave it implementation-dependent. If you want to be sure that a call on fn:transform() will be evaluated, then make sure that the result of your query depends on its return value. The rationale was that the feature is still useful even if it isn't 100% interoperable.
See also bug 29959
I agree with Tim. I would prefer to use fn:put() with fn:transform() instead of having "saved". The same difficulties we had with fn:put() also apply to fn:transform() with "saved".
After discussion on today's telcon, I propose the following resolution: (a) drop the option delivery-format=saved. (b) add a new option post-process. The value is a function of type function(xs:anyURI, item()*) as item()* with the default value function($a, $b) { $b } which is invoked to post-process each result of the transformation (both the principal result and secondary results), in whatever form it would otherwise be delivered (document, serialized, or raw). The first argument of the function is the URI of the result, the second argument is the actual value. The value that is returned in the result of the fn:transform function is the result of applying this post-processing. <note> <p>If the implementation provides a way of writing or invoking functions with side-effects, this post-processing function might be used to save a copy of the result document to persistent storage. For example, if the implementation provides access to the EXPath File library [non-normative reference], then a serialized document might be written to filestore by calling the file:write-binary function. Similar mechanisms might be used to issue an HTTP POST request that posts the result to an HTTP server, or to send the document to an email recipient. The semantics of calling functions with side-effects are entirely implementation-defined.</p> <p>If the primary purpose of the post-processing function is achieved by means of such side-effects, and if the actual results are not needed by the caller of the fn:transform() function, then it does not matter what the post-processing function actually returns (it could be an empty sequence, for example).</p> <p>Calls to fn:transform can potentially have side-effects even in the absence of the post-processing option, because the XSLT specification allows a stylesheet to invoke extension functions that have side-effects. The semantics in this case are implementation-defined.</p> <p>Unless implementations provide mechanisms such as pragmas or function annotations to allow functions with side-effects to be specially recognized, it is advisable that calls to fn:transform should appear in a context where the result of the function is actually used, otherwise there is a risk that an optimizer might decide to eliminate the function call.</p> </note>
> because the XSLT specification allows a stylesheet to invoke extension > functions that have side-effects This suggests that only extension functions have side effects, while in effect there's more (in addition to xsl:result-document and the principal output document): - XSLT uses XPath, which defines fn:trace, fn:transform etc which may have side effects - XSLT defines xsl:message, xsl:assert which may cause side effects - XSLT can have extension functions, attributes and instructions that may cause side effects I'd propose to either enumerate all of them or to make the statement more generic.
At the meeting on 2016-11-29, the WG decided to adopt the resolution proposed in comment 11. Action A-662-02 has been raised to track this.
The changes have been applied.
I have discovered that the changes were incompletely applied. Although the "saved" option has been dropped, there are still quite a few references to it. Fixing this requires deletion of the following sections of text: (a) If the delivery format is saved, the value is the absolute URI of the location where the serialized result has been saved. The saved document will not be accessible at this location within the current ·execution scope· (this is to prevent any dependency on order of execution). (b) The delivery format saved indicates that the transformation should modify the state of the external environment. This has two noteworthy consequences: • It creates a potential security risk. • The fn:transform function ceases to be a pure function, because it has side-effects. Implementations may mitigate these problems in a number of ways, including the following: • Use of the delivery-format=saved option may be disallowed, either completely or at user option. • The environment that the delivery-format=saved option is allowed to modify may be sand-boxed in some way. For example: resources that are created using this option may be accessible only via some special interface; the resource may become available only on completion of the execution scope in which the fn:transform function is evaluated; or the implementation may prevent the use functions such as fn:doc and fn:collection to access such resources. • Creating multiple resources with the same URI may be disallowed. • The implementation may define circumstances in which the side-effect of creating external resources is thwarted as a consequence of query optimization (for example, any situation in which a query calls fn:transform but has no functional dependency on the result of the call). • There may be restrictions on the URIs that can be used to identify saved resources (c) Errors FOXT0005 and FOXT0007. (d) There is also no change log entry for 29951
The fix in comment #15 was applied editorially to the document before publication as Rec.