Skip to content

Commit

Permalink
Generate SDE when node indexed like array
Browse files Browse the repository at this point in the history
- generate error when node indexed like array for . and ..
- add tests for UpStepExpression with predicate (..[1])
- fix text and steps for Expression
- add tests to show existing error for NamedStep
- remove Subset text from error

DAFFODIL-2773

Deprecation/Compatibility

Remove "subset" text from "Indexing is only allowed on arrays" SDE.
  • Loading branch information
olabusayoT committed Oct 4, 2024
1 parent dad8c6d commit a1f7f96
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,16 @@ case class RelativePathExpression(stepsRaw: List[StepExpression], isEvaluatedAbo
sealed abstract class StepExpression(val step: String, val pred: Option[PredicateExpression])
extends Expression {

final override def text: String = step + pred.map(_.text).getOrElse("")

def checkIfNodeIndexedLikeArray(): Unit = {
schemaDefinitionWhen(
pred.isDefined,
"Indexing is only allowed on arrays. Offending path step: '%s'.",
this.text
)
}

def relPathErr() = {
// This path expression cannot be compiled because we went past the root. This normally
// should be an SDE with a RelativePathPastRootError. However, if we don't have any element
Expand Down Expand Up @@ -1012,14 +1022,13 @@ sealed abstract class DownStepExpression(s: String, predArg: Option[PredicateExp
}
}

// TODO: Is ".[i]" ever a valid expression in DFDL?
// Perhaps. Doesn't work currently though. See DAFFODIL-2182

sealed abstract class SelfStepExpression(s: String, predArg: Option[PredicateExpression])
extends DownStepExpression(s, predArg) {

override lazy val compiledDPath = new CompiledDPath(SelfMove)
override def text = "."
override lazy val compiledDPath = {
checkIfNodeIndexedLikeArray()
new CompiledDPath(SelfMove)
}

protected def stepElementDefs: Seq[DPathElementCompileInfo] = {
if (this.isFirstStep) {
Expand All @@ -1037,7 +1046,7 @@ sealed abstract class SelfStepExpression(s: String, predArg: Option[PredicateExp
}
}

case class Self(predArg: Option[PredicateExpression]) extends SelfStepExpression(null, predArg)
case class Self(predArg: Option[PredicateExpression]) extends SelfStepExpression(".", predArg)

/**
* Different from Self in that it verifies the qName (s) is
Expand All @@ -1056,12 +1065,11 @@ case class Self2(s: String, predArg: Option[PredicateExpression])
sealed abstract class UpStepExpression(s: String, predArg: Option[PredicateExpression])
extends StepExpression(s, predArg) {

override def text = ".."

final override lazy val compiledDPath = {
val areAllArrays = isLastStep && stepElements.forall {
_.isArray
} && targetType == NodeInfo.Array
checkIfNodeIndexedLikeArray()
if (areAllArrays) {
new CompiledDPath(UpMoveArray)
} else {
Expand Down Expand Up @@ -1092,7 +1100,7 @@ sealed abstract class UpStepExpression(s: String, predArg: Option[PredicateExpre
override lazy val inherentType: NodeInfo.Kind = NodeInfo.Complex
}

case class Up(predArg: Option[PredicateExpression]) extends UpStepExpression(null, predArg)
case class Up(predArg: Option[PredicateExpression]) extends UpStepExpression("..", predArg)

/**
* Different from Up in that it verifies the qName (s) is the
Expand All @@ -1101,8 +1109,6 @@ case class Up(predArg: Option[PredicateExpression]) extends UpStepExpression(nul
case class Up2(s: String, predArg: Option[PredicateExpression])
extends UpStepExpression(s, predArg) {

override def text = ".."

override protected def stepElementDefs: Seq[DPathElementCompileInfo] = {
val cis = super.stepElementDefs
verifyQNames(cis)
Expand Down Expand Up @@ -1146,24 +1152,15 @@ case class NamedStep(s: String, predArg: Option[PredicateExpression])
new DownArray(nqn)
}
} else {
//
// Note: DFDL spec allows a[exp] if a is not an array, but it's a processing
// error if exp doesn't evaluate to 1.
// TODO: Implement this.
if (pred.isDefined)
subsetError(
"Indexing is only allowed on arrays. Offending path step: '%s%s'.",
step,
pred.get.text
)
// a[exp] is only supported on arrays, because Daffodil no longer treats
// optional elements as arrays
checkIfNodeIndexedLikeArray()
// the downward element step must be the same for all the possible elements, so
// we can pick the first one arbitrarily.
new DownElement(nqn)
}
}

override def text = step

/*
* The ERDs of the elements that correspond to this path step
* (or SDE trying to find them.)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@
<tdml:document><![CDATA[a1,b2,cy99:x20:z10]]></tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Subset: Indexing is only allowed on arrays</tdml:error>
<tdml:error>Indexing is only allowed on arrays</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4427,7 +4427,7 @@ blastoff
Test Name: predicate_05
Schema: predicates
Root: e5
Purpose: This test demonstrates that subset indexing is only allowed on arrays.
Purpose: This test demonstrates that indexing is only allowed on arrays.
-->

<tdml:parserTestCase name="predicate_05" root="e5"
Expand All @@ -4436,15 +4436,15 @@ blastoff
<tdml:document>2,one,two,three</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Subset: Indexing is only allowed on arrays.</tdml:error>
<tdml:error>Indexing is only allowed on arrays.</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

<!--
Test Name: predicate_06
Schema: predicates
Root: e6
Purpose: This test demonstrates that subset indexing is not allowed on optionals
Purpose: This test demonstrates that indexing is not allowed on optionals
-->

<tdml:parserTestCase name="predicate_06" root="e6"
Expand All @@ -4453,7 +4453,7 @@ blastoff
<tdml:document>2,one</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Subset: Indexing is only allowed on arrays.</tdml:error>
<tdml:error>Indexing is only allowed on arrays.</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

Expand Down Expand Up @@ -7297,7 +7297,7 @@ blastoff
<tdml:document>1,2,3</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Subset: Indexing is only allowed on arrays</tdml:error>
<tdml:error>Indexing is only allowed on arrays</tdml:error>
<tdml:error>ex:a</tdml:error>
</tdml:errors>
</tdml:parserTestCase>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,26 +507,110 @@
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="ry">
<xs:complexType>
<xs:sequence>
<xs:element name="e1" type="xs:string"/>
<xs:sequence>
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:assert>{ e1[1] eq '42' }</dfdl:assert>
</xs:appinfo>
</xs:annotation>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="rz">
<xs:complexType>
<xs:sequence>
<xs:element name="e1" type="xs:string">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:assert>{ fn:exists(..[1]) }</dfdl:assert>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="array1">
<xs:complexType>
<xs:sequence>
<xs:element name="array1_1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence dfdl:terminator="|">
<xs:element name="array1_1_1" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="1" maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:assert>{ fn:exists(..[1]) }</dfdl:assert>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

</tdml:defineSchema>

<tdml:parserTestCase name="test_array_self_expr1" model="arraySchema" root="r">
<tdml:parserTestCase name="test_array_self_expr1" model="arraySchema" root="r" ignoreUnexpectedWarnings="false">
<tdml:document>1|2|3</tdml:document>
<tdml:infoset>
<tdml:dfdlInfoset>
<ex:r>
<e1>1</e1><e1>2</e1><e1>3</e1>
</ex:r>
</tdml:dfdlInfoset>
</tdml:infoset>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Indexing</tdml:error>
<tdml:error>only allowed</tdml:error>
<tdml:error>arrays</tdml:error>
<tdml:error>.[1]</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

<tdml:parserTestCase name="test_array_self_expr2" model="arraySchema" root="rx">
<tdml:parserTestCase name="test_array_self_expr2" model="arraySchema" root="rx" ignoreUnexpectedWarnings="false">
<tdml:document>1</tdml:document>
<tdml:errors>
<tdml:error>Parse Error</tdml:error>
<tdml:error>Assertion failed</tdml:error>
<tdml:error>42</tdml:error>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Indexing</tdml:error>
<tdml:error>only allowed</tdml:error>
<tdml:error>arrays</tdml:error>
<tdml:error>.[1]</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

<tdml:parserTestCase name="test_array_path_expr1" model="arraySchema" root="ry" ignoreUnexpectedWarnings="false">
<tdml:document>1</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Indexing</tdml:error>
<tdml:error>only allowed</tdml:error>
<tdml:error>arrays</tdml:error>
<tdml:error>e1[1]</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

<tdml:parserTestCase name="test_array_path_expr2" model="arraySchema" root="rz" ignoreUnexpectedWarnings="false">
<tdml:document>1</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Indexing</tdml:error>
<tdml:error>only allowed</tdml:error>
<tdml:error>arrays</tdml:error>
<tdml:error>..[1]</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

<tdml:parserTestCase name="test_array_path_expr3" model="arraySchema" root="array1" ignoreUnexpectedWarnings="false">
<tdml:document>123|456|789</tdml:document>
<tdml:errors>
<tdml:error>Schema Definition Error</tdml:error>
<tdml:error>Indexing</tdml:error>
<tdml:error>only allowed</tdml:error>
<tdml:error>arrays</tdml:error>
<tdml:error>..[1]</tdml:error>
</tdml:errors>
</tdml:parserTestCase>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ class TestDFDLExpressions3 {
// @Test def test_polymorphic_expr_5() { runner.runOneTest("test_polymorphic_expr_5") }
// @Test def test_polymorphic_expr_6() { runner.runOneTest("test_polymorphic_expr_6") }

// DAFFODIL-2182
// @Test def test_array_self_expr1() { runner.runOneTest("test_array_self_expr1") }
@Test def test_array_self_expr1(): Unit = { runner.runOneTest("test_array_self_expr1") }
@Test def test_array_self_expr2(): Unit = { runner.runOneTest("test_array_self_expr2") }
@Test def test_array_path_expr1(): Unit = { runner.runOneTest("test_array_path_expr1") }
@Test def test_array_path_expr2(): Unit = { runner.runOneTest("test_array_path_expr2") }
@Test def test_array_path_expr3(): Unit = { runner.runOneTest("test_array_path_expr3") }

@Test def test_setVariable_neg_01(): Unit = { runner.runOneTest("setVariable_neg_01") }

Expand Down

0 comments on commit a1f7f96

Please sign in to comment.