Project

Profile

Help

Bug #6093

closed

Bug on predicate with last()

Added by Shuxin Li 10 months ago. Updated 8 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XPath conformance
Sprint/Milestone:
-
Start date:
2023-06-23
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
11, 12, trunk
Fix Committed on Branch:
11, 12, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

With xml document:

<A><B/></A>

and xpath query

//*[((.,.)/parent::*/last() ! (. > 1)) = true()]

Saxon-he 12.2 returns node B. From my understanding node B shouldn't be selected, for (., .)/parent:: selects node A, and last() for node A in this case should evaluate to 1, which does not satisfy the requirement. The same query in BaseX returns empty result set.

However I'm not very certain about either what the context actually should be here or what the last() function should really return. Might this be undefined behavior?

This is a reduced case from:

<A><B><C/></B><D/></A>

and

//*[((C,.)/following::*/last() ! (. > 1)) = true()]
Actions #1

Updated by Michael Kay 10 months ago

Yes, I think you're right. The expression tree (from Saxon-EE with -opt:0) is

<query>
   <globalVariables/>
   <body>
      <docOrder baseUri="file:/Users/mike/GitHub/saxon2020/"
                ns="array=~ err=~ fn=~ local=http://www.w3.org/2005/xquery-local-functions map=~ math=~ saxon=~ xs=~ xsi=~ xml=~"
                line="1"
                intra="1">
         <slash>
            <root/>
            <filter flags="b">
               <axis name="descendant" nodeTest="NE"/>
               <gc op="=" card="M:N" comp="CAVC">
                  <forEach>
                     <slash>
                        <slash>
                           <sequence>
                              <dot type="1NE"/>
                              <dot type="1NE"/>
                           </sequence>
                           <axis name="parent" nodeTest="NE"/>
                        </slash>
                        <fn name="last"/>
                     </slash>
                     <vc op="gt" onEmpty="0">
                        <dot type="1ADI"/>
                        <int val="1"/>
                     </vc>
                  </forEach>
                  <true/>
               </gc>
            </filter>
         </slash>
      </docOrder>
   </body>
</query>

The docOrder node around the inner <slash> has been eliminated indicating that the duplicate parent isn't being eliminated before calling last().

Actions #2

Updated by Michael Kay 10 months ago

What's happening here is that the GeneralComparison XXX = true() decides that neither of its operands needs to be sorted, so it's calling "unordered()" on its operands and this is propagating the elimination of the docOrder() operation.

If the RHS of a SlashExpression is position-sensitive then a docOrder() on the LHS shouldn't be eliminated in this way.

Actions #3

Updated by Michael Kay 10 months ago

Added QT3 test case fn-last/last-28

Actions #4

Updated by Michael Kay 10 months ago

  • Category set to XPath conformance
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Applies to branch 11, 12, trunk added
  • Fix Committed on Branch 11, 12, trunk added
  • Platforms .NET, Java added
Actions #5

Updated by Shuxin Li 10 months ago

Thank you for the explanation and the fix!

Actions #6

Updated by O'Neil Delpratt 10 months ago

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

Bug fix applied in the Saxon 12.3 maintenance release.

Actions #7

Updated by O'Neil Delpratt 10 months ago

  • Status changed from Closed to Resolved

Leaving this bug issue as resolved until resolved against Saxon 11.

Actions #8

Updated by Debbie Lockett 8 months ago

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

Bug fix applied in the Saxon 11.6 maintenance release.

Please register to edit this issue

Also available in: Atom PDF