This is an automated email from the ASF dual-hosted git repository.

slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git


The following commit(s) were added to refs/heads/main by this push:
     new 3f897fe62 Only allow ambiguous path steps between scalar and optional 
elements
3f897fe62 is described below

commit 3f897fe62b7946870290d7414ee27d5b733426b1
Author: Steve Lawrence <[email protected]>
AuthorDate: Tue Mar 12 14:53:49 2024 -0400

    Only allow ambiguous path steps between scalar and optional elements
    
    Scalar and optional elements are both implemented in the infoset exactly
    the same as DIElements, the only real difference is optional elements
    might not appear in the infoset. Arrays on the other hand are
    implemented differently as a DIArray. Because of this, it adds
    complexity if we allow expression path steps that can ambiguously
    reference either an array or an optional. We currently allow this, but
    this complexity leads to bugs and thrown exceptions.
    
    In fact, in most cases ambiguously referencing an array or an optional
    doesn't even work since arrays need a predicate and optionals do not
    allow predicates. The only case it could potentially work is as the last
    step as an argument to a function like fn:count. The added complexity is
    not worth supporting this edge case.
    
    Instead of allowing this, we should instead only allow ambiguous paths
    steps to scalar and optional elements. This modifies the path step logic
    to enforce this. A step must now unambiguously reference an array or it
    must reference scalars/optionals.
    
    Note that this slightly affects the behavior of the fn:count() function.
    This function must still reference an array or optional as before, but
    it can now reference a scalar only if it is an ambiguous path that could
    also reference an optional. If the argument unambiguously references a
    scalar, it is an SDE as it was before. It can also no longer ambiguously
    reference an array or optional, but that was previously broken.
    
    DAFFODIL-2879
---
 .../apache/daffodil/core/dpath/Expression.scala    | 22 +++---
 .../src/test/resources/test/tdml/testWarnings.tdml |  2 +-
 .../processor/tdml/TestTDMLRunnerWarnings.scala    |  5 --
 .../section23/dfdl_functions/Functions.tdml        | 82 +++++++++++-----------
 4 files changed, 51 insertions(+), 60 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
index 82e52d68b..bbd90c4f3 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala
@@ -975,18 +975,16 @@ sealed abstract class StepExpression(val step: String, 
val pred: Option[Predicat
   }
 
   final lazy val checkAmbiguousPath: Unit = {
-    val (arraysOrOptionals, scalars) = stepElements.partition { se =>
-      se.isArray || se.isOptional
-    }
-    (arraysOrOptionals.length, scalars.length) match {
-      case (a, s) if (a > 0 && s > 0) =>
-        arraysOrOptionals.head.SDE(
-          "Path step is ambiguous. It can reference both an array or a 
non-array element, which is not allowed.\n" +
-            "One of the non-arrays is %s",
-          scalars.head.schemaFileLocation.toString,
-        )
-      case _ => // do nothing
-    }
+    val (arrays, nonArrays) = stepElements.partition { _.isArray }
+    schemaDefinitionWhen(
+      arrays.length > 0 && nonArrays.length > 0,
+      "Path step %s is ambiguous. It can reference both an array and a 
non-array element, which is not allowed.\n" +
+        "- Array: %s\n" +
+        "- Non-array: %s\n",
+      step,
+      arrays.head.schemaFileLocation.locationDescription,
+      nonArrays.head.schemaFileLocation.locationDescription,
+    )
   }
 
   /**
diff --git 
a/daffodil-tdml-processor/src/test/resources/test/tdml/testWarnings.tdml 
b/daffodil-tdml-processor/src/test/resources/test/tdml/testWarnings.tdml
index efe1e107f..61ba83035 100644
--- a/daffodil-tdml-processor/src/test/resources/test/tdml/testWarnings.tdml
+++ b/daffodil-tdml-processor/src/test/resources/test/tdml/testWarnings.tdml
@@ -98,7 +98,7 @@
 
   <tdml:errors>
     <tdml:error>Schema Definition Error</tdml:error>
-    <tdml:error>ambiguous</tdml:error>
+    <tdml:error>query-style</tdml:error>
     <tdml:error>AmbigElt</tdml:error>
   </tdml:errors>
 
diff --git 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunnerWarnings.scala
 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunnerWarnings.scala
index 96027482b..1e586fe5e 100644
--- 
a/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunnerWarnings.scala
+++ 
b/daffodil-tdml-processor/src/test/scala/org/apache/daffodil/processor/tdml/TestTDMLRunnerWarnings.scala
@@ -185,11 +185,6 @@ class TestTDMLRunnerWarnings {
               </ex:errUnparsing>
             </tdml:dfdlInfoset>
           </tdml:infoset>
-          <tdml:errors>
-            <tdml:error>Schema Definition Error</tdml:error>
-            <tdml:error>ambiguous</tdml:error>
-            <tdml:error>AmbigElt</tdml:error>
-          </tdml:errors>
           <tdml:warnings>
             <tdml:warning>This will not be found</tdml:warning>
           </tdml:warnings>
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
index b00386f9d..cb97be60d 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
@@ -5239,6 +5239,7 @@
         </xs:sequence>
       </xs:complexType>
     </xs:element>
+
     <xs:element name="scalarArray">
       <xs:complexType>
         <xs:sequence>
@@ -5261,6 +5262,7 @@
         </xs:sequence>
       </xs:complexType>
     </xs:element>
+
     <xs:element name="arrayOptional">
       <xs:complexType>
         <xs:sequence>
@@ -5276,9 +5278,7 @@
             <xs:complexType>
               <xs:sequence>
                 <xs:element name="foo" type="xs:int" minOccurs="0" 
maxOccurs="1" dfdl:representation="binary"/>
-                <!-- throws ClassCastException, possible bug in Daffodil group 
evaluation -->
-                <!-- <xs:group ref="countGroup"/> -->
-                <xs:element name="count" type="xs:int" 
dfdl:representation="binary" dfdl:inputValueCalc="{ fn:count(../ex:foo) }"/>
+                <xs:group ref="countGroup"/>
               </xs:sequence>
             </xs:complexType>
           </xs:element>
@@ -11693,11 +11693,19 @@
     <tdml:document>
       <tdml:documentPart type="byte">00 00 00 01</tdml:documentPart>
     </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>ex:foo</tdml:error>
-      <tdml:error>ambiguous</tdml:error>
-    </tdml:errors>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:scalarOptional xmlns:ex="http://example.com";>
+          <ex:scalar>
+            <ex:foo>1</ex:foo>
+            <ex:count>1</ex:count>
+          </ex:scalar>
+          <ex:optional>
+            <ex:count>0</ex:count>
+          </ex:optional>
+        </ex:scalarOptional>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
   </tdml:parserTestCase>
 
   <!--
@@ -11713,11 +11721,20 @@
     <tdml:document>
       <tdml:documentPart type="byte">00 00 00 01 00 00 00 
01</tdml:documentPart>
     </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>ex:foo</tdml:error>
-      <tdml:error>ambiguous</tdml:error>
-    </tdml:errors>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:scalarOptional xmlns:ex="http://example.com";>
+          <ex:scalar>
+            <ex:foo>1</ex:foo>
+            <ex:count>1</ex:count>
+          </ex:scalar>
+          <ex:optional>
+            <ex:foo>1</ex:foo>
+            <ex:count>1</ex:count>
+          </ex:optional>
+        </ex:scalarOptional>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
   </tdml:parserTestCase>
 
   <!--
@@ -11753,20 +11770,11 @@
     <tdml:document>
       <tdml:documentPart type="byte">00 00 00 01 00 00 00 
01</tdml:documentPart>
     </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <ex:arrayOptional xmlns:ex="http://example.com";>
-          <ex:array>
-            <ex:foo>1</ex:foo>
-            <ex:foo>1</ex:foo>
-            <ex:count>2</ex:count>
-          </ex:array>
-          <ex:optional>
-            <ex:count>0</ex:count>
-          </ex:optional>
-        </ex:arrayOptional>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>ex:foo</tdml:error>
+      <tdml:error>ambiguous</tdml:error>
+    </tdml:errors>
   </tdml:parserTestCase>
 
   <!--
@@ -11782,21 +11790,11 @@
     <tdml:document>
       <tdml:documentPart type="byte">00 00 00 01 00 00 00 01 00 00 00 
01</tdml:documentPart>
     </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <ex:arrayOptional xmlns:ex="http://example.com";>
-          <ex:array>
-            <ex:foo>1</ex:foo>
-            <ex:foo>1</ex:foo>
-            <ex:count>2</ex:count>
-          </ex:array>
-          <ex:optional>
-            <ex:foo>1</ex:foo>
-            <ex:count>1</ex:count>
-          </ex:optional>
-        </ex:arrayOptional>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>ex:foo</tdml:error>
+      <tdml:error>ambiguous</tdml:error>
+    </tdml:errors>
   </tdml:parserTestCase>
 
 <!--

Reply via email to