"Expressions must be all updating" puzzle
Saturday, 19 August 2023 · 5 messages · last reply 21 Aug 2023
EK
Eliot Kimber19 Aug 2023 00:31 #
In BaseX 10:
In an updating function I have a call to another updating function that uses
update:output() to log messages.
If that function call is included, BaseX says that expressions must be all updating, but if I remove the call, BaseX is happy.
The calling function is:declare %updating
%rest:path('/now/rest/analytics/store-latest-acrolinx-users' )
function now:storeAcrolinxUsers() {
let $acrolinxMap as map(*)? :=
try {
acrolinx:getUserDataMap()
} catch * {
util:logToConsole(
'storeAcrolinxUsers'
,``[`{$err:code}` - `{$err:description}`]``
,'warn'
)
}
return
if (exists($acrolinxMap))
then
let $doc as element() := acrolinx:serializeAcrolinxUserMap($acrolinxMap)
let $fileName as xs:string := 'acrolinx-users_' || replace($doc/@timestamp, ':', '~') || '.xml'
return db:put(analyticsmgmt:getAnalyticsDatabase(), $doc, relpath:newFile('acrolinx/users', $fileName))};
The offending function is util:logToConsole(), which is declared as:
declare %updating function util:logToConsole(
$functionName as xs:string,
$message as xs:string,
$logLevel as xs:string
) {
let $logMessage as xs:string := '[' || upper-case($logLevel) || '] ' || $functionName || '(): ' || $message
return
(
update:output(prof:dump($logMessage)) ,
update:output($logMessage)
)
};This is declared as an updating function and returns “updating” functions.
If I comment out the call to util:logToConsole() in the first function, then BaseX is happy.
If I use the non-updating version of logToConsole(), util:logToLog(), then BaseX is also happy.
So my question is: why is BaseX complaining about the use of this updating function in an updating function?
There must be some subtlety that I’m missing but I have not yet figured out what it is.
Thanks,
Eliot
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
CG
Christian Grün21 Aug 2023 08:15 #
Hi Eliot,
Both branches of try/catch must either be updating or non-updating, and I assume that acrolinx:getUserDataMap() is non-updating.
Hope this helps,
Christian
Eliot Kimber <eliot.kimber at servicenow.com> schrieb am Sa., 19. Aug. 2023, 00:33:
Quoted text · Eliot Kimber · 134 lines
> In BaseX 10: > > > > In an updating function I have a call to another updating function that > uses update:output() to log messages. > > > > If that function call is included, BaseX says that expressions must be all > updating, but if I remove the call, BaseX is happy. > > > > The calling function is: > > declare %updating > > %rest:path('/now/rest/analytics/store-latest-acrolinx-users' ) > > function now:storeAcrolinxUsers() { > > let $acrolinxMap as map(*)? := > > try { > > acrolinx:getUserDataMap() > > } catch * { > > util:logToConsole( > > 'storeAcrolinxUsers' > > ,``[`{$err:code}` - `{$err:description}`]`` > > ,'warn' > > ) > > } > > return > > if (exists($acrolinxMap)) > > then > > let $doc as element() := acrolinx:serializeAcrolinxUserMap($acrolinxMap) > > let $fileName as xs:string := 'acrolinx-users_' || > replace($doc/@timestamp, ':', '~') || '.xml' > > return db:put(analyticsmgmt:getAnalyticsDatabase(), $doc, > relpath:newFile('acrolinx/users', $fileName)) > > > > }; > > > > The offending function is util:logToConsole(), which is declared as: > > declare %updating function util:logToConsole( > > $functionName as xs:string, > > $message as xs:string, > > $logLevel as xs:string > > ) { > > let $logMessage as xs:string := '[' || upper-case($logLevel) || '] ' || > $functionName || '(): ' || $message > > return > > ( > > update:output(prof:dump($logMessage)) , > > update:output($logMessage) > > ) > > }; > > > > This is declared as an updating function and returns “updating” functions. > > > > If I comment out the call to util:logToConsole() in the first function, > then BaseX is happy. > > If I use the non-updating version of logToConsole(), util:logToLog(), then > BaseX is also happy. > > > > So my question is: why is BaseX complaining about the use of this updating > function in an updating function? > > There must be some subtlety that I’m missing but I have not yet figured > out what it is. > > > > Thanks, > > > > Eliot > > _____________________________________________ > > *Eliot Kimber* > > Sr Staff Content Engineer > > O: 512 554 9368 > > M: 512 554 9368 > > servicenow.com <https://www.servicenow.com> > > LinkedIn <https://www.linkedin.com/company/servicenow> | Twitter > <https://twitter.com/servicenow> | YouTube > <https://www.youtube.com/user/servicenowinc> | Facebook > <https://www.facebook.com/servicenow> >
EK
Eliot Kimber21 Aug 2023 16:18 #
I guess my confusion is why this requirement is imposed in the context of a let expression? It cannot be the case that let expressions must be updating in the context of an updating function.
But you are correct, the acrolinx:getUserDataMap() is a non-updating function that may throw an exception (it calls a REST API on an Acrolinx server so there might be an HTTP failure).
Cheers,
E.
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
Quoted text · Christian Grün · 61 lines
From: Christian Grün <christian.gruen at gmail.com> Date: Monday, August 21, 2023 at 1:15 AM To: Eliot Kimber <eliot.kimber at servicenow.com> Cc: BaseX <basex-talk at mailman.uni-konstanz.de> Subject: Re: [basex-talk] "Expressions must be all updating" puzzle [External Email] Hi Eliot, Both branches of try/catch must either be updating or non-updating, and I assume that acrolinx:getUserDataMap() is non-updating. Hope this helps, Christian Eliot Kimber <eliot.kimber at servicenow.com<mailto:eliot.kimber at servicenow.com>> schrieb am Sa., 19. Aug. 2023, 00:33: In BaseX 10: In an updating function I have a call to another updating function that uses update:output() to log messages. If that function call is included, BaseX says that expressions must be all updating, but if I remove the call, BaseX is happy. The calling function is: declare %updating %rest:path('/now/rest/analytics/store-latest-acrolinx-users' ) function now:storeAcrolinxUsers() { let $acrolinxMap as map(*)? := try { acrolinx:getUserDataMap() } catch * { util:logToConsole( 'storeAcrolinxUsers' ,``[`{$err:code}` - `{$err:description}`]`` ,'warn' ) } return if (exists($acrolinxMap)) then let $doc as element() := acrolinx:serializeAcrolinxUserMap($acrolinxMap) let $fileName as xs:string := 'acrolinx-users_' || replace($doc/@timestamp, ':', '~') || '.xml' return db:put(analyticsmgmt:getAnalyticsDatabase(), $doc, relpath:newFile('acrolinx/users', $fileName)) }; The offending function is util:logToConsole(), which is declared as: declare %updating function util:logToConsole( $functionName as xs:string, $message as xs:string, $logLevel as xs:string ) { let $logMessage as xs:string := '[' || upper-case($logLevel) || '] ' || $functionName || '(): ' || $message return ( update:output(prof:dump($logMessage)) , update:output($logMessage) ) }; This is declared as an updating function and returns “updating” functions. If I comment out the call to util:logToConsole() in the first function, then BaseX is happy. If I use the non-updating version of logToConsole(), util:logToLog(), then BaseX is also happy. So my question is: why is BaseX complaining about the use of this updating function in an updating function? There must be some subtlety that I’m missing but I have not yet figured out what it is. Thanks, Eliot Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.com<https://www.servicenow.com> LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
CG
Christian Grün21 Aug 2023 16:47 #
Quoted text · Eliot Kimber · 5 lines
> > I guess my confusion is why this requirement is imposed in the context of > a let expression? It cannot be the case that let expressions must be > updating in the context of an updating function. >
True, there are different checks: The inner check isn't aware of the let context, it merely matches the (non)updating statuses of try and catch. The outer check ensures that the expression defined in the let clause is not updating.
You can disable the strict W3 XQUF semantics by enabling the BaseX-specific
MIXUPDATES option.EK
Eliot Kimber21 Aug 2023 16:50 #
Given this limitation on try/catch, seems like the better design for my code would be to return a map with result and errors and check for errors in the updating code.
Cheers,
E.
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>
Quoted text · Christian Grün · 9 lines
From: Christian Grün <christian.gruen at gmail.com> Date: Monday, August 21, 2023 at 9:47 AM To: Eliot Kimber <eliot.kimber at servicenow.com> Cc: BaseX <basex-talk at mailman.uni-konstanz.de> Subject: Re: [basex-talk] "Expressions must be all updating" puzzle [External Email] I guess my confusion is why this requirement is imposed in the context of a let expression? It cannot be the case that let expressions must be updating in the context of an updating function. True, there are different checks: The inner check isn't aware of the let context, it merely matches the (non)updating statuses of try and catch. The outer check ensures that the expression defined in the let clause is not updating. You can disable the strict W3 XQUF semantics by enabling the BaseX-specific MIXUPDATES option.
Written for BaseX 10.7. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery