Repository navigation
Fixes for writing sas7bdat files (32-bit/row-compression) - #432
Merged
evanmiller merged 1 commit intoNov 10, 2026
Merged
Conversation
Contributor
Author
|
The build failed due to capacity constraints on macOS arm64 runners. I'll push an empty commit to retrigger the build later. |
hpoettker
force-pushed
the
row-compression-and-32-bit-fixes
branch
from
November 10, 2026 19:15
b4fdac4 to
6a9bd2c
Compare
Contributor
Author
|
The build is now successful. And the build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes several problems with the sas7bdat writer that made SAS reject files or display them incorrectly. It covers row-compressed (
CHAR) files with many rows and uncompressed 32-bit files.My careful optimism in #424 that the sas7bdat write feature as provided through the pyreadstat API (Roche/pyreadstat#205) is good to go was a bit misplaced. It turns out that there is quite a lot more going on on the COMP page (currently described in the code by the comment "The mostly empty page that SAS writes after the metadata of compressed files") than previously thought.
#423 did the right thing but only addressed the problem for smaller files.
While I previously tested only with smaller files, I now validated the writer against a matrix of 32/64 bit, uncompressed/row-compression, thousands of columns, and millions of rows. And SAS reads the written files correctly.
Row-compressed files
SAS keeps an index of the pages holding compressed rows. The writer only wrote a minimal version of it, which broke once a file had more than a few hundred rows.
READSTAT_ERROR_TOO_MANY_ROWSis returned when a file would exceed what the index can describe, before anything is written.Uncompressed 32-bit files
The row size subheader has a field that tells SAS how far the first rows on the first page that holds rows are offset. We made a directionally correct fix in #421. But that was only correct while all metadata fits on the first page, and failed from about 1000 columns. The field is now computed from the actual page layout.