Exist: AssertFailure when addressing comment nodes outside root elements for db documents

Created on 7 May 2015  路  13Comments  路  Source: eXist-db/exist

I can confirm the issue reported at http://stackoverflow.com/questions/30086095/select-comments-before-root-node with a fresh build of eXist from the current develop branch.

Reproducible test:

Store the following document as /db/test.xml

<!-- DOCUMENT REVIEWED -->
<doc id="test">
  <figure>
    <figcaption>caption</figcaption>
  </figure>
  <p>blah blah blah</p>
</doc>

The following query will fail:

doc('/db/test.xml')/node()[2]/preceding-sibling::comment()

Expected result:

<!-- DOCUMENT REVIEWED -->

Actual result, as reported in exist.log:

2015-05-06 20:28:36,739 [eXistThread-50] WARN  (SanityCheck.java [showTrace]:94) - Stacktrace:
org.exist.util.sanity.AssertFailure: TRACE: Node 891:null not found.
    at org.exist.util.sanity.SanityCheck.TRACE(SanityCheck.java:73)
    at org.exist.storage.dom.DOMFile.findValue(DOMFile.java:1265)
    at org.exist.storage.dom.RawNodeIterator.seek(RawNodeIterator.java:84)
    at org.exist.storage.dom.RawNodeIterator.<init>(RawNodeIterator.java:71)
    at org.exist.storage.NativeBroker.getXMLStreamReader(NativeBroker.java:545)
    at org.exist.xquery.LocationStep.getSiblings(LocationStep.java:899)
    at org.exist.xquery.LocationStep.eval(LocationStep.java:449)
    at org.exist.xquery.AbstractExpression.eval(AbstractExpression.java:71)
    at org.exist.xquery.PathExpr.eval(PathExpr.java:265)
    at org.exist.xquery.AbstractExpression.eval(AbstractExpression.java:71)
    at org.exist.xquery.XQuery.execute(XQuery.java:298)
    at org.exist.xquery.XQuery.execute(XQuery.java:218)
    at org.exist.http.servlets.XQueryServlet.process(XQueryServlet.java:492)
    at org.exist.http.servlets.XQueryServlet.doPost(XQueryServlet.java:198)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:457)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:229)
    at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:103)
    at org.exist.http.urlrewrite.Forward.doRewrite(Forward.java:50)
    at org.exist.http.urlrewrite.XQueryURLRewrite.doRewrite(XQueryURLRewrite.java:557)
    at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:357)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:669)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1448)
    at de.betterform.agent.web.filter.XFormsFilter.doFilter(XFormsFilter.java:171)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1419)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:368)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:488)
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:943)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1004)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:861)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:745)

On the other hand, the in-memory version of this query returns the expected result:

let $doc := 
    document { 
        <!-- DOCUMENT REVIEWED -->,
        <doc id="test">
          <figure>
            <figcaption>caption</figcaption>
          </figure>
          <p>blah blah blah</p>
        </doc>
    }
return 
    $doc/node()[2]/preceding-sibling::comment()

Result:

<!-- DOCUMENT REVIEWED -->

On a perhaps related note, eXide returns unexpected results when displaying the in-database version of this document - seemingly because of the presence of the comment:

doc('/db/test.xml')

eXide reports that this returns one node, but only displays:

<!-- DOCUMENT REVIEWED -->

I would expect to see the entire document, but only the comment displays.

This variant returns expected results - 2 items, the comment node and the node:

doc('/db/test.xml')/node()

So all in all, eXist seems to have some issues handling comments outside the root element of the document.

bug

Most helpful comment

I think I have fixed this here: https://github.com/adamretter/exist/commit/15bed5a55950f5e830ef1e019c9752fabd4ad737 I hope to send a Pull Request soon.

All 13 comments

I've just performed the test with 4.1.0-SNAPSHOT (current develop) and confirmed that this problem is still present.

@joewiz I've noticed my logs are flooded with similar warnings (eXist-4.0.0, deployed in Tomcat-7.0.85). Despite the warnings, I haven't seen anything suspicious in the results returned, though. And while it's also Sanitycheck.java that seems to be throwing the warning, I've noticed how Saxon seems to be involved (I'm transforming query results via transform:transform()), so I don't know if it's 100% related:

2018-03-08 10:21:17,105 [ajp-bio-8060-exec-17] WARN  (DOMFile.java [get]:1436) - org.exist.storage.btree.BTreeException: Node 0 not found. 
2018-03-08 10:21:17,109 [ajp-bio-8060-exec-17] WARN  (SanityCheck.java [showTrace]:94) - Stacktrace:
org.exist.util.sanity.AssertFailure: TRACE: Node 1082:0 not found.
  at org.exist.util.sanity.SanityCheck.TRACE(SanityCheck.java:73)
  at org.exist.storage.dom.DOMFile.findValue(DOMFile.java:1294)
  at org.exist.storage.dom.DOMFile.get(DOMFile.java:1430)
  at org.exist.storage.NativeBroker$15.start(NativeBroker.java:3528)
  at org.exist.storage.dom.DOMTransaction.run(DOMTransaction.java:110)
  at org.exist.storage.NativeBroker.objectWith(NativeBroker.java:3540)
  at org.exist.dom.persistent.StoredNode.getNextSibling(StoredNode.java:324)
  at net.sf.saxon.dom.DOMNodeWrapper.getSuccessorNode(DOMNodeWrapper.java:929)
  at net.sf.saxon.dom.DOMNodeWrapper.getSuccessorElement(DOMNodeWrapper.java:899)
  at net.sf.saxon.dom.DOMNodeWrapper.getSuccessorElement(DOMNodeWrapper.java:41)
  at net.sf.saxon.tree.util.SteppingNavigator$FollowingElementStepper.step(SteppingNavigator.java:157)
  at net.sf.saxon.tree.util.SteppingNavigator$DescendantAxisIterator.next(SteppingNavigator.java:270)
  at net.sf.saxon.tree.util.SteppingNavigator$DescendantAxisIterator.next(SteppingNavigator.java:197)
  at net.sf.saxon.om.FocusTrackingIterator.next(FocusTrackingIterator.java:61)
  at net.sf.saxon.expr.ContextMappingIterator.next(ContextMappingIterator.java:59)
  at net.sf.saxon.value.SequenceExtent.<init>(SequenceExtent.java:89)
  at net.sf.saxon.value.SequenceExtent.makeSequenceExtent(SequenceExtent.java:113)
  at net.sf.saxon.expr.instruct.GlobalVariable.getSelectValue(GlobalVariable.java:635)
  at net.sf.saxon.expr.instruct.GlobalVariable.actuallyEvaluate(GlobalVariable.java:710)
  at net.sf.saxon.expr.instruct.GlobalParam.evaluateVariable(GlobalParam.java:90)
  at net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:100)
  at net.sf.saxon.expr.VariableReference.iterate(VariableReference.java:444)
  at net.sf.saxon.expr.AdjacentTextNodeMerger.iterate(AdjacentTextNodeMerger.java:201)
  at net.sf.saxon.expr.Atomizer.iterate(Atomizer.java:303)
  at net.sf.saxon.expr.AtomicSequenceConverter.iterate(AtomicSequenceConverter.java:228)
  at net.sf.saxon.functions.FoldingFunction.evaluateItem(FoldingFunction.java:54)
  at net.sf.saxon.functions.Concat.evaluateItem(Concat.java:88)
  at net.sf.saxon.functions.Concat.evaluateAsString(Concat.java:77)
  at net.sf.saxon.expr.instruct.SimpleNodeConstructor.processLeavingTail(SimpleNodeConstructor.java:216)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:822)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:419)
  at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:668)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Template.expand(Template.java:367)
  at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:343)
  at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:397)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:336)
  at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1124)
  at net.sf.saxon.expr.instruct.ApplyTemplates$ApplyTemplatesPackage.processLeavingTail(ApplyTemplates.java:500)
  at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:345)
  at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:397)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Template.expand(Template.java:367)
  at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:343)
  at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:397)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:336)
  at net.sf.saxon.expr.instruct.NextMatch$NextMatchPackage.processLeavingTail(NextMatch.java:198)
  at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:270)
  at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:228)
  at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:822)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Template.expand(Template.java:367)
  at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:343)
  at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:397)
  at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:669)
  at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:144)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:450)
  at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:389)
  at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:336)
  at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1124)
  at net.sf.saxon.Controller.transformDocument(Controller.java:2106)
  at net.sf.saxon.Controller.transform(Controller.java:1704)
  at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:547)
  at net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:177)
  at net.sf.saxon.jaxp.TransformerHandlerImpl.endDocument(TransformerHandlerImpl.java:173)
  at org.exist.util.serializer.ReceiverToSAX.endDocument(ReceiverToSAX.java:81)
  at org.exist.storage.serializers.XIncludeFilter.endDocument(XIncludeFilter.java:161)
  at org.exist.util.serializer.SAXToReceiver.endDocument(SAXToReceiver.java:56)
  at org.apache.xerces.parsers.AbstractSAXParser.endDocument(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentScannerImpl.endEntity(Unknown Source)
  at org.apache.xerces.impl.XMLEntityManager.endEntity(Unknown Source)
  at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
  at org.apache.xerces.impl.XMLEntityScanner.skipSpaces(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentScannerImpl$TrailingMiscDispatcher.dispatch(Unknown Source)
  at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
  at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
  at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
  at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
  at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
  at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
  at org.exist.http.servlets.XSLTServlet.doPost(XSLTServlet.java:266)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
  at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
  at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:378)
  at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
  at org.exist.http.urlrewrite.Forward.doRewrite(Forward.java:50)
  at org.exist.http.urlrewrite.XQueryURLRewrite.doRewrite(XQueryURLRewrite.java:548)
  at org.exist.http.urlrewrite.XQueryURLRewrite.applyViews(XQueryURLRewrite.java:413)
  at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:359)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
  at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
  at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:193)
  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
  at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)

@joewiz On closer examination, my Saxon-related warnings (obviously) were triggered by the use of the doc() function in an XSLT stylesheet, with a relative path that resolves to a document stored in the db. The AssertFailure appears to be triggered when any node type is retrieved from a document containing a comment that precedes the document element.

So far, I haven't found a workaround for the AssertFailure warning, unfortunately: anytime such a document tree is traversed, the warning is triggered (e.g. doc('/db/test.xml')/root()/*, (doc('/db/test.xml')//*[1])).

Yet, in testimony to the fact that eXist has a problem w.r.t. the node types, see these expressions:

  • doc('/db/test.xml')/self::* should return the empty node set, but instead eXist returns:

  • doc('/db/test.xml')/node()/self::* should return the <doc> element, but instead eXist returns both the comment and the <doc> element:




    caption


    blah blah blah


@rvdb Wow, this is troubling! I keep bumping into this issue too.

@joewiz I've been able to find a workaround avoiding the AssertFailure warning in XSLT processing. The problem manifested itself when creating an XSLT variable directly from a document, as in:

<xsl:variable name="menu.content" select="doc('menu.xml')"/>

Traversal of this $menu.content tree (e.g. <xsl:apply-templates select="$menu.content//item"/>) produces the AssertFailure warning in the logs (even though everything is working as expected).

Now, if this same variable is created indirectly, as in:

<xsl:variable name="menu.content">
  <xsl:copy-of select="doc('menu.xml')"/>
</xsl:variable>

... this $menu.context tree _can_ be traversed without triggering the warning. This reminds me of behaviour I'd reported in a previous bug (https://github.com/eXist-db/exist/issues/214, which seems to have been fixed in the mean time).

I don't know if this indirect variable counts as moving the node tree in-memory, thus avoiding access from the database. It seems to be in line with your observations concerning retrieval of database-stored nodes vs. in-memory nodes, but I don't know if they're closely related.

Ahh, and look what happens with an equivalent XQuery "isolation" of the doc() content into an own root node:

let $doc := document { doc('/db/test.xml') }
return $doc/node()[2]/preceding-sibling::comment()

This does produce the expected result, without AssertFailure warning:

<!-- DOCUMENT REVIEWED -->

It seems direct retrieval from the db vs in-memory access _is_ key.

@joewiz And notice, how this expression _does_ produce the correct node with your example:

doc('/db/test.xml')/node()[2]/preceding::comment()

The mystery deepens...

I think I have fixed this here: https://github.com/adamretter/exist/commit/15bed5a55950f5e830ef1e019c9752fabd4ad737 I hope to send a Pull Request soon.

@joewiz Okay my PR which might help with this is here - https://github.com/eXist-db/exist/pull/2113 please can you test?

@adamretter Building #2113 and running my original test shows that your PR fixes the problem in the original post. However, a test in one of @rvdb's comments is still failing. I'll adapt it to the following code to demonstrate the failure:

xquery version "3.1";

let $in-mem := document { 
    <!-- DOCUMENT REVIEWED -->,
    <doc id="test">
      <p>blah blah blah</p>
    </doc>
}
let $store := xmldb:store("/db", "test.xml", $in-mem)
return
    doc('/db/test.xml')/self::attribute()

... returns a result - of type document-node()! - instead of the expected result (empty sequence). Change self::attribute() to any node kind test - e.g., self::comment(), self::element(), self::processing-instruction - and the result is the same: the query returns the document node. Same result if you remove the comment node.

However, if you change the query to return $in-mem/self::attribute() (thus querying the in-memory version instead of the on-disk version), the expected result (empty sequence) is returned. So the problem remains limited to queries of the database.

Do you see this as a separate issue from the original one? If so, I can file a new issue - "Node kind test bug with document-node in database". (I'll link to the possibly related issues: https://github.com/eXist-db/exist/issues/1463 and https://github.com/eXist-db/exist/issues/1562.)

@joewiz Definitely a separate issue, but I have fixed it anyway :-)

@adamretter would this require a 4.4 release? Should this only be ported to 5.0.0? I would imagine that many apps rely on the bugged behaviour.

@duncdrum there will be a backport PR shortly for 4.x.x and 5.0.0.

Was this page helpful?
0 / 5 - 0 ratings