fixes
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 9 Jan 2026 22:35:32 +0000 (14:35 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 9 Jan 2026 22:35:32 +0000 (14:35 -0800)
rust/doc/src/spv/light-detail.md
rust/pspp/src/spv/read/light.rs
rust/pspp/src/spv/read/tests.rs
rust/pspp/src/spv/testdata/light5.expected [new file with mode: 0644]
rust/pspp/src/spv/testdata/light5.spv [new file with mode: 0644]
rust/pspp/src/spv/testdata/light6.expected [new file with mode: 0644]
rust/pspp/src/spv/testdata/light6.spv [new file with mode: 0644]

index 2eadec547c6465b33e9d9f396a1f16be0aad8905..5797a045b7ef4255e5a6eb0dab70a066f919c6dc 100644 (file)
@@ -805,14 +805,21 @@ Group =>
 
 `name` is the name of the category (or group).
 
-A `Leaf` represents a leaf category.  The `Leaf`'s `leaf-index` is a
-nonnegative integer unique within the `Dimension` and less than
-`n-categories` in the Dimension.  If the user does not sort or
-rearrange the categories, then `leaf-index` starts at 0 for the first
-`Leaf` in the dimension and increments by 1 with each successive
-`Leaf`.  If the user does sort or rearrange the categories, then the
-order of categories in the file reflects that change and `leaf-index`
-reflects the original order.
+A `Leaf` represents a leaf category.  The `Leaf`'s `leaf-index` is
+ordinarily a integer unique within the `Dimension` in the range
+`0..n-categories`:
+
+- If the user does not sort or rearrange the categories, then
+  `leaf-index` starts at 0 for the first `Leaf` in the dimension and
+  increments by 1 with each successive `Leaf`.
+
+- If the user does sort or rearrange the categories, then the order of
+  categories in the file reflects that change and `leaf-index`
+  reflects the original order.
+
+- A `leaf-index` of -1 indicates a deleted category.  A reader can
+  ignore these categories.  The remaining `n` categories have
+  `leaf-index` in the range `0..n`.
 
 A dimension can have no leaf categories at all.  A table that
 contains such a dimension necessarily has no data at all.
index b3b9f4526b606851a5b820aa9c95dff161bb2ca4..13598369ebdaec68d398fa009ab8c6fccba1452d 100644 (file)
@@ -179,7 +179,7 @@ impl LightTable {
             .iter()
             .map(|cell| {
                 (
-                    PrecomputedIndex(cell.index as usize),
+                    PrecomputedIndex(dbg!(cell.index) as usize),
                     cell.value.decode(encoding, &footnotes, warn),
                 )
             })
@@ -1718,8 +1718,10 @@ impl Category {
         let name = self.name.decode(encoding, footnotes, warn);
         match &self.child {
             Child::Leaf { leaf_index } => {
-                ptod.push(*leaf_index as usize);
-                group.push(pivot::Leaf::new(name));
+                if *leaf_index >= 0 {
+                    ptod.push(*leaf_index as usize);
+                    group.push(pivot::Leaf::new(name));
+                }
             }
             Child::Group {
                 merge: true,
@@ -1751,7 +1753,7 @@ enum Child {
         #[br(magic(0u16), parse_with(parse_bool), temp)]
         _x24: bool,
         #[br(magic(b"\x02\0\0\0"))]
-        leaf_index: u32,
+        leaf_index: i32,
         #[br(magic(0u32), temp)]
         _tail: (),
     },
index 9ab4e7b6ca0f5540d657afabfa494706d1baad65..40fefc6f9be96728192d3e78f05825974f289dff 100644 (file)
@@ -44,6 +44,12 @@ fn light5() {
     test_raw_spvfile("light5", None);
 }
 
+/// Test categories to be deleted due to negative `leaf-index`.
+#[test]
+fn light6() {
+    test_raw_spvfile("light6", None);
+}
+
 #[test]
 fn legacy1() {
     test_raw_spvfile("legacy1", None);
diff --git a/rust/pspp/src/spv/testdata/light5.expected b/rust/pspp/src/spv/testdata/light5.expected
new file mode 100644 (file)
index 0000000..8acd5b1
--- /dev/null
@@ -0,0 +1,7 @@
+                                                                                     Hypothesis Test Summary
+                                      Null Hypothesis                                    │                              Test                              │Sig.[a,b]│          Decision
+─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────┼─────────┼───────────────────────────
+1 The distributions of Variable0000001, Variable0000002 and Variable0000003 are the same.│Related-Samples Friedman's Two-Way Analysis of Variance by Ranks│     .164│Retain the null hypothesis.
+─────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────┴─────────┴───────────────────────────
+a. The significance level is .050.
+b. Asymptotic significance is displayed.
diff --git a/rust/pspp/src/spv/testdata/light5.spv b/rust/pspp/src/spv/testdata/light5.spv
new file mode 100644 (file)
index 0000000..55951cd
Binary files /dev/null and b/rust/pspp/src/spv/testdata/light5.spv differ
diff --git a/rust/pspp/src/spv/testdata/light6.expected b/rust/pspp/src/spv/testdata/light6.expected
new file mode 100644 (file)
index 0000000..d0ceed0
--- /dev/null
@@ -0,0 +1,5 @@
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+               Frequency│Percent
+────────────────────────┼───────
+Missing System        21│  100.0
+────────────────────────┴───────
diff --git a/rust/pspp/src/spv/testdata/light6.spv b/rust/pspp/src/spv/testdata/light6.spv
new file mode 100644 (file)
index 0000000..b48fd37
Binary files /dev/null and b/rust/pspp/src/spv/testdata/light6.spv differ