This is an automated email from the ASF dual-hosted git repository.
mbeckerle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git
The following commit(s) were added to refs/heads/master by this push:
new 82028c1 Throw SDE in the case of inputValueCalc containing
checkConstraints(.)
82028c1 is described below
commit 82028c1ae85fd2461e633450cf9b13be4292e066
Author: Steinberger <[email protected]>
AuthorDate: Fri Sep 4 10:57:04 2020 -0400
Throw SDE in the case of inputValueCalc containing checkConstraints(.)
For inputValueCalc, you cannot use checkConstraints(.)
because the inputValueCalc expression is computing that value.
This commit also addresses the case of test_assertFailShowsValue2
indicated in Daffodil-1043
Daffodil-1035 Daffodil-1025 Daffodil-1043
---
.../daffodil/debugger/InteractiveDebugger.scala | 2 +-
.../scala/org/apache/daffodil/dpath/DPath.scala | 15 ++-
.../org/apache/daffodil/infoset/InfosetImpl.scala | 10 +-
.../section23/dfdl_expressions/expressions.tdml | 131 +++++++++++++--------
.../dfdl_expressions/TestDFDLExpressions.scala | 9 +-
5 files changed, 108 insertions(+), 59 deletions(-)
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
index 0746fe6..1480305 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
@@ -1094,7 +1094,7 @@ class InteractiveDebugger(runner:
InteractiveDebuggerRunner, eCompilers: Express
// display the empty element.
//
case r: RuntimeSchemaDefinitionError if r.getCause() ne null =>
r.getCause() match {
- case nd: InfosetNoDataException => {
+ case nd: InfosetNoDataExceptionBase => {
//
// Displays the empty element since it has no value.
//
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
index b621ae3..9506810 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
@@ -36,12 +36,13 @@ import org.apache.daffodil.infoset.DISimple
import org.apache.daffodil.infoset.InfosetArrayIndexOutOfBoundsException
import org.apache.daffodil.infoset.InfosetException
import org.apache.daffodil.infoset.InfosetLengthUnknownException
-import org.apache.daffodil.infoset.InfosetNoDataException
+import org.apache.daffodil.infoset.InfosetNoDataExceptionBase
import org.apache.daffodil.infoset.InfosetNoInfosetException
import org.apache.daffodil.infoset.InfosetNoNextSiblingException
import org.apache.daffodil.infoset.InfosetNoSuchChildElementException
import org.apache.daffodil.infoset.InfosetNodeNotFinalException
import org.apache.daffodil.infoset.OutputValueCalcEvaluationException
+import org.apache.daffodil.infoset.InfosetSelfReferencingException
import org.apache.daffodil.processors.CompileState
import org.apache.daffodil.processors.Failure
import org.apache.daffodil.processors.ParseOrUnparseState
@@ -145,7 +146,7 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn:
NamedQName, tt: NodeInfo.Kin
case ni: InfosetNoInfosetException => doPE(e, ps)
- case nd: InfosetNoDataException => doPE(e, ps)
+ case nd: InfosetNoDataExceptionBase => doPE(e, ps)
case ai: InfosetArrayIndexOutOfBoundsException => doPE(e, ps)
@@ -160,6 +161,14 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn:
NamedQName, tt: NodeInfo.Kin
case _ => doSDE(e, ps)
}
}
+ case ParserNonBlocking => {
+ e match {
+ case nd: InfosetNoDataExceptionBase => doSDE(
+ new
InfosetSelfReferencingException(state.dState.currentNode.asElement,
+ state.dState.currentNode.erd), ps)
+ case _ => doSDE(e, ps)
+ }
+ }
case _ => doSDE(e, ps)
}
case us: UState => throw e
@@ -196,7 +205,7 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn:
NamedQName, tt: NodeInfo.Kin
whereBlockedInfo.block(noSibling.diSimple, noSibling.info, 0,
noSibling)
case noArrayIndex: InfosetArrayIndexOutOfBoundsException =>
whereBlockedInfo.block(noArrayIndex.diArray,
noArrayIndex.diArray.erd.dpathElementCompileInfo, noArrayIndex.index,
noArrayIndex)
- case nd: InfosetNoDataException if nd.erd.outputValueCalcExpr.isDefined
=> {
+ case nd: InfosetNoDataExceptionBase if
nd.erd.outputValueCalcExpr.isDefined => {
// we got a no-data exception from an element with outputValueCalc
// that is, some OVC element requested the value of another OVC element
val ovc = new OutputValueCalcEvaluationException(nd)
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
index 70ad1ca..51b31cb 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
@@ -233,10 +233,16 @@ case class InfosetNoInfosetException(val rd:
Maybe[DPathCompileInfo])
*
* For complex types indicates has not been setNilled.
*/
-case class InfosetNoDataException(val diElement: DIElement, val erd:
ElementRuntimeData)
- extends ProcessingError("Expression Evaluation",
One(erd.schemaFileLocation), Nope, "Element %s does not have a value.",
erd.namedQName)
+sealed abstract class InfosetNoDataExceptionBase(val diElement: DIElement, val
erd: ElementRuntimeData, message: String)
+ extends ProcessingError("Expression Evaluation",
One(erd.schemaFileLocation), Nope, "%s %s", message, erd.namedQName)
with InfosetException with RetryableException
+case class InfosetNoDataException(override val diElement: DIElement, override
val erd: ElementRuntimeData)
+ extends InfosetNoDataExceptionBase(diElement, erd, "Element does not have a
value.")
+
+case class InfosetSelfReferencingException(override val diElement: DIElement,
override val erd: ElementRuntimeData)
+ extends InfosetNoDataExceptionBase(diElement, erd, "Self referencing element
does not have a value.")
+
case class InfosetArrayIndexOutOfBoundsException(val diArray: DIArray, val
index: Long, val length: Long)
extends ProcessingError("Expression Evaluation", Nope, Nope, "Value %d is
out of range for the '%s' array with length %d", index, diArray.erd.namedQName,
length)
with InfosetException with RetryableException
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
index 11dd8b9..20429ae 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
@@ -2306,26 +2306,58 @@
</tdml:infoset>
</tdml:parserTestCase>
+ <tdml:defineSchema name="selfReferencingExpression">
+ <xs:include
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" />
+
+ <xs:simpleType name="cnt1">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="2"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="sr1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+ <xs:sequence>
+ <xs:element name="v" type="ex:cnt1"
+ dfdl:inputValueCalc="{ if (dfdl:checkConstraints(.)) then
xs:int(../ex:cnt) else -1 }" />
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="sr2">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+ <xs:sequence>
+ <xs:element name="v" type="xs:int" dfdl:lengthKind="explicit"
dfdl:length="{.}" />
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="sr3">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+ <xs:sequence>
+ <xs:element name="v" type="ex:cnt1"
+ dfdl:inputValueCalc="{ dfdl:checkConstraints(if(../ex:cnt eq
0) then ../ex:cnt else .) }" />
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ </tdml:defineSchema>
+
<tdml:defineSchema name="checkConstraints">
<xs:include
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<dfdl:format ref="ex:GeneralFormat" />
- <xs:element name="e1">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="cnt" type="xs:int"
- dfdl:lengthKind="delimited" />
- <xs:element name="a" minOccurs="0" maxOccurs="unbounded"
- dfdl:occursCountKind="expression" dfdl:occursCount="{
xs:int(../ex:cnt) }">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="v" type="xs:int"
- dfdl:inputValueCalc="{ dfdl:checkConstraints(.) }" />
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
+
<xs:element name="e2" dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
@@ -2339,6 +2371,7 @@
</xs:restriction>
</xs:simpleType>
</xs:element>
+
<xs:element name="e3" dfdl:lengthKind="delimited">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
@@ -2404,12 +2437,7 @@
</xs:appinfo>
</xs:annotation>
</xs:element>
-
- <!-- This test is incorrect. An element of simple type cannot use "."
- in any inputValueCalc, as "." means "the value of this element", so
- we're chasing our tail here. -->
- <xs:element name="e8" type="xs:int"
- dfdl:inputValueCalc="{ dfdl:checkConstraints(.) }" />
+
<xs:simpleType name="st1">
<xs:restriction base="ex:st2">
<xs:pattern value="[0-9]+" />
@@ -2435,41 +2463,50 @@
</tdml:defineSchema>
<!--
- Test Name: dfdlCheckConstraints
- Schema: checkConstraints
- Purpose: This test demonstrates that checkConstraints cannot reference an
inputValueCalc-ed element because the value is being computed by inputValueCalc
+ Test Name: dfdlCheckConstraintsSelfReference1
+ Schema: selfReferencingExpression
+ Purpose: This tests the error in the case of a self referencing
checkConstraints without a value
-->
- <tdml:parserTestCase name="dfdlCheckConstraints"
- root="e1" model="checkConstraints" description="DFDL-23-135R">
- <tdml:document>6</tdml:document>
+ <tdml:parserTestCase name="dfdlSelfReferencingExpression1"
+ root="sr1" model="selfReferencingExpression"
description="DFDL-23-135R">
+ <tdml:document>1</tdml:document>
<tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>Placeholder</tdml:error>
+ <tdml:error>Expression Evaluation Error</tdml:error>
+ <tdml:error>Self referencing</tdml:error>
+ <tdml:error>does not have a value</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
- <tdml:parserTestCase name="checkConstraintsComplexTypeFails"
- root="e7" model="checkConstraints" description="DFDL-23-135R">
- <tdml:document>s1s2</tdml:document>
+<!--
+ Test Name: dfdlCheckConstraintsSelfReference2
+ Schema: selfReferencingExpression
+ Purpose: This tests the error in the case of a self referencing
dfdl:length without a value
+-->
+
+ <tdml:parserTestCase name="dfdlSelfReferencingExpression2"
+ root="sr2" model="selfReferencingExpression"
description="DFDL-23-135R">
+ <tdml:document>1</tdml:document>
<tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>checkConstraints</tdml:error>
- <tdml:error>AnyAtomic</tdml:error>
+ <tdml:error>Expression Evaluation Error</tdml:error>
+ <tdml:error>Self referencing</tdml:error>
+ <tdml:error>does not have a value</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
-<!--
- Test Name: dfdlCheckConstraints2
- Schema: checkConstraints
- Purpose: This test demonstrates that checkConstraints cannot reference an
inputValueCalc-ed element because the value is being computed by inputValueCalc
--->
- <tdml:parserTestCase name="dfdlCheckConstraints2" validation="on"
- root="e8" model="checkConstraints" description="DFDL-23-135R">
- <tdml:document></tdml:document>
+ <!--
+ Test Name: dfdlCheckConstraintsSelfReference3
+ Schema: selfReferencingExpression
+ Purpose: This tests the error in the case of a self reference without a
value
+ -->
+
+ <tdml:parserTestCase name="dfdlSelfReferencingExpression3"
+ root="sr3" model="selfReferencingExpression"
description="DFDL-23-135R">
+ <tdml:document>1</tdml:document>
<tdml:errors>
- <tdml:error>Schema Definition Error</tdml:error>
- <tdml:error>Placeholder</tdml:error>
+ <tdml:error>Expression Evaluation Error</tdml:error>
+ <tdml:error>Self referencing</tdml:error>
+ <tdml:error>does not have a value</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
index 1ae4501..36aa2df 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
@@ -247,12 +247,9 @@ class TestDFDLExpressions {
@Test def test_expresion_bad_path_to_element(): Unit = {
runner.runOneTest("expresion_bad_path_to_element") }
@Test def test_ArrayOptElem_02(): Unit = {
runner.runOneTest("ArrayOptElem_02") }
- //DFDL-1035 - tests need better diagnostic
- //@Test def test_dfdlCheckConstraints() {
runner.runOneTest("dfdlCheckConstraints") }
- //@Test def test_dfdlCheckConstraints2() {
runner.runOneTest("dfdlCheckConstraints2") }
-
- // DFDL-1043
- // @Test def test_checkConstraintsComplexTypeFails() {
runner.runOneTest("checkConstraintsComplexTypeFails") }
+ @Test def test_dfdlSelfReferencingExpression1(): Unit = {
runner.runOneTest("dfdlSelfReferencingExpression1") }
+ @Test def test_dfdlSelfReferencingExpression2(): Unit = {
runner.runOneTest("dfdlSelfReferencingExpression2") }
+ @Test def test_dfdlSelfReferencingExpression3(): Unit = {
runner.runOneTest("dfdlSelfReferencingExpression3") }
@Test def test_nonFunctionIsDetected() = {
runnerNV.runOneTest("nonFunctionIsDetected") }
@Test def test_constantFunction1(): Unit = {
runnerNV.runOneTest("constantFunction1") }