Project

Profile

Help

Bug #4298

closed

Uncaught "java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown"

Added by Evan Lenz over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2019-08-23
Due date:
% Done:

100%

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

Description

This problem is in 9.9 but not 9.8. I believe it may have been introduced in a recent minor release, because I believe I had been using an earlier 9.9 version without the problem.

Execute the following legal stylesheet against any input:

<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <xsl:variable name="node" select="//whatever"/>
    <xsl:sequence select="$node/(/foo/string())"/>
  </xsl:template>

</xsl:stylesheet>

Here is the error that resulted:

java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown
        at net.sf.saxon.expr.LocalVariableReference.copy(LocalVariableReference.java:57)
        at net.sf.saxon.expr.SlashExpression.rebuildSteps(SlashExpression.java:1039)
        at net.sf.saxon.expr.SlashExpression.getLeadingSteps(SlashExpression.java:1068)
        at net.sf.saxon.expr.HomogeneityChecker.typeCheck(HomogeneityChecker.java:58)
        at net.sf.saxon.style.StyleElement.typeCheck(StyleElement.java:1555)
        at net.sf.saxon.style.XSLSequence.validate(XSLSequence.java:95)
        at net.sf.saxon.style.StyleElement.validateSubtree(StyleElement.java:1744)
        at net.sf.saxon.style.StyleElement.validateChildren(StyleElement.java:1779)
        at net.sf.saxon.style.StyleElement.validateSubtree(StyleElement.java:1748)
        at net.sf.saxon.style.XSLTemplate.validateSubtree(XSLTemplate.java:595)
        at net.sf.saxon.style.PrincipalStylesheetModule.preprocess(PrincipalStylesheetModule.java:404)
        at net.sf.saxon.style.Compilation.compilePackage(Compilation.java:286)
        at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:259)
        at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:107)
        at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:785)
        at net.sf.saxon.Transform.doTransform(Transform.java:741)
        at net.sf.saxon.Transform.main(Transform.java:80)
Fatal error during transformation: java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown

My workaround is to use the root() function as in root($node)/foo/string(). This successfully avoids the problem.

Actions #1

Updated by Michael Kay over 4 years ago

  • Description updated (diff)

How extraordinary! Thanks for reducing it to such a simple repro. I imagine that the optimizer has attempted to inline the variable $node and has somehow failed to remove an existing reference to the variable. It's probably related to a recent fix in the area of "condional sort expressions" -- expressions of the form $node/(path) where sorting into document order is unnecessary if $node is a singleton.

Actions #2

Updated by Evan Lenz over 4 years ago

Oops, let's try that again. I actually lost it when I submitted it with the wrong formatting and had to reconstruct it from memory. That will teach me to use Preview.

Stylesheet:

<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <xsl:variable name="node" select="//whatever"/>
    <xsl:sequence select="$node/(/foo/string())"/>
  </xsl:template>

</xsl:stylesheet>

Error:

java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown
        at net.sf.saxon.expr.LocalVariableReference.copy(LocalVariableReference.java:57)
        at net.sf.saxon.expr.SlashExpression.rebuildSteps(SlashExpression.java:1039)
        at net.sf.saxon.expr.SlashExpression.getLeadingSteps(SlashExpression.java:1068)
        at net.sf.saxon.expr.HomogeneityChecker.typeCheck(HomogeneityChecker.java:58)
        at net.sf.saxon.style.StyleElement.typeCheck(StyleElement.java:1555)
        at net.sf.saxon.style.XSLSequence.validate(XSLSequence.java:95)
        at net.sf.saxon.style.StyleElement.validateSubtree(StyleElement.java:1744)
        at net.sf.saxon.style.StyleElement.validateChildren(StyleElement.java:1779)
        at net.sf.saxon.style.StyleElement.validateSubtree(StyleElement.java:1748)
        at net.sf.saxon.style.XSLTemplate.validateSubtree(XSLTemplate.java:595)
        at net.sf.saxon.style.PrincipalStylesheetModule.preprocess(PrincipalStylesheetModule.java:404)
        at net.sf.saxon.style.Compilation.compilePackage(Compilation.java:286)
        at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:259)
        at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:107)
        at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:785)
        at net.sf.saxon.Transform.doTransform(Transform.java:741)
        at net.sf.saxon.Transform.main(Transform.java:80)
Fatal error during transformation: java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown

Workaround: root($node)/foo/string()

Actions #3

Updated by Evan Lenz over 4 years ago

Ha! You already fixed the formatting for me, thanks. :-)

Thanks for speculating on the cause too. Interesting stuff.

Being a good citizen and reporting the problem led to my workaround, so now we can immediately go back to using the latest version. Win/win.

Actions #4

Updated by Michael Kay over 4 years ago

My initial guess was a bit off-target, though not totally. There's some early reorganisation of the path expression going on, during the type-checking phase (and thus well before any variable inlining), when it is realised that the trailing "/string()" means the expression will always return atomic values and therefore no "homogeneity check" is needed (this is the check that the expression doesn't return a mixture of atomic values and nodes). The involves a rearrangement of the expression from A/(B/C) form to (A/B)/C, which involves copying sub-expressions; and copying subexpressions that include variable references is always requires a certain amount of care, and in this case is failing.

It's rather remarkable that this failure doesn't happen a lot; it's hard to see what the conditions are that make it so rare. For the same reason, it's not immediately obvious what we need to change to fix it.

Actions #5

Updated by Michael Kay over 4 years ago

  • Category set to Internals
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Priority changed from High to Normal
  • Applies to branch trunk added
  • Fix Committed on Branch 9.9, trunk added

I have come to the conclusion, from careful study of the code and from running tests, that the expression rearrangement being done by HomogeneityChecker.typeCheck() (in circumstances where (a) the expression always returns atomic values, and (b) the argument path expression needs to be sorted into document order) is redundant and this code can be removed, which neatly avoids the problem.

Actions #6

Updated by O'Neil Delpratt over 4 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 9.9.1.5 added

Bug fix applied in the Saxon 9.9.1.5 maintenance release.

Please register to edit this issue

Also available in: Atom PDF