XQuery Eval Facility

Syntax

EvalExpr ::= UsingClause? "eval" "{" ExprSingle "}"
UsingClause ::= "using " "$" VarName ("," "$" VarName)*

Semantics

The Eval expression first computes the value of its target expression in the context of the surrounding query. The result of this computation is atomized and cast as a string, then parsed and evaluated in a new static context and dynamic context derived from the contexts of the enclosing query at the global (top-level) scope. The derived contexts contain declarations for, and values of, the variables bound by the optional UsingClause. The values are taken from the innermost in-scope variable in the enclosing query with the same QName as the variable being declared.

The evaluated query may contain its own prolog, but may not be a library module, may not contain schema imports, and may not declare external variables. In all other respects, the evaluated query behaves like a regular query. The rules for deriving the evaluated query's static and dynamic context are explained in a subsection below.

As eval introduces a distinct static context, it is not an error if the prolog of the evaluated query declares variables and/or functions shadowing components with the same name of the original query. However, the evaulated query may not declare global and/or external variables with names conflicting with the bindings specified by the UsingClause (which are implicitly declared in the evaluated query's static context).

Derived static context

This section describes how the static context of the evaluated query is derived from the static context of the enclosing query and the evaluated query's prolog ("evaluated prolog").

In the following definitions, the enclosing static context refers to the static context of the enclosing query after the prolog has been parsed.

Derived dynamic context

Errors

Examples

let $x := 10 return
using $x eval {
"declare variable $x := 11;
$x + 1"
}

The query above is invalid as it re-declares the UsingClause bindings, which are implicitly defined in the evaluated prolog. It should raise err:XQST0049

declare variable $x := 41;
eval { concat ("$x", "+", "1") }

The above query is valid and produces the result 42. It illustrates that evaluated code has access to global variables of the enclosing query.

declare variable $g := 11;
declare function local:f1 ($a) { $g + $a };

let $x := 10 return
using $x eval { "
declare function local:f2 () { $g + $x };
local:f1 ($x) + local:f2 ()
"}

This example, which in a conforming implementation should return the integer 42, illustrates that both global variables and user-defined functions from the enclosing query are available to the evaluated query, which may in turn contain its own user-defined functions.

declare namespace ns1 = "myns";
declare variable $ns1:x := 1;
declare variable $ns1:y := 40;
eval { '
declare namespace ns2 = "myns";
declare variable $ns2:x := 2;
$ns1:x + $ns1:y
' }

In this example, the namespace prefix ns1 is inherited by the evaluated query, which also binds the prefix ns2 to the same namespace. The evaluated query declares variable $ns2:x which has the same expanded QName (and thus over-rides) the variable $ns1:x from the surrounding query. The correct result for this query is 42.

let $x := 42 return eval { "$x" }

This eval query attempts to use a FLWOR variable from the surrounding query without declaring it in the UsingClause; it should raise err:XPST0008 (undefined variable).

declare variable $n := <a><b>1</b><b>+$x</b></a>;
declare variable $x :=2;
eval { $n }

This example should return 3 (nodes are atomized before being passed to eval).

declare namespace ns1 = "myns";
declare namespace ns2 = "myns";
let $ns1:x := 3 return
using $ns1:x, $ns2:x eval { "$ns1:x" }

Since the UsingClause lists two variables with equal QName's, this query should raise err:XQST0049

eval { 1 to 2 }

As eval expects a single item, this query should raise err:XPTY0004

let $x := "21" return
using $x eval { concat ($x, " + xs:double ($x)") }

This eval expression accesses $x in two ways — both in the ExprSingle and in the evaluated code. The result should be 42.

declare variable $x := 20;

declare function local:f () { $x };

let $x := 22 return
using $x eval { "$x + local:f ()" }

The correct answer is 42. This query illustrates that references to global variables within a user-defined function's body are resolved in the original dynamic context that the function was compiled against, not in the innermost dynamic context available.