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 in this module are assigned to the http://basex.org/modules/xquery namespace, which is statically bound to the xquery prefix.
Evaluation
xquery:eval
Updated: Allow decimal places for timeout value.
Updated: A function item can be invoked instead of a query.
| 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 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: a basex:transfer error is raised if its body invokes Java code or accesses an already opened database. Captured values, the captured query focus and supplied arguments are copied; function items occurring in them are checked as well.
- Accepted:
let $n := db:get('db')/a return xquery:eval(fn() { name($n) }), as the captured node is copied - Accepted:
declare variable $v := random:integer(); xquery:eval(fn() { $v }) - Rejected:
xquery:eval(fn() { . }), as the context value is not part of the function signature - Rejected:
xquery:eval(fn() { Q{java:java.lang.Math}abs(-1) })
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:fork-any: New function returning the first available result. - Added:
xquery:reduce: New function for parallel aggregation. - Updated:
xquery:fork-join:reportandtimeoutoptions added. - Updated:
xquery:eval: Allow decimal places for timeout value. - Updated:
xquery:eval,xquery:eval-update: a function item can be invoked instead of a query.
- 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.