Forgot to mention that sending a sequence instead of element() as input to the function local:addPrefix() was intentional to match our production query and should not matter (i think) to recreate the problem.
On Fri, Jun 13, 2014 at 6:06 PM, Srinivasan Muthu <[email protected]> wrote: > We have been using BaseX 7.7 beta for a while and recently we switched to > 7.8.2 and found two queries failed with the existing unit tests. After > research, we found that the query is now getting compiled into a different > optimized query (from 7.7) and results in evaluating a variable, even if > that variable will never be used, as it is inside an IF condition for > particular input. Here is the query: > > ------------------------------------------------------------------ > declare function local:addPrefix($arg as element()?){ > concat("prefix-", $arg) > }; > > let $a := > <a> > <b>1</b> > <b>2</b> > <b>3</b> > </a> > > let $prefixed-data:= <ele>{local:addPrefix($a/b)}</ele> > > return > if (exists($a/c)) then ( > $prefixed-data > ) else ( > 'no input data' > ) > ------------------------------------------------------------------ > > In BaseX 7.7beta the output is 'no input data' which is correct. > Here $prefixed-data does not get evaluated in BaseX 7.7 beta, as > exists($a/c) is FALSE. The optimized query in GUI also shows > '$prefixed-data' variable removed. Here is the optimized query in BaseX 7.7 > beta: > > *Compiling:* > - rewriting for tail calls: Q{ > http://www.w3.org/2005/xquery-local-functions}addPrefix > - rewriting fn:exists($a/c) > - inlining let $prefixed-data := element ele { (local:addPrefix($a/b)) } > - removing variable $prefixed-data > *Optimized Query: * > declare function local:addPrefix($arg as element()?) { > fn:concat("prefix-", $arg) }; > let $a := element a { (element b { ("1") }, element b { ("2") }, element b > { ("3") }) } return if($a/c) then element ele { (local:addPrefix($a/b)) } > else "no input data" > > > ------------------------------------------------------------------ > > In BaseX 7.8.2 the query throws an error. > > In 7.8.2, $prefixed-data gets evaluated even though the 'IF" condition is > FALSE. See optimized query from GUI here: > > *Error:* > Stopped at > C:/source/perforce/PSODepot/health-analyzer/ha-rel504/libs/catalog/src/main/resources/analysis/vsphere/6.5/CO-001/file3, > 1/18: > [XPTY0004] Cannot treat item() sequence as element()?: (<b>...</b>, > <b>...</b>, <b>...</b>). > Compiling: > - inlining Q{http://www.w3.org/2005/xquery-local-functions}addPrefix#1 > - inlining let $arg_3 as element()? := $a_1/b > - simplifying flwor expression > - rewriting fn:exists($a_1/c) > *Query:* > declare function local:addPrefix($arg as element()?){ concat("prefix-", > $arg) }; let $a := <a> <b>1</b> <b>2</b> <b>3</b> </a> let $prefixed-data:= > <ele>{local:addPrefix($a/b)}</ele> return if (exists($a/c)) then ( > $prefixed-data ) else ( 'no input data' ) > *Optimized Query:* > let $a_1 := element a { (element b { ("1") }, element b { ("2") }, element > b { ("3") }) } let $prefixed-data_2 := element ele { (fn:concat("prefix-", > ((: element()?, true :) $a_1/b))) } return if($a_1/c) then $prefixed-data_2 > else "no input data" > Query plan: > <QueryPlan> > <GFLWOR> > <Let> > <Var name="$a" id="1"/> > <CElem> > <QNm value="a" type="xs:QName"/> > <CElem> > <QNm value="b" type="xs:QName"/> > <Str value="1" type="xs:string"/> > </CElem> > <CElem> > <QNm value="b" type="xs:QName"/> > <Str value="2" type="xs:string"/> > </CElem> > <CElem> > <QNm value="b" type="xs:QName"/> > <Str value="3" type="xs:string"/> > </CElem> > </CElem> > </Let> > <Let> > <Var name="$prefixed-data" id="2"/> > <CElem> > <QNm value="ele" type="xs:QName"/> > <FNStr name="concat(atom1,atom2[,...])"> > <Str value="prefix-" type="xs:string"/> > <TypeCheck type="element()?" function="true"> > <IterPath> > <VarRef> > <Var name="$a" id="1"/> > </VarRef> > <IterStep axis="child" test="b"/> > </IterPath> > </TypeCheck> > </FNStr> > </CElem> > </Let> > <If> > <IterPath> > <VarRef> > <Var name="$a" id="1"/> > </VarRef> > <IterStep axis="child" test="c"/> > </IterPath> > <VarRef> > <Var name="$prefixed-data" id="2"/> > </VarRef> > <Str value="no input data" type="xs:string"/> > </If> > </GFLWOR> > </QueryPlan> > > > ------------------------------------------------------------------ > > We wanted to make sure that this is due to the way queries are executed > differently now in BaseX 7.8.2 and not a bug in BaseX 7.8.2. Removing the > unused variable makes sense for optimization purposes, so it looks like 7.7 > was doing the right thing. Can you confirm please? > > Thanks, > Srini >

