[Bug 4446] [XQuery] 2.3.4 Equivalent expressions

http://www.w3.org/Bugs/Public/show_bug.cgi?id=4446





------- Comment #1 from mike@saxonica.com  2007-06-06 09:38 -------
There has been some email discussion on this within the WG, and there was some
sentiment for leaving the text as it is on the grounds that we've spent a lot
of time on the area and this is the best we can do; however I volunteered and
was given an action (A-332-03) to see if we can't make any editorial
improvements.

It seems to me that the complaint here is that the term "equivalent expression"
has no definition, other than the circular definition implied from the sentence
where the term is introduced. At the same time, it's not clear (to one reader
at least) that the following paragraphs concerning conditional expressions and
typeswitch are intended to qualify the general statement allowing arbitrary
rewrites. There are other problems: it's undefined what it means for one result
to be "the same as" another, and the freedom in respect of errors shouldn't
extend to static errors. Finally, I think we can do better in terms of setting
expectations about where rewrites might change error behaviour, without being
over-prescriptive.

The following is my attempt to improve this section. Text in [#...#] is my
commentary not intended for inclusion in the final spec.

<new>
For a variety of reasons, including optimization, implementations MAY rewrite
expressions into a different form. There are a number of rules that limit the
extent of this freedom:

* Other than the raising or not raising of errors, the result of evaluating a
rewritten expression MUST conform to the semantics defined in this
specification for the original expression. [# remove "be the same as", because
where the specification allows implementations latitude e.g. over ordering,
rewrites can exploit this freedom #]

  Note: this allows an implementation to return a result in cases where the
original expression would have raised an error, or to raise an error in cases
where the original expression would have returned a result. The main cases
where this is likely to arise in practice are (a) where a rewrite changes the
order of evaluation, such that a subexpression causing an error is evaluated
when the expression is written one way and is not evaluated when the expression
is written a different way, and (b) where intermediate results of the
evaluation cause overflow or other out-of-range conditions. [# This note is
non-normative and unenforceable, but sets expectations. It gives users a bit of
leverage over vendors who decide that 1 div 0 is 42 #]

  Note: this rule does not mean that the result of the expression will always
be the same in non-error cases as if it had not been rewritten, because there
are many cases where the result of an expression is to some degree
implementation-dependent or implementation-defined.

*  Conditional and typeswitch expressions MUST NOT raise a dynamic error in
respect of subexpressions occurring in a branch that is not selected. Thus, the
following example MUST NOT raise a dynamic error if the document abc.xml does
not exist:

if (doc-available('abc.xml')) then doc('abc.xml') else ()

* As stated earlier, an expression MUST NOT be rewritten to dispense with a
required cardinality check: for example, string-length(//title) MUST raise an
error if the document contains more than one title element

* Expressions must not be rewritten in such a way as to create or remove static
errors. [# see bug #3773 #] For example, there is a rule that in casting a
string to a QName the operand must be a string literal. This rule applies to
the original expression and not to any rewritten form of the expression.


Expression rewrite is illustrated by the following examples.

    * Consider the expression //part[color eq "Red"]. An implementation might
choose to rewrite this expression as //part[color = "Red"][color eq "Red"]. The
implementation might then process the expression as follows: First process the
"=" predicate by probing an index on parts by color to quickly find all the
parts that have a Red color; then process the "eq" predicate by checking each
of these parts to make sure it has only a single color. The result would be as
follows:
          o  Parts that have exactly one color that is Red are returned.
          o  If some part has color Red together with some other color, an
error is raised.
          o The existence of some part that has no color Red but has multiple
non-Red colors does not trigger an error.

*      The expression in the following example cannot raise a casting error if
it is evaluated exactly as written (i.e., left to right). Since neither
predicate depends on the context position, an implementation might choose to
reorder the predicates to achieve better performance (for example, by taking
advantage of an index). This reordering could cause the expression to raise an
error.

      $N[@x castable as xs:date][xs:date(@x) gt xs:date("2000-01-01")]

      To avoid unexpected errors caused by expression rewrite, tests that are
designed to prevent dynamic errors should be expressed using conditional or
typeswitch expressions. For example, the above can be written as:

$N[if (@x castable as xs:date)
   then xs:date(@x) gt xs:date("2000-01-01")
   else false()]

</new>

Received on Wednesday, 6 June 2007 09:38:27 UTC