Project

Profile

Help

Bug #2550

closed

No watch found for xsl:element

Added by Gunther Rademacher over 8 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Streaming
Sprint/Milestone:
-
Start date:
2015-12-17
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.7
Fix Committed on Branch:
9.7
Fixed in Maintenance Release:
Platforms:

Description

This XQuery

for $x in saxon:stream(doc('uriresolver:resolve')/*/*/element {node-name()} {node()}) return $x

did not qualify for streaming in 9.6, but fell back to non-streaming mode.

With 9.7, it throws this exception:

net.sf.saxon.s9api.SaxonApiUncheckedException: No watch found for xsl:element
	at net.sf.saxon.s9api.XdmSequenceIterator.hasNext(XdmSequenceIterator.java:66)
	at net.sf.saxon.s9api.XdmSequenceIterator.next(XdmSequenceIterator.java:90)
	at NonStreamableQuery.testNonStreamableQueryUsingSaxonStream(NonStreamableQuery.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: net.sf.saxon.trans.XPathException: No watch found for xsl:element
	at com.saxonica.ee.bytecode.util.Callback.makeXPathException(Callback.java:143)
	at gen_SlashContextMappingFunction_1.map(Unknown Source)
	at net.sf.saxon.expr.ContextMappingIterator.next(ContextMappingIterator.java:61)
	at net.sf.saxon.query.XQueryExpression$ErrorReportingIterator.next(XQueryExpression.java:846)
	at net.sf.saxon.s9api.XdmSequenceIterator.hasNext(XdmSequenceIterator.java:57)
	... 26 more
Actions #1

Updated by Michael Kay over 8 years ago

  • Status changed from New to In Progress

Note, replacing "for $x in XXX return $x" by the simpler expression XXX gives a different internal error.

My first reaction is that I may have to document restrictions here. saxon:stream() is designed to deliver a subset of XSLT's streaming capability to XQuery users, but this example is doing things that don't map directly to anything in XSLT, and where it's therefore not possible to rely on all the streamability analysis available for the XSLT case.

Actions #2

Updated by Michael Kay over 8 years ago

The test becomes streamable if it is rewritten as

for $x in saxon:stream(doc('uri')/*/*)/element {node-name()} {node()} return $x"

or equivalently

saxon:stream(doc('uri')/*/*)/element {node-name()} {node()}

Note the changed position of the closing paren.

There's a fundamental difference here: the way you wrote the query, you were trying to apply streaming to a sequence of constructed element nodes; the way I rewrote it, streaming is applied to a sequence of input nodes, and for each of these, a new element node is constructed.

I'm going to see if I can find a way to improve the diagnostics on this, but I'm not going to attempt to make it actually work.

Actions #3

Updated by Michael Kay over 8 years ago

The query can also be made streamable by changing it to

saxon:stream(doc('uri')/*/*/element {node-name()} {copy-of(node())})

which suggests that a possible solution is to insert the copy-of() automatically.

With the help of some experimentation I have found that adding a copy-of operation into the inverted evaluation pipeline appears to be safe in the case where:

(a) the parent expression is grounded (e.g. an element constructor)

(b) the child expression is not grounded

(c) the operand usage of the consuming child operand is absorption

(d) the parent expression is not a copy-of() or snapshot() operation

With this change both versions of the query become streamable.

However, another version of the query written as:

streaming("saxon:stream(doc('uri')/*/* ! element {node-name()} {node()})");

fails to terminate, so I will now investigate that one.

Actions #4

Updated by Michael Kay over 8 years ago

  • Category set to Streaming
  • Status changed from In Progress to Resolved
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Fix Committed on Branch 9.7 added

The final version of the expression (using "!") violates the rule that the argument to saxon:stream() must be a path expression, so I won't pursue that one further. Closing this with the change identified, applied to Inversion.java on the 9.7 branch.

Actions #5

Updated by O'Neil Delpratt over 8 years ago

  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 9.7.0.2 added

Bug fix applied in the Saxon 9.7.0.2 maintenance release

Actions #6

Updated by O'Neil Delpratt over 8 years ago

  • Status changed from Resolved to Closed

Please register to edit this issue

Also available in: Atom PDF