Following Omar's message on lock management [1] I thought I would share a technique that I have tried. It makes use of the function inspect:functions [2].
The code below shows two versions of an eval-update function. After running each version the info.result view reports:
- local:eval-update => a global write lock. - local:eval-update2 => no locks at all!
I am pretty sure this is a bug/oversight in inspect:functions. I suspect running it risks data integrity, so it is not a good idea.
However, I do make use of a non-updating version of this technique, as a way to do string evaluation without triggering a global read lock. If I know that no lockable resources are referenced then it seems safe to me? Note: inspect:functions is similar to the unimplemented standard XQuery 3.1 function fn:load-xquery-module[3]
/Andy
[1] https://mailman.uni-konstanz.de/pipermail/basex-talk/2022-May/017207.html [2] https://docs.basex.org/wiki/Inspection_Module#inspect:functions [3] https://www.w3.org/TR/xpath-functions-31/#func-load-xquery-module
(:~ evaluate XQuery string, string is enriched with external variable definitions for convenience :) declare %updating function local:eval-update($exp as xs:string,$binds as map(*)){ let $decl:= map:keys($binds)!``[declare variable $`{ . }` external;]``=>string-join("") return xquery:eval-update($decl || $exp, $binds) };
declare %updating function local:eval-update2($exp as xs:string,$binds as map(*)){ let $decl:= map:keys($binds)!``[let $`{ . }` :=$binds("`{ . }`") ]``=>string-join("") let $mod:=("module namespace _='abuse'; declare %updating function _:foo($binds){" , $decl, "return " , $exp , "};")=>string-join("") let $p:=file:create-temp-file("APB", ".xqm") let$_:=file:write-text($p,$mod) return updating inspect:functions($p)($binds) };
(: note: the bind functionality is not used in this example) let $binds:=map{"p1":42} let $exp:="db:replace('factbook', 'abuse.xml', '<a/>')" return local:eval-update2($exp,$binds)
Hi Andy,
I am pretty sure this is a bug/oversight in inspect:functions. I suspect running it risks data integrity, so it is not a good idea.
Good catch; and I’m somewhat sorry this bug is fixed now [1]. As we can’t assess at compile time if locking is necessary, a global read lock is now applied as soon as the function is called. The read lock is upgraded to a write lock if one of the returned functions is invoked as an updating function.
Cheers, Christian
[1] https://github.com/BaseXdb/basex/commit/8e6ae0d02188348b7b8adb872657fc700518...
Hi Christian,
I’m somewhat sorry this bug is fixed now
Me too :)
As we can’t assess at compile time if locking is necessary.
I guess there are two compile times at play here, as with xquery-eval. It would be nice to find a way to downgrade locks as well as upgrade them. But easier said than done.
/Andy
On Mon, 13 Jun 2022 at 12:17, Christian Grün christian.gruen@gmail.com wrote:
Hi Andy,
I am pretty sure this is a bug/oversight in inspect:functions. I suspect
running it risks data integrity, so it is not a good idea.
Good catch; and I’m somewhat sorry this bug is fixed now [1]. As we can’t assess at compile time if locking is necessary, a global read lock is now applied as soon as the function is called. The read lock is upgraded to a write lock if one of the returned functions is invoked as an updating function.
Cheers, Christian
[1] https://github.com/BaseXdb/basex/commit/8e6ae0d02188348b7b8adb872657fc700518...
basex-talk@mailman.uni-konstanz.de