Reputation: 192
Below is the sample code where $p2
is an optional external parameter
(i.e. with ? modifier
); the code gives XDMP-ARG: -- vars is invalid
exception when empty sequence-()
is passed against $p2
.
Tried it on Marklogic 8 & 9
let $query :=
"
declare variable $p1 as node()? external;
declare variable $p2 as node()? external;
(
if($p1) then xdmp:log('P1') else ()
,
if($p2) then xdmp:log('P2') else ()
)
"
let $p1 := <p></p>
let $p2 := ()
return
xdmp:eval(
$query,
(xs:QName('p1'), $p1, xs:QName('p2'), $p2)
)
I expected the code to run and print logs. Can I get some deep insights into how the exception occurred?
Upvotes: 0
Views: 192
Reputation: 3732
A less-clean alternatives is to use a special marker value to represent 'empty' instead of a literal empty sequence -- which as HTH says, is not preserved when passed IN another sequence (not only do sequences not 'nest' but empty sequences are not 'countable' or 'identifiable' values exactly -- don't know the precise term).
this should demonstrate:
let $x := ( 1 , () , () , 2 )
$x is now a sequence of length 2 not 4, empty sequences resolve to nothing and the containing sequence 'collapses' (removes the slot, not putting a kind of 'null' value in it)
So a approach in general can be used which you substitute a 'empty token' of some kind. like
declare variable $empty := <empty/>
(: ANY single value or node type will work that is type compatible with non-empty uses :)
Now
let $x := (1,$empty,$empty,2) (: sequence length 4 :)
and thus you can pass to eval() replacing () with $empty. The called code needs a test against $empty as well
if( $p1 != $empty ) then xdmp:log("P1 is" , $p1 )
This technique is used sometimes to create sparse tree structures like binary trees, red/black trees etc.
HTH's solution is better. (this just demonstrates an alternative to help understand the core issue better)
Upvotes: 1
Reputation: 20414
If you pass in vars as a Sequence of key,val,key,val it needs to be even (multiple of 2). You can't embed sequences like that, as nested sequences get flattened automatically in XQuery. Pass in your vars using a map:map:
map:new((
map:entry("p1", $p1),
map:entry("p2", $p2),
))
HTH!
Upvotes: 5