Project

Profile

Help

Bug #4314

Problem using current-merge-group() as argument to function call on the right hand side of simple map expression

Added by Martin Honnen about 2 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XSLT conformance
Sprint/Milestone:
-
Start date:
2019-09-22
Due date:
% Done:

0%

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

Description

Using Saxon-HE 9.9.1.5J, I have run into a problem when I try to use use current-merge-group() inside of xsl:merge-action but in an XPath expression that uses the simple map operator !; Saxon the refuses to run the code claiming there is no current merge group: "XTDE3480: There is no current merge group".

A much reduced and not very meaningful test case that demonstrates the problem is:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    expand-text="yes"
    exclude-result-prefixes="#all">
    
    <xsl:output indent="yes"/>
    
    <xsl:function name="mf:test" as="item()*">
        <xsl:param name="i1" as="xs:integer*"/>
        <result>{sum($i1)}</result>
    </xsl:function>
    
    <xsl:template match="/" name="xsl:initial-template">
        <root>
            <xsl:merge>
                <xsl:merge-source select="1 to 10">
                    <xsl:merge-key select=". idiv 5"></xsl:merge-key>
                </xsl:merge-source>
                <xsl:merge-action>
                    <xsl:message select="position(), ': ', current-merge-group()"/>
                    <xsl:sequence select="(1 to 3) ! mf:test(current-merge-group())"/>
                </xsl:merge-action>
            </xsl:merge>
        </root>
    </xsl:template>
    
</xsl:stylesheet>

Output when run from the command line with -it -xsl:map-expression-problem1.xsl:

Processing  (no source document) initial template = xsl:initial-template
1 :  1 2 3 4
Error evaluating (fn:sum(...)) in xsl:sequence/@select on line 23 column 87 of map-expression-problem1.xsl:
  XTDE3480: There is no current merge group. Found while atomizing the first argument of mf:test()
at template xsl:initial-template on line 15 of map-expression-problem1.xsl:
     invoked by unknown caller (null)
at template xsl:initial-template on line 15 of map-expression-problem1.xsl:
     invoked by unknown caller (null)
at template xsl:initial-template on line 15 of map-expression-problem1.xsl:
     invoked by unknown caller (null)
There is no current merge group. Found while atomizing the first argument of mf:test()

As the call to the mf:test is inside of an xsl:merge-action I think the current-merge-group() should be present. Somehow the use of the map operator ! seems to trigger this so I suppose that Saxon rewrites the code and doing it in a way that makes it claim that the merge group is absent.

History

#1 Updated by Michael Kay about 2 years ago

  • Status changed from New to In Progress
  • Assignee set to Michael Kay

Thanks. Reproduced as XSLT3 test case merge-099. The call on current-merge-group() appears to have been correctly loop-lifted and its result bound to a system-generated variable; but the variable is being lazily evaluated and it seems that the context information for the delayed evaluation is incomplete.

#2 Updated by Michael Kay about 2 years ago

The context for lazy evaluation is being set using the static method XPathContextMajor.newContext(XPathContextMinor), which for some reason sets the currentMergeGroupIterator to null rather than copying it. I can't see why it should be doing this, so I'll try changing it to see if anything breaks.

#3 Updated by Michael Kay about 2 years ago

Changing the code to copy the currentMergeGroupIterator unfortunately breaks other tests:

  merge-055
  merge-056
  merge-087
  merge-088

These tests are designed to check that current-merge-group() is cleared on a component invocation such as xsl:call-template.

#4 Updated by Michael Kay about 2 years ago

The best approach seems to be for the newContext() method to copy the currenfMergeIterator from the old context, and then for invocation constructs (callTemplate, applyTemplates etc) to explicitly set it to null.

I have also added a couple of tests (merge-100, merge-101) to show that current-merge-group() and -key() are cleared by a call to a stylesheet function. (This case was working, but untested).

#5 Updated by Michael Kay about 2 years ago

  • Status changed from In Progress to Resolved
  • Applies to branch trunk added
  • Fix Committed on Branch 9.9, trunk added

#6 Updated by O'Neil Delpratt about 2 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 9.9.1.6 added

Patch committed to the Saxon 9.9.1.6 maintenance release.

Please register to edit this issue

Also available in: Atom PDF