Skip to content

Commit 57e1216

Browse files
committed
crates/doc: relax sum inspection to allow numeric strings
Improve the error message to relate that `format: number` may be used. Update catalog test to provide coverage.
1 parent db4f493 commit 57e1216

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

crates/doc/src/shape/inspections.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/// This module implements various inspections which can be performed over Shapes.
22
use super::*;
33
use crate::reduce::Strategy;
4-
use json::{LocatedProperty, Location};
4+
use json::{schema::formats::Format, LocatedProperty, Location};
55

66
#[derive(thiserror::Error, Debug, Eq, PartialEq)]
77
pub enum Error {
88
#[error("'{0}' must exist, but is constrained to always be invalid")]
99
ImpossibleMustExist(String),
1010
#[error("'{0}' has reduction strategy, but its parent does not")]
1111
ChildWithoutParentReduction(String),
12-
#[error("{0} has 'sum' reduction strategy, restricted to numbers, but has types {1:?}")]
12+
#[error("{0} has 'sum' reduction strategy (restricted to integers, numbers and strings with `format: integer` or `format: number`) but has types {1:?}")]
1313
SumNotNumber(String, types::Set),
1414
#[error(
1515
"{0} has 'merge' reduction strategy, restricted to objects & arrays, but has types {1:?}"
@@ -80,13 +80,14 @@ impl Shape {
8080
}
8181
};
8282

83-
if matches!(self.reduction, Reduction::Strategy(Strategy::Sum))
84-
&& self.type_ - types::INT_OR_FRAC != types::INVALID
85-
{
86-
out.push(Error::SumNotNumber(
87-
loc.pointer_str().to_string(),
88-
self.type_,
89-
));
83+
if matches!(self.reduction, Reduction::Strategy(Strategy::Sum)) {
84+
match (self.type_ - types::INT_OR_FRAC, &self.string.format) {
85+
(types::INVALID, _) => (), // Okay (native numeric only).
86+
(types::STRING, Some(Format::Number) | Some(Format::Integer)) => (), // Okay (string-formatted numeric).
87+
(type_, _) => {
88+
out.push(Error::SumNotNumber(loc.pointer_str().to_string(), type_));
89+
}
90+
}
9091
}
9192
if matches!(self.reduction, Reduction::Strategy(Strategy::Merge(_)))
9293
&& self.type_ - (types::OBJECT | types::ARRAY) != types::INVALID
@@ -145,6 +146,11 @@ mod test {
145146
type: object
146147
reduce: {strategy: merge}
147148
properties:
149+
sum-right-type:
150+
reduce: {strategy: sum}
151+
type: [number, string]
152+
format: integer
153+
148154
sum-wrong-type:
149155
reduce: {strategy: sum}
150156
type: [number, string]
@@ -207,10 +213,7 @@ mod test {
207213
Error::SetInvalidProperty("/-/whoops2".to_owned()),
208214
Error::ImpossibleMustExist("/must-exist-but-cannot".to_owned()),
209215
Error::ImpossibleMustExist("/nested-array/1".to_owned()),
210-
Error::SumNotNumber(
211-
"/sum-wrong-type".to_owned(),
212-
types::INT_OR_FRAC | types::STRING
213-
),
216+
Error::SumNotNumber("/sum-wrong-type".to_owned(), types::STRING),
214217
Error::MergeNotObjectOrArray("/merge-wrong-type".to_owned(), types::BOOLEAN),
215218
Error::ChildWithoutParentReduction("/*/nested-sum".to_owned()),
216219
]

crates/validation/tests/snapshots/scenario_tests__shape_inspections.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ expression: errors
1717
},
1818
Error {
1919
scope: test://example/int-halve#/collections/testing~1int-halve/schema,
20-
error: /str has 'sum' reduction strategy, restricted to numbers, but has types "string",
20+
error: /str has 'sum' reduction strategy (restricted to integers, numbers and strings with `format: integer` or `format: number`) but has types "string",
2121
},
2222
Error {
2323
scope: test://example/int-halve#/collections/testing~1int-halve/key/0,
@@ -37,7 +37,7 @@ expression: errors
3737
},
3838
Error {
3939
scope: test://example/int-string#/collections/testing~1int-string-rw/readSchema,
40-
error: /str has 'sum' reduction strategy, restricted to numbers, but has types "string",
40+
error: /str has 'sum' reduction strategy (restricted to integers, numbers and strings with `format: integer` or `format: number`) but has types "string",
4141
},
4242
Error {
4343
scope: test://example/int-string#/collections/testing~1int-string-rw/key/0,

examples/reduction-types/sum.flow.yaml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ collections:
66
properties:
77
key: { type: string }
88
value:
9-
# Sum only works with types "number" or "integer".
10-
# Others will error at build time.
11-
type: number
9+
# Sum only works with numbers.
10+
# Other types will error at build time.
11+
type: [number, string]
12+
format: number
1213
reduce: { strategy: sum }
1314
required: [key]
1415
key: [/key]
@@ -24,3 +25,12 @@ tests:
2425
collection: example/reductions/sum
2526
documents:
2627
- { key: "key", value: 3.8 }
28+
- ingest:
29+
collection: example/reductions/sum
30+
documents:
31+
- { key: "key", value: "2000000000000000000000" }
32+
- { key: "key", value: "1000000000010000000000.00005" }
33+
- verify:
34+
collection: example/reductions/sum
35+
documents:
36+
- { key: "key", value: "3000000000010000000003.800050000000000" }

0 commit comments

Comments
 (0)