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
>

Reply via email to