Martin Bjorklund je 28.9.2015 ob 12:15 napisal:
Jernej Tuljak <jern...@mg-soft.si> wrote:
Martin Bjorklund je 25.9.2015 ob 15:22 napisal:
Jernej Tuljak <jern...@mg-soft.si> wrote:
Ladislav Lhotka je 25.9.2015 ob 13:44 napisal:
Jernej Tuljak <jern...@mg-soft.si> writes:

Ladislav Lhotka je 25.9.2015 ob 9:58 napisal:
Jernej Tuljak <jern...@mg-soft.si> writes:

Martin Bjorklund je 24.9.2015 ob 13:54 napisal:
Jernej Tuljak <jern...@mg-soft.si> wrote:
Ladislav Lhotka je 23.9.2015 ob 14:29 napisal:
Jernej Tuljak <jern...@mg-soft.si> writes:

Ladislav Lhotka je 23.9.2015 ob 12:52 napisal:
On 23 Sep 2015, at 12:37, Jernej Tuljak <jern...@mg-soft.si>
wrote:

Ladislav Lhotka je 23.9.2015 ob 11:58 napisal:
On 23 Sep 2015, at 11:45, Jernej Tuljak <jern...@mg-soft.si>
wrote:

Section 7.21.5., the first bullet describing the augmentation
case
does not consider that an "augment" may specify a top-level
"choice"
or a "choice"/"case" nested within a top-level "choice" as the
target
node. There will be no initial context node for the expression
in
such
a case.

        leaf enable-foos {
          type boolean;
        }
        choice ch1 {
          case foo {
            choice foos {
              when "enable-foos = 'true'";
              leaf foo1 {
                type string;
              }
              leaf foo2 {
                type string;
              }
            }
          }
          container meh;
        }

        augment "/ch1/foo/foos" {
          when "enable-foos = 'true'";
          leaf foo3 {
            type string;
          }
        }

OLD:

         o If the "when" statement is a child of an "augment"
         statement,
         then
            the context node is the augment's target node in the
            data tree,
            if
            the target node is a data node.  Otherwise, the
            context
            node is
            the closest ancestor node to the target node that is
            also a data
            node.

NEW:

         o If the "when" statement is a child of an "augment"
         statement,
         then
            the context node is the augment's target node in the
            data tree,
            if
            the target node is a data node.  Otherwise, the
            context
            node is
            the closest ancestor node to the target node that is
            also a data
            node. If no such node exists, the context node is
            the
            root node.

Good catch, I support this change.

Also regarding sec. 7.21.5, I think we agreed that a when
expression
must not reference nodes that are made conditional through that
when
statement. I can’t find this rule in the text.
The "no referencing the initial context node and its descendants"
text
is currently in the guidelines draft only (6087bis).
IMO this should be a hard rule in 6020bis. Such expressions are
seriously broken and could lead to deadlocks.
I think that was the purpose of the change in 3rd bullet. A "dummy"
node
with no value and child nodes has been introduced.
Not really, the dummy node solves the problem of a non-existent
context
node.
Are you referring to "existence" in the instance document or the
schema tree? Why is there no need for "no children, no value dummy"
in
1st and 2nd bullet?
In these cases, the context node is well-defined anyway.  But I think
that also these bullets need to have text that make sure that the
outcome is deterministic in all cases, such as:

       augement /foo {
         when "bar > 1";
         leaf bar { type int32; }
       }

or

       grouping foo {
         leaf bar { type int32; }
       }
       container x {
         uses foo {
           when "bar > 1";
         }
       }


etc.

So I suggest this NEW text:


        o If the "when" statement is a child of an "augment" statement,
        then
           the context node is the augment's target node in the data
           tree,
           if
           the target node is a data node.  Otherwise, the context node
           is
           the closest ancestor node to the target node that is also a
           data
           node.  If no such node exists, the context node is the root
           node.
           The accessible tree is tentatively altered during the
           processing
           of the XPath expression by removing all instances (if any)
           of
           the
           nodes added by the "augment" statement.

        o  If the "when" statement is a child of a "uses", "choice", or
           "case" statement, then the context node is the closest
           ancestor
           node to the "uses", "choice", or "case" node that is also a
           data
           node.  If no such node exists, the context node is the root
           node.
           The accessible tree is tentatively altered during the
           processing
           of the XPath expression by removing all instances (if any)
           of
           the
           nodes added by the "uses", "choice", or "case" statement.

        o If the "when" statement is a child of any other data
        definition
           statement, the accessible tree is tentatively altered during
           the
           processing of the XPath expression by replacing all
           instances
           (if
           any) of the data node for which the "when" statement is
           defined
           with a single dummy node with the same name, but with no
           value
           and
           no children.  The context node is this dummy node.

+1

       container foo {
         when "child::* or child::text() or not(self::*)"; // always
         false
         leaf bar {
           type string;
         }
       }
I think it would be better to clearly state that a "when" expression
MUST NOT refer to nodes that are made conditional by the same "when"
statement - it's similar to the rule that forbids mutual references.
This would also cover all uses of "when".

The above example would be really confusing if the "bar" instance is
present.
It is true that this introduces a caveat that is bound to confuse end
YANG users.

     I also don't like the fact that "when" and "must" would give
different results in this case.
Just to be clear, you would like this, right?

NEW:

       The XPath expression is conceptually evaluated in the following
       context, in addition to the definition inSection 6.4.1
<https://tools.ietf.org/html/draft-ietf-netmod-rfc6020bis-07#section-6.4.1>:

       o If the "when" statement is a child of an "augment" statement,
       then
          the context node is the augment's target node in the data tree,
          if
          the target node is a data node.  Otherwise, the context node is
          the closest ancestor node to the target node that is also a data
          node. If no such node exists, the context node is the root node.

       o  If the "when" statement is a child of a "uses", "choice", or
          "case" statement, then the context node is the closest ancestor
          node to the "uses", "choice", or "case" node that is also a data
          node.  If no such node exists, the context node is the root
          node.

       o  If the "when" statement is a child of any other data definition
          statement, the context node is the node in the accessible tree
          for
          which the "when" statement is defined.
            An XPath expression MUST NOT reference nodes that are made
            conditional
       by the "when" statement that defines it.
Yes, plus the other two rules that are already in 6020bis:

If the XPath expression references any node that also has associated
"when" statements, these "when" expressions MUST be evaluated first.

There MUST NOT be any circular dependencies in these "when"
expressions.
I don't see a case in which the context node is non-existent (in the
schema tree) in any of the three bullets, even without "no value, no
descendants" dummy node.
The third bullet is aimed at cases like this:

leaf foo {
       when "../bar > 0";
       mandatory true;
       ...
}

If there is no instance of "foo", a validator has to find out whether
the "mandatory" statement applies (and the absence of "foo" is thus a
schema error), or whether it is overruled by the "when" expression
being
false. But in order to be able to evaluate that expression, XPath
requires a context node in the instance document, so we need to
tentatively add one.
Then the dummy node text is broken all together. It instructs to
modify the accessible tree (schema)
The accessible tree is not the schema, it is the instance data.

instead of instructing to
instantiate a dummy if an instance of the context node does not
exist.
No, the text says *replace* any instances with the dummy instance;
this ensures that the result is the same regardless of if the node
exists or not.
Okay, the accessible tree is instantiated data nodes.

container top {
     leaf foo {
         when "../bar > 0";
         mandatory true;
         ...
     }
}

"top": {}

"top": { "foo": "" }

How is a context node ensured for the two instances, if replacing
something that may not exist? You would need to create a dummy if
there is no "foo" instance, right? The text only says "replace".
Ok; the intention was "replace if it exists, and create otherwise"
(i.e., "replace" as in NETCONF edit operation).   We can make this
explicit:

NEW:

- If the "when" statement is a child of any other data definition
   statement, the accessible tree is tentatively altered during the
   processing of the XPath expression by replacing all instances of the
   data node for which the "when" statement is defined with a single
   dummy node with the same name, but with no value and no children.
   If no instances of the data node exists, the dummy node is created.
   The context node is this dummy node.


I agree with this.



A context node always exists in the schema tree.
The context node is in the data tree.

IMO, this
needs to be fixed in order to prevent the interpretation I came up
with (and also Balazs, independently). This interpretation was clearly
not the intention.

NEW:

     The XPath expression is conceptually evaluated in the following
     context, in addition to the definition inSection 6.4.1
     
<https://tools.ietf.org/html/draft-ietf-netmod-rfc6020bis-07#section-6.4.1>:

     o  If the "when" statement is a child of an "augment" statement, then
        the context node is the augment's target node in the data tree, if
        the target node is a data node.  Otherwise, the context node is
        the closest ancestor node to the target node that is also a data
        node. If no such node exists, the context node is the root node.

     o  If the "when" statement is a child of a "uses", "choice", or
        "case" statement, then the context node is the closest ancestor
        node to the "uses", "choice", or "case" node that is also a data
        node.  If no such node exists, the context node is the root node.

     o  If the "when" statement is a child of any other data definition
        statement, the context node is the node in the accessible tree for
        which the "when" statement is defined.
            If an instance of the context node does not exist during
            processing
     of the XPath expression, the context node is tentatively instantiated
     as a single dummy node with the same name, but with no value and no
     children, and merged into the instance of the accessible tree.

     The result of the XPath expression is converted to a boolean value
     using the standard XPath rules.

     An XPath expression MUST NOT reference nodes that are made conditional
     by the "when" statement that defines it.

     If the XPath expression references any node that also has associated
     "when" statements, these "when" expressions MUST be evaluated first.

     There MUST NOT be any circular dependencies in these "when"
     expressions.

Something like this also takes care of Martin's example ("* = 42").
How?  It is not clear to me if the '*' is legal or not.
It just occurred to me that it is very hard to not reference the
context node in a "when" XPath expression, since the context node is
always your initial XPath context (you always start with a node-set of
size 1, containing the context node).

"../bar" says, select the parent of the context node, then select
"bar" child
"*" says, select the children of the context node that are also
element nodes

So, yeah, "MUST NOT reference conditional nodes" doesn't work.
So do you think that my proposed text about "tentatively remove all
conditional nodes" works?

Not sure anymore:

  grouping foo {
    leaf mandatory-foo1 {
      type string;
      mandatory true;
    }
  }

  container top {
    leaf enable {
      type boolean;
    }
    container foo {
      uses foo {
        when "../enable = 'true'";
      }
    }
  }

  augment "/top/foo" {
    when "../enable = 'true'";
    leaf mandatory-foo2 {
      type string;
      mandatory true; // local augment
    }
  }

For the following instance:

"top": { "enable": "true" }

Note that the context node (container "foo") does not exist. You'd have to create if not exists (+remove nodes from grouping, choice, case, augment if any).

Jernej



/martin
_______________________________________________
netmod mailing list
netmod@ietf.org
https://www.ietf.org/mailman/listinfo/netmod

_______________________________________________
netmod mailing list
netmod@ietf.org
https://www.ietf.org/mailman/listinfo/netmod

Reply via email to