Bug 4378: absent context item

The question is: what kind of error should we raise when we need a context item and the context item is absent? And where and how should we describe the rules?

I’m concerned that we have a solution that works for the full range of specs: XQuery, XPath, and XSLT.

I think the best way to achieve this as follows:

(A) If we’re going to build this on the concept of “context item static type” then we need to strengthen the foundations. In XSLT there are contexts, for example the body of a named template, where the best we know statically is that the context item is “either item() or absent”. There may even be cases where we know statically that the context item is “either node() or absent”. I don’t propose to do this formally, but I suggest we add to the definition of “context item static type”: 

The context item static type is either an item type, or the value “absent” indicating that the context item does not exist, or the union of the two (for example, it might be “either node() or absent”).

(B) In 2.2.3.1 we have:

<quote>
If the Static Typing Feature is in effect, a processor must raise a type error during static analysis if the inferred static type of an expression is not subsumed by the required type of the context where the expression is used. For example, the call of substring above would cause a type error if the inferred static type of $a is xs:integer; equally, a type error would be reported during static analysis if the inferred static type is xs:anyAtomicType.

If the Static Typing Feature is not in effect, a processor may raise a type error during static analysis only if the inferred static type of an expression has no overlap (intersection) with the required type: so for the first argument of substring, the processor may raise an error if the inferred type is xs:integer, but not if it is xs:anyAtomicType. Alternatively, if the Static Typing Feature is not in effect, the processor may defer all type checking until the dynamic evaluation phase.

</quote>

After these paragraphs, add:

<quote>
These rules are extended in the case of expressions that depend on the context item to handle the case where the context item is (potentially) absent:

* If the Static Typing Feature is in effect, a processor must raise a type error during static analysis [errorref] if the context item static type for such an expression includes the value “absent”.

* If the Static Typing Feature is not in effect, a processor may raise a type error during static analysis [errorref] if the context item static type for such an expression is the value “absent”.
</quote>

(C) In 3.1.4 Context Item Expression, expand on the rules. Currently:

<old>
If the context item is absentDM31, a context item expression raises a dynamic error [err:XPDY0002].
</old>

which changes to:

<new>
 * If the context item is absent, a type error [errorref] is raised. As with other type errors, processors that implement the Static Typing Feature will raise this error during static analysis based on the context item static type, and processors that do not implement the Static Typing Feature have the option of raising the error during static analysis if evaluation will necessarily fail.
</new>

(D) I’m a little surprised to discover that for axis steps, we appear to currently raise XPTY0020 rather than XPDY0002: "If the context item is a node, an axis step returns a sequence of zero or more nodes; otherwise, a type error is raised [err:XPTY0020].” However, looking at test cases, it seems they expect to raise XPDY0002 if there is no context item, and XPTY0020 if the context item is of the wrong type. I suggest we regularise this by stating that XPDY0002 (or its replacement) is raised if there is no context item. So add the sentence:

* If the context item is absent, a type error [errorref] is raised, in the same way as for a Context Item Expression [link].


(E) Change XPDY0002 to a type error. My preference would be to do this with no change in error code, for compatibility reasons, but I could live with changing the code. (One argument in favour of changing the code is that XPDY0002 applies when ANY part of the dynamic context is absent; though an absent context item is by far the most common case).

In all places where XPDY0002 is referenced, change the language used to describe the error, referring to ContextItemExpression for the detail. For example for fn:string() we currently say:

A dynamic error is raised [err:XPDY0002]XP30 by the zero-argument version of the function if the context item is absentDM31.

and this changes to:

A type error is raised [err:XPDY0002]XP30 by the zero-argument version of the function if the context item is absentDM31. The rules are the same as for an explicit ContextItemExpression [link].

(F) Add to the Incompatibility appendix: 

“Processors are now able to report the absence of a context item during static analysis. This may affect applications that use try/catch to recover from this situation dynamically”.


Michael Kay
Saxonica

Received on Tuesday, 3 November 2015 18:41:00 UTC