Skip to content

Commit 6e9145a

Browse files
grahamwetzlerclaude
andcommitted
fix(schemas): support integer versions in unit test versions.include/exclude
IncludeExclude used StringOrArrayOfStrings which has no Number variant, causing deserialization failures when YAML integers (e.g. `- 2`) appeared in unit_test versions.include or versions.exclude lists. Adds VersionIdentifier (number-or-string) and VersionOrVersionList types scoped to IncludeExclude, leaving StringOrArrayOfStrings unchanged. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1 parent 40c2fe4 commit 6e9145a

2 files changed

Lines changed: 68 additions & 3 deletions

File tree

crates/dbt-schemas/src/schemas/common.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ use crate::schemas::semantic_layer::semantic_manifest::SemanticLayerElementConfi
2525

2626
use super::relations::base::ComponentName;
2727
use super::serde::{
28-
StringOrArrayOfStrings, bool_or_string_bool, bool_or_string_bool_default, i64_or_string_i64,
28+
StringOrArrayOfStrings, VersionOrVersionList, bool_or_string_bool,
29+
bool_or_string_bool_default, i64_or_string_i64,
2930
};
3031

3132
/// Indicates where schema metadata originates from.
@@ -863,8 +864,8 @@ impl DbtChecksum {
863864
#[skip_serializing_none]
864865
#[derive(Deserialize, Serialize, Debug, Clone, DbtSchema)]
865866
pub struct IncludeExclude {
866-
pub exclude: Option<StringOrArrayOfStrings>,
867-
pub include: Option<StringOrArrayOfStrings>,
867+
pub exclude: Option<VersionOrVersionList>,
868+
pub include: Option<VersionOrVersionList>,
868869
}
869870

870871
#[derive(Debug, Serialize, Deserialize, Clone, DbtSchema, Default)]

crates/dbt-schemas/src/schemas/serde.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,45 @@ pub enum StringOrMap {
433433
MapValue(HashMap<String, YmlValue>),
434434
}
435435

436+
// Number before String so YAML integers (e.g. `2`) match Number, not fail on String
437+
#[derive(Serialize, UntaggedEnumDeserialize, Debug, Clone, DbtSchema)]
438+
#[serde(untagged)]
439+
pub enum VersionIdentifier {
440+
Number(f64),
441+
String(String),
442+
}
443+
444+
impl VersionIdentifier {
445+
pub fn to_version_string(&self) -> String {
446+
match self {
447+
VersionIdentifier::Number(n) => {
448+
if n.fract() == 0.0 {
449+
(*n as i64).to_string()
450+
} else {
451+
n.to_string()
452+
}
453+
}
454+
VersionIdentifier::String(s) => s.clone(),
455+
}
456+
}
457+
}
458+
459+
#[derive(Serialize, UntaggedEnumDeserialize, Debug, Clone, DbtSchema)]
460+
#[serde(untagged)]
461+
pub enum VersionOrVersionList {
462+
Single(VersionIdentifier),
463+
List(Vec<VersionIdentifier>),
464+
}
465+
466+
impl VersionOrVersionList {
467+
pub fn to_strings(&self) -> Vec<String> {
468+
match self {
469+
VersionOrVersionList::Single(v) => vec![v.to_version_string()],
470+
VersionOrVersionList::List(vs) => vs.iter().map(|v| v.to_version_string()).collect(),
471+
}
472+
}
473+
}
474+
436475
#[derive(Serialize, UntaggedEnumDeserialize, Debug, Clone, DbtSchema)]
437476
#[serde(untagged)]
438477
pub enum StringOrArrayOfStrings {
@@ -991,6 +1030,7 @@ impl std::fmt::Display for FloatOrString {
9911030
#[cfg(test)]
9921031
mod tests {
9931032
use super::*;
1033+
use crate::schemas::common::IncludeExclude;
9941034
use dbt_common::serde_utils::Omissible;
9951035

9961036
#[derive(Serialize, Deserialize)]
@@ -999,6 +1039,30 @@ mod tests {
9991039
grants: OmissibleGrantConfig,
10001040
}
10011041

1042+
#[test]
1043+
fn test_include_exclude_parses_integer_version() {
1044+
let yaml = "include:\n - 2\n - 3\n";
1045+
let ie: IncludeExclude = dbt_yaml::from_str(yaml).unwrap();
1046+
let strings = ie.include.unwrap().to_strings();
1047+
assert_eq!(strings, vec!["2", "3"]);
1048+
}
1049+
1050+
#[test]
1051+
fn test_include_exclude_parses_string_version() {
1052+
let yaml = "include:\n - \"2\"\n - \"3\"\n";
1053+
let ie: IncludeExclude = dbt_yaml::from_str(yaml).unwrap();
1054+
let strings = ie.include.unwrap().to_strings();
1055+
assert_eq!(strings, vec!["2", "3"]);
1056+
}
1057+
1058+
#[test]
1059+
fn test_include_exclude_parses_single_integer_version() {
1060+
let yaml = "include: 2\n";
1061+
let ie: IncludeExclude = dbt_yaml::from_str(yaml).unwrap();
1062+
let strings = ie.include.unwrap().to_strings();
1063+
assert_eq!(strings, vec!["2"]);
1064+
}
1065+
10021066
#[test]
10031067
fn test_grant_config_normalizes_string_to_array() {
10041068
let mut grants: IndexMap<String, StringOrArrayOfStrings> = IndexMap::new();

0 commit comments

Comments
 (0)