XQuery Functions
This module contains functions for parsing and evaluating XQuery strings at runtime, and to run code in parallel.
The Job Functions can be used to register and run queries as separate jobs.
Conventions
All functions and errors are in the http://basex.org/modules/xquery namespace, to which the xquery prefix is statically bound.
Evaluation
xquery:eval
Updated: A function item can be invoked instead of a query. Allow decimal places for timeout value. The permission option also applies to returned function items.
| Signature | xquery:eval( $query as (xs:string|xs:anyURI|fn(*)), $bindings as (map((xs:string|xs:QName), item()*)|array(*))? := {}, $options as map(*)? := {}) as item()* | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Summary | Evaluates the supplied $query and returns the resulting items. If the query is of type xs:anyURI, the module located at this URI will be retrieved (a relative URI will be resolved against the static base URI).
Instead of a query, a function item can be supplied, which is invoked with the arguments of the The calling query is globally locked, as the databases accessed by the evaluated query are not known in advance. Variables and the context value can be declared via
The following
| ||||||||||||||||||
| Errors |
| ||||||||||||||||||
| Examples | Result: 4 Result: Hello World. Invokes a function item with a single argument.If a URI is supplied, the query in the specified file will be evaluated.You can bind the context and operate on a certain database only, for example.The expressions use strings as keys. All of them return XML.The expressions use QNames as keys. All of them return 'XML'. |
xquery:eval-update
Updated: A function item can be invoked instead of a query.
| Signature | xquery:eval-update( $query as (xs:string|xs:anyURI|fn(*)), $bindings as (map((xs:string|xs:QName), item()*)|array(*))? := (), $options as map(*)? := ()) as empty-sequence() | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Summary | Evaluates a query as updating expression. All updates will be added to the Pending Update List of the main query and performed after the evaluation of the main query. The rules for all arguments are the same as for xquery:eval. | ||||||||||
| Errors |
| ||||||||||
| Examples | Removes entries from a temporary database and returns an info string. |
Function Items
Instead of a query, a function item can be supplied to xquery:eval, xquery:eval-update, job:eval, job:execute and ws:eval. It is invoked with the arguments of the $bindings array, which must match its arity, as with fn:apply. Maps and arrays are function items as well, but they are rejected with a type error.
A function item carries the compiled code and the static context of the query that created it, and must therefore be independent of that query. Captured values, the captured query focus and supplied arguments are copied; function items occurring in them are checked as well. Databases can be accessed in the function body: they are opened and locked by the nested query. Some accepted queries:
declare function local:f() { count(db:get('db')//a) };
declare variable $v := random:integer();
xquery:eval(fn() { $v })
xquery:eval(local:f#0)
(: the captured node is copied :)
let $n := db:get('db')/a
return xquery:eval(fn() { name($n) })
xquery:eval(fn() { count(db:get('db')//a) })
A basex:eval error is raised if the function depends on the calling query:
(: nodes of static variables are not copied :)
declare variable $v := db:get('db');
xquery:eval(fn() { count($v//a) })
(: the context value is not part of the function signature: :)
xquery:eval(fn() { . })
(: the context value is not part of the function signature :)
xquery:eval(fn() { . })
(: static variables with Java objects :)
xquery:eval(fn() { Q{java:java.lang.Math}abs(-1) })
(: the function body is rewritten for index access :)
let $x := db:get('db')//a[1]/string()
let $f := fn() { db:get('db')//a[text() = $x] }
return ($f(), xquery:eval($f))
The code is compiled by the calling query. Functions annotated with %basex:eval are compiled without accessing the dynamic context of the calling query: databases are not opened, and fn:current-dateTime returns the time of the nested query. Inline functions that are directly supplied as function or bindings argument are annotated automatically. Functions that are referenced via variables or function calls must be annotated explicitly. Other functions may be optimized with the dynamic context of the calling query: their bodies may be rewritten for index access, which results in the error shown above, and fn:current-dateTime may return the time of the calling query.
As no query text is parsed, the options that address it have no effect: the function keeps the base-uri of the query that created it, and there is no query location that could be reported with pass. The permission option constrains the code that is compiled in the nested context; it does not apply to code that was already compiled by the calling query, because the permissions of a function are checked when it is compiled, not when it is invoked.
Parsing
xquery:parse
| Signature | xquery:parse( $query as (xs:string|xs:anyURI), $options as map(*)? := {}) as element()create | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Summary | Parses the specified $query as XQuery module and returns the resulting query plan. If the query is of type xs:anyURI, the module located at this URI will be retrieved (a relative URI will be resolved against the static base URI). The following $options are available:
| ||||||||||||||||||
| Examples | The result: |
Parallel Execution
Parallel query execution is recommended if you have various calls that require a lot of time, but that cannot be sped up by rewriting the code. This is the case, for example, if external URLs are called. If you are parallelizing local data reads (such as the access to a database), single-threaded queries will usually be faster, because parallelized access to disk data often results in randomized access patterns, which will rarely be optimized by the caching strategies of HDDs, SSDs, or the operating system.
xquery:for-each
Added: New function.
| Signature | xquery:for-each( $input as item()*, $action as fn($item as item(), $pos as xs:integer) as item()*, $options as map(*)? := {}) as item()*admin | ||
|---|---|---|---|
| Summary | This function applies the supplied (non-updating) $action to every item of $input in parallel and returns the results in input order. It is the parallel counterpart of fn:for-each and saves you from wrapping each call in a separate function item. If $action accepts a second argument, it is supplied the 1-based position of the item. The same $options as for xquery:fork-join are available. | ||
| Errors |
| ||
| Examples | Requests 100 URLs, use at most 8 parallel threads.Returns the squares (1, 4, 9, 16, 25), computed in parallel. |
xquery:fork-join
Updated: report and timeout options added.
| Signature | xquery:fork-join( $functions as fn(*)*, $options as map(*)? := {}) as item()*admin | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Summary | This function executes the supplied (non-updating) $functions in parallel and returns the results in the order of the input functions. The following $options are available:
errors: false()), the results of failing functions are dropped, and the returned sequence is no longer aligned with the input functions. Enable report to keep this assignment. | ||||||||||||||||||
| Errors |
| ||||||||||||||||||
| Examples | Requests 100 URLs, use at most 8 parallel threads.Parallel sleep function calls. The function is expected to finish in 1 second if the system has at least 2 cores.Returns one record per function: { 'value': true() }, { 'error': { 'code': #err:FOER0000, 'description': '…', … } }, { 'value': false() }. |
xquery:fork-any
Added: New function.
| Signature | xquery:fork-any( $functions as fn(*)*, $options as map(*)? := {}) as item()*admin | ||
|---|---|---|---|
| Summary | This function executes the supplied (non-updating) $functions in parallel and returns the result of the first one that finishes successfully; the remaining branches are cancelled. If all functions raise an error, the function fails as well. This is useful for redundant requests, such as querying several mirrors and using the fastest response. As the winning branch is not deterministic, only the parallel and timeout $options (see xquery:fork-join) are evaluated. | ||
| Errors |
| ||
| Examples | Sends a request to two mirrors in parallel and returns the response that arrives first. |
xquery:reduce
Added: New function.
| Signature | xquery:reduce( $input as item()*, $init as item()*, $action as fn($acc as item()*, $item as item()) as item()*, $combine as fn($acc1 as item()*, $acc2 as item()*) as item()*, $options as map(*)? := {}) as item()*admin | ||
|---|---|---|---|
| Summary | This function aggregates $input in parallel (map-reduce). The sequence is split into chunks; each chunk is folded sequentially with $action, starting from $init (as with fn:fold-left), and the partial results are merged with the associative $combine function. For the result to be deterministic, $combine must be associative and $init must be its identity (neutral element). If $input is empty, $init is returned. Only the parallel and timeout $options (see xquery:fork-join) are evaluated. | ||
| Errors |
| ||
| Examples | Computes the sum 1 + 2 + … + 1000000 = 500000500000 in parallel. |
Errors
| Code | Description |
|---|---|
error | An unexpected error occurred. |
memory | Query execution exceeded memory limit. |
nested | Nested query evaluation is not allowed. |
permission | Insufficient permissions for evaluating the query. |
timeout | Query execution exceeded timeout. |
update | updating expression found or expected. |
Changelog
Version 13.0- Added:
xquery:for-each: New function for parallel iteration. - Added:
xquery:reduce: New function for parallel aggregation. - Added:
xquery:fork-any: New function returning the first available result. - Updated:
xquery:eval: A function item can be invoked instead of a query. Allow decimal places for timeout value. Thepermissionoption also applies to returned function items. - Updated:
xquery:eval-update: A function item can be invoked instead of a query. - Updated:
xquery:fork-join:reportandtimeoutoptions added. - Updated:
xquery:parse:optimizeoption added.
- Updated:
xquery:fork-join: Options added. - Updated: The Clark notation was replaced with the Expanded QNames notation.
- Updated:
xquery:parse:$querycan additionally be of typexs:anyURI. - Removed: xquery:parse-uri (merged with
xquery:parse)
- Removed: xquery:invoke, xquery:invoke-update (merged with
xquery:evalandxquery:eval-update)
- Added:
xquery:invoke-update - Updated:
xquery:eval:passoption added - Updated:
xquery:parse,xquery:parse-uri:base-urioption added - Updated: xquery:update renamed to
xquery:eval-update - Updated: error codes updated; errors now use the module namespace
- Added:
xquery:fork-join - Updated:
xquery:eval:base-urioption added - Updated: Relative URIs will always be resolved against the static base URI of the query
- Removed: xquery:type (moved to Profiling Functions)
- Added:
xquery:parse-uri - Updated:
xquery:parse:passoption added
- Added: xquery:update,
xquery:parse - Removed: xquery:evaluate (opened databases will now be closed by main query)
- Added:
$optionsargument
- Added:
xquery:evaluate - Updated: used variables must be explicitly declared in the query string.
- Added: New module added. Functions have been adopted from the obsolete Utility Module.