Errors in a query can be reported in either the static analysis phase or the dynamic evaluation phase. These two phases are roughly analogous to compiling and running program code. Certain XQuery implementations take a more aggressive approach to finding type-related errors in the static analysis phase. These implementations are said to support static typing.
Static typing, as the term is used in XQuery, refers to reporting all possible type errors at analysis (compile) time rather than evaluation (run) time. This is sometimes referred to as pessimistic static typing, where the philosophy is to report any errors that could possibly happen, not just those that it knows will happen. The static typing feature of XQuery is optional; implementations are not required to support static typing and many do not fully support it.
The fact that a processor doesn't support this feature doesn't mean that it is doing no compile-time analysis. It might use the analysis transparently for optimization purposes, or it might report some errors at compile time; but in this case, it will report errors optimistically. It will only report errors when it can see that there is definitely something wrong, like in the expression "x" + 3
, and not simply in cases of ambiguity, as in $x + 3
, where the value of $x
depends on some input data.
Static typing has the advantages of allowing type errors to be caught earlier and more reliably, and can help some implementations optimize queries. However, as you will see in this chapter, it can also be an irritation to query authors in that it reports many "false" errors.
As part of the static typing process, the processor checks all expressions in a query and assigns them a static type, which is the supplied type of the expression. For example, the expression "abc"
is assigned the static type of xs:string
. The expression count(doc("catalog.xml")//product)
is assigned the static type of xs:integer
, which is the return type of the count
function.
A type error is reported when a function or operator expects a value of a certain type and a parameter or operand of an incompatible type is used.
A number of obvious type errors can be caught in the analysis phase, for example:
Passing an integer to a function that expects a string, as in upper-case(2)
Attempting a cast between two types that do not allow casting, as in current-date( ) cast as xs:integer
Attempting to add two strings, as in "abc" + "def"
Passing a sequence of multiple values to a function or operation that expects a single atomic value, as in substring(("a","b"),3)
All of these examples will raise a type error no matter what the input document contains. Many implementations that do not support the static typing feature will also report these errors at analysis time, since they will always result in an error.
Static typing also takes into account any in-scope schema definitions. A schema can make static typing much more useful by providing the processor with extra information about the input documents, namely:
If the number
element is declared to be of type xs:string
, it is obviously an error to try to multiply it by 2.
If a product
can have more than one name
child, you don't want to use the expression product/name
as an argument to the substring
function, because the substring
function only accepts a single string (or the empty sequence), not a sequence of multiple strings.
If you refer to an element produt
(misspelled) in your query, it must be an error, because no produt
element is declared in the schema.
The path catalog/number
contains an error because the schema does not allow number
to be a child of catalog
, even if both of those elements are declared in the schema.
None of the above errors could be caught during the static analysis phase if no schema were present. Sometimes this type of feedback can be extremely useful. For one thing, it can lead to queries that are more robust. You may not have envisioned a product with more than one name in your test data, but you would have found this error the hard way later when querying some new input data that happened to have that characteristic.
Static typing can also make query debugging and testing much easier. If you get an error message saying that catalog/number
will always return the empty sequence (and therefore is not a valid path), it is much more useful than getting no results from your entire query and wondering why. Coming up with test data that addresses every single possible combination of elements and values in an input document can relieve the burden on you.
The down side of static typing is that sometimes the errors raised are less useful. Sometimes you know that an error situation would never arise in your input document, even if the schema might allow it. Suppose you want to substring the name of a single product, based on its product number. You might use the expression:
substring(doc("catalog.xml")//product[number = 557]/name, 1, 10)
However, if static typing is in effect, this expression causes a static error. This is because, as far as the processor knows, there could be more than one name
element that matches that criterion, but the substring
function's signature requires that only zero or one item be provided as the first argument. You may know for sure that no two products will have the same product number (perhaps because you are familiar with the application that generates the XML documents), but the processor doesn't know that.
This particular error can be avoided by calling the zero-or-one
function, described in "The zero-or-one, one-or-more, and exactly-one Functions," later in this chapter.
3.143.203.96