> The XQuery Processor
EvalExpr ::= UsingClause? "eval" "{" ExprSingle "}"
UsingClause ::= "using " "$" VarName ("," "$" VarName)*
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.
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).
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 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.