Hi all, on the way to writing a small DSL I stumbled upon the following BaseX 7.6 issue. I'm not able to explain to myself why the first two expressions of the following xquery module return correctly whereas the last yields NullPointerException (as shown in the appended stacktrace). What I'm mtrying to do is to wrap up some modification code into userfriendly function calls that can be used in mini xquery scripts to formalize xml workflow. Thank you for any help, Marco.
declare variable $globals := map { 'change' := local:change#1, 'generate' := local:gen#0 };
declare function local:gen(){ <b/> };
declare function local:change($doc){ copy $newdoc := $doc modify( insert node <a/> as last into $newdoc ) return $newdoc };
( xquery:eval("copy $newdoc := <b/> modify( insert node <a/> as last into $newdoc ) return $newdoc",$globals),
xquery:eval("$generate()", $globals), xquery:eval("$change($doc)", map:new( ($globals, map { "doc" := <b/>}))) )
The stacktrace and query plan:
Error: Improper use? Potential bug? Your feedback is welcome: Contact: basex-talk@mailman.uni-konstanz.de Version: BaseX 7.6 Java: Oracle Corporation, 1.7.0_15 OS: Linux, i386 Stack Trace: java.lang.NullPointerException org.basex.query.up.expr.Transform.value(Transform.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.UserFunc.value(UserFunc.java:175) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.BaseFuncCall.value(BaseFuncCall.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.value.item.FuncItem.invValue(FuncItem.java:104) org.basex.query.func.DynamicFunc.value(DynamicFunc.java:56) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.QueryContext.value(QueryContext.java:254) org.basex.query.func.FNXQuery.eval(FNXQuery.java:95) org.basex.query.func.FNXQuery.eval(FNXQuery.java:71) org.basex.query.func.FNXQuery.iter(FNXQuery.java:37) org.basex.query.QueryContext.iter(QueryContext.java:285) org.basex.query.expr.List$1.next(List.java:100) org.basex.query.QueryContext.execute(QueryContext.java:524) org.basex.query.QueryProcessor.execute(QueryProcessor.java:96) org.basex.core.cmd.AQuery.query(AQuery.java:77) org.basex.core.cmd.XQuery.run(XQuery.java:22) org.basex.core.Command.run(Command.java:342) org.basex.core.Command.exec(Command.java:321) org.basex.core.Command.execute(Command.java:78) org.basex.gui.GUI.exec(GUI.java:397) org.basex.gui.GUI$7.run(GUI.java:349) Compiling: - pre-evaluating map { "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } } Optimized Query: declare function local:change($doc) { copy $newdoc as node() := $doc modify insert node element a { () } into $newdoc return $newdoc }; declare function local:gen() { element b { () } }; (xquery:eval("copy $newdoc := $generate() modify( insert node <a/> as last into $newdoc ) return $newdoc", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$generate()", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$change($doc)", map:new((map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }, map { "doc":=element b { () } })))) Query plan: <QueryPlan> <UserFuncs> <UserFunc name="local:change" arg0="doc"> <Transform> <Let var="$newdoc as node()"> <VarRef> <Var name="$doc" id="2"/> </VarRef> </Let> <Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> <CElem> <QNm value="a" type="xs:QName"/> </CElem> </Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> </Transform> </UserFunc> <UserFunc name="local:gen"> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </UserFunc> </UserFuncs> <VarStack> <Var name="$globals" id="0"/> </VarStack> <List> <FNXQuery name="eval(string[,bindings])"> <Str value="copy $newdoc := $generate()
 modify(
 insert node <a/> as last into $newdoc 
 )
 return $newdoc" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$generate()" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$change($doc)" type="xs:string"/> <FNMap name="new([maps[,coll]])"> <List> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> <LitMap> <Str value="doc" type="xs:string"/> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </LitMap> </List> </FNMap> </FNXQuery> </List> </QueryPlan>
Surely looks like a bug [1]. I’d be interested if you have tried to build your query without xquery:eval. It may be worth noting that all queries using eval() calls are hardly optimizable, because a dynamically built query can do lots of unexpected things (excluding, thankfully, updates).
[1] https://github.com/BaseXdb/basex/issues/662 ___________________________
On Thu, Mar 14, 2013 at 3:35 PM, Marco Lettere marco.lettere@dedalus.eu wrote:
Hi all, on the way to writing a small DSL I stumbled upon the following BaseX 7.6 issue. I'm not able to explain to myself why the first two expressions of the following xquery module return correctly whereas the last yields NullPointerException (as shown in the appended stacktrace). What I'm mtrying to do is to wrap up some modification code into userfriendly function calls that can be used in mini xquery scripts to formalize xml workflow. Thank you for any help, Marco.
declare variable $globals := map { 'change' := local:change#1, 'generate' := local:gen#0 };
declare function local:gen(){
<b/> };
declare function local:change($doc){ copy $newdoc := $doc modify( insert node <a/> as last into $newdoc ) return $newdoc };
( xquery:eval("copy $newdoc := <b/> modify( insert node <a/> as last into $newdoc ) return $newdoc",$globals),
xquery:eval("$generate()", $globals), xquery:eval("$change($doc)", map:new( ($globals, map { "doc" := <b/>}))) )
The stacktrace and query plan:
Error: Improper use? Potential bug? Your feedback is welcome: Contact: basex-talk@mailman.uni-konstanz.de Version: BaseX 7.6 Java: Oracle Corporation, 1.7.0_15 OS: Linux, i386 Stack Trace: java.lang.NullPointerException org.basex.query.up.expr.Transform.value(Transform.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.UserFunc.value(UserFunc.java:175) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.BaseFuncCall.value(BaseFuncCall.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.value.item.FuncItem.invValue(FuncItem.java:104) org.basex.query.func.DynamicFunc.value(DynamicFunc.java:56) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.QueryContext.value(QueryContext.java:254) org.basex.query.func.FNXQuery.eval(FNXQuery.java:95) org.basex.query.func.FNXQuery.eval(FNXQuery.java:71) org.basex.query.func.FNXQuery.iter(FNXQuery.java:37) org.basex.query.QueryContext.iter(QueryContext.java:285) org.basex.query.expr.List$1.next(List.java:100) org.basex.query.QueryContext.execute(QueryContext.java:524) org.basex.query.QueryProcessor.execute(QueryProcessor.java:96) org.basex.core.cmd.AQuery.query(AQuery.java:77) org.basex.core.cmd.XQuery.run(XQuery.java:22) org.basex.core.Command.run(Command.java:342) org.basex.core.Command.exec(Command.java:321) org.basex.core.Command.execute(Command.java:78) org.basex.gui.GUI.exec(GUI.java:397) org.basex.gui.GUI$7.run(GUI.java:349) Compiling:
- pre-evaluating map { "change":=function($1) as item()* {
local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } } Optimized Query: declare function local:change($doc) { copy $newdoc as node() := $doc modify insert node element a { () } into $newdoc return $newdoc }; declare function local:gen() { element b { () } }; (xquery:eval("copy $newdoc := $generate() modify( insert node <a/> as last into $newdoc ) return $newdoc", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$generate()", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$change($doc)", map:new((map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }, map { "doc":=element b { () } })))) Query plan:
<QueryPlan> <UserFuncs> <UserFunc name="local:change" arg0="doc"> <Transform> <Let var="$newdoc as node()"> <VarRef> <Var name="$doc" id="2"/> </VarRef> </Let> <Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> <CElem> <QNm value="a" type="xs:QName"/> </CElem> </Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> </Transform> </UserFunc> <UserFunc name="local:gen"> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </UserFunc> </UserFuncs> <VarStack> <Var name="$globals" id="0"/> </VarStack> <List> <FNXQuery name="eval(string[,bindings])"> <Str value="copy $newdoc := $generate()
 modify(
 insert node <a/> as last into $newdoc 
 )
 return $newdoc" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$generate()" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$change($doc)" type="xs:string"/> <FNMap name="new([maps[,coll]])"> <List> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> <LitMap> <Str value="doc" type="xs:string"/> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </LitMap> </List> </FNMap> </FNXQuery> </List> </QueryPlan>
BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
Hi Marco,
the discussed bug [1] has now been fixed. Sorry for the delay.
Best, Christian
[1] https://github.com/BaseXdb/basex/issues/662 ___________________________
On Mon, Mar 18, 2013 at 3:59 PM, Christian Grün christian.gruen@gmail.com wrote:
Surely looks like a bug [1]. I’d be interested if you have tried to build your query without xquery:eval. It may be worth noting that all queries using eval() calls are hardly optimizable, because a dynamically built query can do lots of unexpected things (excluding, thankfully, updates).
[1] https://github.com/BaseXdb/basex/issues/662 ___________________________
On Thu, Mar 14, 2013 at 3:35 PM, Marco Lettere marco.lettere@dedalus.eu wrote:
Hi all, on the way to writing a small DSL I stumbled upon the following BaseX 7.6 issue. I'm not able to explain to myself why the first two expressions of the following xquery module return correctly whereas the last yields NullPointerException (as shown in the appended stacktrace). What I'm mtrying to do is to wrap up some modification code into userfriendly function calls that can be used in mini xquery scripts to formalize xml workflow. Thank you for any help, Marco.
declare variable $globals := map { 'change' := local:change#1, 'generate' := local:gen#0 };
declare function local:gen(){
<b/> };
declare function local:change($doc){ copy $newdoc := $doc modify( insert node <a/> as last into $newdoc ) return $newdoc };
( xquery:eval("copy $newdoc := <b/> modify( insert node <a/> as last into $newdoc ) return $newdoc",$globals),
xquery:eval("$generate()", $globals), xquery:eval("$change($doc)", map:new( ($globals, map { "doc" := <b/>}))) )
The stacktrace and query plan:
Error: Improper use? Potential bug? Your feedback is welcome: Contact: basex-talk@mailman.uni-konstanz.de Version: BaseX 7.6 Java: Oracle Corporation, 1.7.0_15 OS: Linux, i386 Stack Trace: java.lang.NullPointerException org.basex.query.up.expr.Transform.value(Transform.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.UserFunc.value(UserFunc.java:175) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.func.BaseFuncCall.value(BaseFuncCall.java:68) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.value.item.FuncItem.invValue(FuncItem.java:104) org.basex.query.func.DynamicFunc.value(DynamicFunc.java:56) org.basex.query.QueryContext.value(QueryContext.java:296) org.basex.query.QueryContext.value(QueryContext.java:254) org.basex.query.func.FNXQuery.eval(FNXQuery.java:95) org.basex.query.func.FNXQuery.eval(FNXQuery.java:71) org.basex.query.func.FNXQuery.iter(FNXQuery.java:37) org.basex.query.QueryContext.iter(QueryContext.java:285) org.basex.query.expr.List$1.next(List.java:100) org.basex.query.QueryContext.execute(QueryContext.java:524) org.basex.query.QueryProcessor.execute(QueryProcessor.java:96) org.basex.core.cmd.AQuery.query(AQuery.java:77) org.basex.core.cmd.XQuery.run(XQuery.java:22) org.basex.core.Command.run(Command.java:342) org.basex.core.Command.exec(Command.java:321) org.basex.core.Command.execute(Command.java:78) org.basex.gui.GUI.exec(GUI.java:397) org.basex.gui.GUI$7.run(GUI.java:349) Compiling:
- pre-evaluating map { "change":=function($1) as item()* {
local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } } Optimized Query: declare function local:change($doc) { copy $newdoc as node() := $doc modify insert node element a { () } into $newdoc return $newdoc }; declare function local:gen() { element b { () } }; (xquery:eval("copy $newdoc := $generate() modify( insert node <a/> as last into $newdoc ) return $newdoc", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$generate()", map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }), xquery:eval("$change($doc)", map:new((map{ "change":=function($1) as item()* { local:change(($1)) }, "generate":=function() as item()* { local:gen(()) } }, map { "doc":=element b { () } })))) Query plan:
<QueryPlan> <UserFuncs> <UserFunc name="local:change" arg0="doc"> <Transform> <Let var="$newdoc as node()"> <VarRef> <Var name="$doc" id="2"/> </VarRef> </Let> <Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> <CElem> <QNm value="a" type="xs:QName"/> </CElem> </Insert> <VarRef> <Var name="$newdoc as node()" id="3"/> </VarRef> </Transform> </UserFunc> <UserFunc name="local:gen"> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </UserFunc> </UserFuncs> <VarStack> <Var name="$globals" id="0"/> </VarStack> <List> <FNXQuery name="eval(string[,bindings])"> <Str value="copy $newdoc := $generate()
 modify(
 insert node <a/> as last into $newdoc 
 )
 return $newdoc" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$generate()" type="xs:string"/> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> </FNXQuery> <FNXQuery name="eval(string[,bindings])"> <Str value="$change($doc)" type="xs:string"/> <FNMap name="new([maps[,coll]])"> <List> <Map size="2"> <Str value="change" type="xs:string"/> <FuncItem type="function(item()*) as item()*"> <Var name="$1" id="1"/> <BaseFuncCall name="local:change(($1))"> <VarRef> <Var name="$1" id="1"/> </VarRef> </BaseFuncCall> </FuncItem> <Str value="generate" type="xs:string"/> <FuncItem type="function() as item()*"> <BaseFuncCall name="local:gen(())"/> </FuncItem> </Map> <LitMap> <Str value="doc" type="xs:string"/> <CElem> <QNm value="b" type="xs:QName"/> </CElem> </LitMap> </List> </FNMap> </FNXQuery> </List> </QueryPlan>
BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
basex-talk@mailman.uni-konstanz.de