Exist: Functional XQuery causes NullPointerException

Created on 14 Jan 2019  路  6Comments  路  Source: eXist-db/exist

The following XQuery causes a NullPointerException:

declare namespace io = "http://io";

(: IO version of get-char :)
declare function local:get-char() as map(*) {
  local:create-io(function($realworld as element(io:realworld)) {
    ($realworld,
       123)
  })
};

(: IO version of put-char :)
declare function local:put-char($codepoint as xs:integer) as map(*) {
  local:create-io(function($realworld as element(io:realworld)) {
    ($realworld,
        ())
  })
};

declare function local:create-io($apply-fn as function(element(io:realworld)) as item()+) as map(*) {
  map {
    'apply': $apply-fn,
    'bind' : function($binder as function(item()*) as map(*)) as map(*) {
      let $bound-apply-fn := function($realworld) {
        let $io-res := $apply-fn($realworld)
        let $new-world := $io-res[1]
        let $res := subsequence($io-res, 2)
        return
          $binder($res)("apply")($new-world)
      }
      return
        local:create-io($bound-apply-fn)
    }
  }
};

let $x :=
        local:get-char()
          ?bind(local:put-char#1)
return $x?apply(<io:realworld/>)

The query should return the value <io:realworld xmlns:io="http://io"/> as it does in both BaseX and Saxon.

In eXist-db the following Java stacktrace is the result of the NPE:

Exception in thread "java-admin-client-0.query-0" java.lang.NullPointerException
    at org.exist.xquery.AnalyzeContextInfo.<init>(AnalyzeContextInfo.java:70)
    at org.exist.xquery.DynamicFunctionCall.eval(DynamicFunctionCall.java:73)
    at org.exist.xquery.LetExpr.eval(LetExpr.java:99)
    at org.exist.xquery.UserDefinedFunction.eval(UserDefinedFunction.java:162)
    at org.exist.xquery.FunctionCall$DeferredFunctionCallImpl.execute(FunctionCall.java:434)
    at org.exist.xquery.DeferredFunctionCall.realize(DeferredFunctionCall.java:57)
    at org.exist.xquery.DeferredFunctionCall.isEmpty(DeferredFunctionCall.java:199)
    at org.exist.xmldb.LocalResourceSet.<init>(LocalResourceSet.java:58)
    at org.exist.xmldb.LocalXPathQueryService.execute(LocalXPathQueryService.java:224)

The problem seems to be that Expr#analyze is not called on the body of the UserDefinedFunction.

bug

Most helpful comment

@adamretter interesting implementation!
Slightly modified, your example does output the expected value in eXist-db as well.
https://gist.github.com/line-o/d60f286383dd74db48b40478f4cea5cd

All 6 comments

@adamretter interesting implementation!
Slightly modified, your example does output the expected value in eXist-db as well.
https://gist.github.com/line-o/d60f286383dd74db48b40478f4cea5cd

@line-o That's a great work around thank you. How the hell did you figure out that would work though?

@adamretter try and error while figuring out what your code actually does :)

@adamretter I thought: "Maybe, less inline functions could help me and the parser understand"

@line-o nice.
@adamretter NPE are bad, can you wiggle down the sample query into an xqsuite test, so we can see more clearly what causes it?

P.S.: Ran both queries and get the same results NPE for a) and desired output for b).

any news?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bpolitycki picture Bpolitycki  路  4Comments

mathias-goebel picture mathias-goebel  路  4Comments

adamretter picture adamretter  路  4Comments

lguariento picture lguariento  路  5Comments

adamretter picture adamretter  路  6Comments