Bug #2545
closed
Invalid slot number: local variables in match pattern with mode="#all"
Category:
XSLT conformance
Applies to branch:
9.6, 9.7
Fix Committed on Branch:
9.6, 9.7
Fixed in Maintenance Release:
Description
Reported on the help forum:
Using: Saxon-EE 9.6.0.7
Input:
<?xml version="1.0" encoding="UTF-8"?>
<A/>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:template match="*[some $item in ('') satisfies $item eq local-name()]" mode="#all"/>
</xsl:stylesheet>
I've been able to isolate this issue to this very small subset of the stylesheet I encountered it in. Removing or changing the mode attribute avoids the error, as does rewriting the match pattern to *[local-name() = ('')]
. (The sequence being compared against was originally in a stylesheet variable and contained more than just an empty string.)
I'm stuck with version 9.6.0.7 for the time being, so my apologies if this issue has already been addressed.
- Status changed from New to In Progress
The problem seems to be in XSLTemplate.allocatePatternSlots(). If a pattern declares local variables and the template has mode="#all", slots are allocated in the "omniMode" (which contains all template rules) but they need to be allocated to every individual named mode.
The same problem is present in the 9.7 code, but the bug is not manifested for this test case because the predicate in the match pattern is optimised to eliminate the local variable (the predicate is reduced to [not(local-name(.))]
.)
- Status changed from In Progress to Resolved
- Applies to branch 9.7 added
- Fix Committed on Branch 9.6, 9.7 added
I reproduced the problem on the 9.7 branch by using a pattern that was less amenable to optimization:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:param name="p" select="''"/>
<xsl:template match="*[some $item in $p satisfies $item eq local-name()]" mode="#all"/>
</xsl:stylesheet>
I have committed a patch on the 9.6 and 9.7 branches that solves this test case. Not yet regression-tested.
- Subject changed from Invalid slot number using quantified expression within a match pattern to Invalid slot number: local variables in match pattern with mode="#all"
- Status changed from Resolved to In Progress
Added a test case match-245 to do something similar, but a bit more complex. The test passed on 9.6, but on 9.7 it failed
java.lang.UnsupportedOperationException: Cannot copy a variable reference whose binding is unknown
at net.sf.saxon.expr.GlobalVariableReference.copy(GlobalVariableReference.java:42)
- Status changed from In Progress to Resolved
Fixing this involved two main changes:
(a) global variable references are now bound to the compiled GlobalVariable object earlier, allowing the variable reference to be copied when a template with mode="#all" is copied.
(b) the copying of a template rule with mode="#all" is now done within the logic of XSLTemplate after calling RuleManager.setTemplateRule(), rather than from within the code of RuleManager.setTemplateRule(). This allows the variable compiledTemplateRules to contain a list of all copies of the template rules, so that when the time comes to allocate slots for local variables this is done for all copies.
A further change has been committed to the 9.7 branch.
- Status changed from Resolved to In Progress
This patch appears to cause test case mode-1202 to fail.
- Status changed from In Progress to Resolved
The new code was bypassing the code in RuleManager.setTemplateRule() which splits a union pattern and allocates a default priority. Test case mode-1202 is fixed by changing the call on Mode.addRule() to call RuleManager.setTemplateRule().
Looking at the code, I am also concerned that RuleManager.setTemplateRule(), when it breaks a union pattern into its separate sub-patterns, appears to allocate the same priority to each of them, whereas the whole point is that the subpatterns can have different default priorities. Exploring more closely with the debugger, it works by accident: UnionPattern.getDefaultPriority() returns NaN, and this means that the recursive call to register each subpattern makes a second call on getDefaultPriority() - the code which gets the default priority for the union pattern is redundant but not wrong. I have removed this code on the 9.7 branch, with no ill-effects.
- % 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
- Fixed in Maintenance Release 9.7.0.3 added
- Fixed in Maintenance Release deleted (
9.7.0.2)
Leave open until fix applied in the 9.6 branch
- Status changed from Resolved to Closed
- Fixed in Maintenance Release 9.6.0.9 added
- Fixed in Maintenance Release deleted (
9.7.0.3)
Bug fix applied in the Saxon 9.6.0.9 maintenance release.
- Sprint/Milestone set to 9.7.0.2
- Fixed in Maintenance Release 9.7.0.2 added
Please register to edit this issue
Also available in: Atom
PDF