Following up on the OpenSQLAnywhere item discussed in OpenQBW #15.
This report is based only on byte-level analysis of QBW files owned by the contributor and self-consistency relationships inside those files. No vendor SDK, documentation, disassembly, or proprietary reader was used to derive or validate it.
Current behavior
PageTrailer currently treats:
0xFF4 and 0xFF5 as two loose metadata bytes;
0xFF6..0xFFB as six reserved zero bytes.
Consequently, verify_trailer rejects valid pages once the value spanning 0xFF4..0xFF7 exceeds 16 bits.
Observed layout
The trailer is instead:
| offset |
size |
interpretation |
0xFF4 |
4 |
little-endian page log sequence number |
0xFF8 |
4 |
reserved zero bytes |
The field must be 32 bits wide: on the largest file in the three-file corpus, observed values exceed 0xFFFF, and bytes 0xFF6..0xFF7 carry their high half. Bytes 0xFF8..0xFFB remain zero.
In-file controls
Three independent relationships support the interpretation:
-
On all three files, the maximum page value is exactly ten less than the little-endian u32 at superblock offset 0x08:
| file |
superblock 0x08 |
max page 0xFF4 |
difference |
| sample A |
35,800 |
35,790 |
10 |
| sample B |
1,848,242 |
1,848,232 |
10 |
| production corpus file |
747,273,956 |
747,273,946 |
10 |
-
The four bytes at superblock 0x0C, which would be needed if 0x08 were the low half of a 64-bit file identifier, are zero in all three files. The 0x08 value behaves as the current write counter instead.
-
Pages carrying the 0x20 case bit in their page-type byte have a substantially newer LSN distribution than pages without it. That is consistent with the case bit marking pages written after a checkpoint.
Proposed API correction
- Replace
PageTrailer::meta_ff4, meta_ff5, and zero_ff6 with lsn: u32 and zero_ff8: [u8; 4].
- Expose
Page::lsn().
- Rename
Superblock::file_id_lo to current_lsn.
- Make
verify_trailer validate zero_ff3 and zero_ff8, not the high half of the LSN.
- Update the specification, CLI output, changelog, and synthetic tests.
This changes public fields, so it is a breaking API correction under the crate's current 0.x versioning.
I have a focused patch with synthetic coverage prepared locally and can open it as a draft PR once the contributor-side fork/push path is configured. I kept lowercase page-type normalization out of this issue so it can be reviewed as a separate logical change.
Following up on the OpenSQLAnywhere item discussed in OpenQBW #15.
This report is based only on byte-level analysis of QBW files owned by the contributor and self-consistency relationships inside those files. No vendor SDK, documentation, disassembly, or proprietary reader was used to derive or validate it.
Current behavior
PageTrailercurrently treats:0xFF4and0xFF5as two loose metadata bytes;0xFF6..0xFFBas six reserved zero bytes.Consequently,
verify_trailerrejects valid pages once the value spanning0xFF4..0xFF7exceeds 16 bits.Observed layout
The trailer is instead:
0xFF40xFF8The field must be 32 bits wide: on the largest file in the three-file corpus, observed values exceed
0xFFFF, and bytes0xFF6..0xFF7carry their high half. Bytes0xFF8..0xFFBremain zero.In-file controls
Three independent relationships support the interpretation:
On all three files, the maximum page value is exactly ten less than the little-endian
u32at superblock offset0x08:0x080xFF4The four bytes at superblock
0x0C, which would be needed if0x08were the low half of a 64-bit file identifier, are zero in all three files. The0x08value behaves as the current write counter instead.Pages carrying the
0x20case bit in their page-type byte have a substantially newer LSN distribution than pages without it. That is consistent with the case bit marking pages written after a checkpoint.Proposed API correction
PageTrailer::meta_ff4,meta_ff5, andzero_ff6withlsn: u32andzero_ff8: [u8; 4].Page::lsn().Superblock::file_id_lotocurrent_lsn.verify_trailervalidatezero_ff3andzero_ff8, not the high half of the LSN.This changes public fields, so it is a breaking API correction under the crate's current 0.x versioning.
I have a focused patch with synthetic coverage prepared locally and can open it as a draft PR once the contributor-side fork/push path is configured. I kept lowercase page-type normalization out of this issue so it can be reviewed as a separate logical change.