This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 12184 - Circularity in xs:override
Summary: Circularity in xs:override
Status: CLOSED FIXED
Alias: None
Product: XML Schema
Classification: Unclassified
Component: Structures: XSD Part 1 (show other bugs)
Version: 1.1 only
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: David Ezell
QA Contact: XML Schema comments list
URL:
Whiteboard:
Keywords: resolved
Depends on:
Blocks: 11354
  Show dependency treegraph
 
Reported: 2011-02-25 13:03 UTC by Michael Kay
Modified: 2011-03-04 23:56 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2011-02-25 13:03:27 UTC
I believe there are problems in the spec in explaining what happens when two schema documents each contain xs:override elements referring to the other (or more generically, with any cycles in the xs:override graph, including as a special case a document that attempts to override itself).

Consider test case over023. This contains two documents, which I shall call P (actually over023.xsd) and Q (actually over023a.xsd).

P.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:override schemaLocation="Q.xsd">
    <xs:element name="doc" type="xs:date"/>
  </xs:override>
</xs:schema>

Q

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:override schemaLocation="P.xsd"/>
  <xs:element name="doc">
    <xs:complexType>
       <xs:sequence>
          <xs:element name="para" maxOccurs="unbounded"/>
       </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

If we follow the process described in 4.2.5, starting at P, then

If a schema document P contains an <override> element E pointing to some schema document Q, then schema(P) contains not only the components in immed(P), but also the components in schema(override(E,Q)).

So what is override(E,Q)? I think it is this (call it Q'):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:override schemaLocation="P.xsd">
    <xs:element name="doc" type="xs:date"/>
   </xs:override>
  <xs:element name="doc" type="xs:date"/>
</xs:schema>

Next step is to evaluate schema(Q'). Because Q' contains an xs:override element, to do this we need to evaluate override(E, P). This produces P', which looks like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:override schemaLocation="Q.xsd">
    <xs:element name="doc" type="xs:date"/>
  </xs:override>
</xs:schema>

To determine schema(P') we again need to evaluate override(Q, E), and since neither Q nor E have changed, this will produce a result identical to Q'. So the process as described never terminates.

It's possible that this paragraph was intended to provide a termination condition: "If applying the override transformation specified in Transformation for xs:override (§F.2) to D and E results in a schema document equivalent to D (e.g. when none of the [children] of D, or of any <redefine> and <override> elements in D match any of the [children] of E, except for the [children] of E themselves), then the effect is the same as for a cyclic set of <include> references".

However, it's far from clear what is meant by saying "the effect is the same". The paragraph refers the reader to section 4.2.3 on xs:include, which tells you to evaluate schema(Q), and evaluating schema(Q) when Q contains an xs:override element takes you back to the non-terminating xs:override rules.

Looking beyond the mechanics of the detailed rules, it's hard to see what they are trying to achieve. What is the use case for permitting cyclic xs:overrides? Given the purpose of xs:override, it feels like a logical error, and I can't see why we don't treat it as such.
Comment 1 Michael Kay 2011-03-03 08:41:28 UTC
To resolve this, I suggest we add some explanation after the definition "If a schema document Dnew contains an <override> element E pointing to some schema document Dold, then schema(Dnew) contains ...."

Specifically:

Note: If the above definition is naively translated into an algorithm, the algorithm may fail to terminate in the case where the graph of schema documents contains cycles. To guarantee termination, the algorithm must detect when it has reached closure, that is, when further computation will have no effect on the outcome. In particular, it is useful to recognize (a) that it is possible to terminate as soon as conflicting components have been generated (for example, two different type definitions with the same name), and (b) that when override(E, D) (for some E and D) is equivalent to D, no new schema components will be contributed by further processing: this can be detected either by comparing the input and output of the override transformation using a comparator such as the XPath fn:deep-equal function, or by observing the conditions that cause override(E, D) to be idempotent, for example the fact that E is empty.
Comment 2 David Ezell 2011-03-04 16:56:07 UTC
RESOLUTION: mark 12184 as decided, using the note in Comment #1.
Comment 3 C. M. Sperberg-McQueen 2011-03-04 23:20:35 UTC
The note given in comment 1 has been added to the status-quo document, with a slight modification; in adding it to the text I took the liberty of changing it so that it now speaks of non-termination

    in the case where the graph of include and override references among 
    schema documents contains cycles

Michael, if you are happy with this resolution, please close the issue; otherwise, reopen it.