Bug #4549

Saxon seems to use only a single index for multiple keys

Added by Jeremy Cronk about 1 year ago. Updated 8 months ago.

XSLT conformance
Start date:
Due date:
% Done:


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


This isn't something I've been able to duplicate in anything but the original stylesheet, so I'm attaching the stylesheet, Main.xsl, along with its dependencies and an input file that shows the issue.

There's a bunch of indirect stuff happening via table lookups and function dispatch in this stylesheet, but when I try to replicate everything in a smaller stylesheet, everything seems to work correctly.

The specific issue here is that while there are a number of keys defined, when it hits the key-with-fallback function defined on line 2098, instead of using the specified table (which is coming from a table lookup itself), it seems to only use the key for coverage-option-codes-list, so in the output you get <LegalEntityCd>Incl</LegalEntityCd> on line 15, when it should be "IN", and same for BillingMethodCd on line 25 ("P" instead of "CPB"), etc. This only seems to happen in Saxon 9.9, and in Saxon 9.8, we get the correct lookup values returned.

My initial workaround was to use saxon:key-map() and add saxon:range-key="yes" to the key declarations. This causes the correct behavior in Saxon but in Saxon, it raises an internal error.

With the attached version of the stylesheet, I've also tried to use xsl:message to check the values of the variables, params, and the result of the call to key() in the key-with-fallback function, but as soon as I do this, everything works properly.

I haven't been able to isolate a specific trigger for this, unfortunately, but I was thinking some kind of caching issue was happening, and on the mailing list you mentioned that the behavior points to an issue happening during optimization. I haven't had the opportunity to try with and without optimization, however.

CodeLookup.xml (278 KB) CodeLookup.xml Jeremy Cronk, 2020-05-08 19:02
DataElements.xml (93.2 KB) DataElements.xml Jeremy Cronk, 2020-05-08 19:02
FormattingFunctions.xsl (11.4 KB) FormattingFunctions.xsl Jeremy Cronk, 2020-05-08 19:02
Main.xsl (134 KB) Main.xsl Jeremy Cronk, 2020-05-08 19:02
AL3DataDictionary.xml (1.27 MB) AL3DataDictionary.xml Jeremy Cronk, 2020-05-08 19:02
input.xml (1.83 KB) input.xml Jeremy Cronk, 2020-05-08 19:03


#1 Updated by Michael Kay about 1 year ago

  • Category set to XSLT conformance
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal

I have confirmed that 9.9 and 9.8 give different results, and that 10.0 gives the same result as 9.9.

Understanding what's going on will take a little longer...

#2 Updated by Michael Kay about 1 year ago

If I run in 10.0 with -opt:-f then I get the correct output. So it appears to be a problem with function inlining.

#3 Updated by Michael Kay about 1 year ago

System functions that maintain information on behalf of a specific caller are supposed to implement the interface StatefulSystemFunction, and to have a copy() method that copies this information when the calling expression is copied (which can happen during function inlining etc). Without this copy, two different inlinings of the same system function on behalf of different callers will not have separate copies of this information.

KeyFn maintains such information (it does a static lookup of the key name in the common case where it is supplied as a string literal), but it does not implement StatefulSystemFunction and does not have a copy() method.

#4 Updated by Michael Kay about 1 year ago

  • Status changed from New to Resolved
  • Applies to branch 10 added
  • Fix Committed on Branch 10, 9.9 added

Fixed on the 9.9 and 10.0 branches by making KeyFn implement StatefulSystemFunction, and adding a copy() method.

#5 Updated by O'Neil Delpratt about 1 year ago

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

Bug fix committed in the Saxon 10.1 maintenance release.

#6 Updated by O'Neil Delpratt 8 months ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 10.2, added
  • Fixed in Maintenance Release deleted (10.1)

Bug fix applied on the Saxon maintenance release.

Please register to edit this issue

Also available in: Atom PDF