Skip to content

Commit

Permalink
colblk: fix UintBuilder's construction of constant column with default
Browse files Browse the repository at this point in the history
Previously if a UintBuilder was constructed with InitWithDefault, and the
column contained no non-zero elements, the UintBuilder would never construct an
array to back b.array.elems. The call to unsafe.Slice would panic when it
observed a non-zero element count and a nil pointer.
  • Loading branch information
jbowens committed Aug 2, 2024
1 parent 2e4bf3a commit cda4471
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
17 changes: 17 additions & 0 deletions sstable/colblk/testdata/uints
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
# be finished separately so the test can continue with testing higher-width
# integers.

# Test a default-zero builder that only contains zeros.

init widths=(32) default-zero
----
b32

size rows=(100)
----
b32:
32: *colblk.UintBuilder[uint32].Size(100, 0) = 5

finish widths=(32) rows=100
----
b32: *colblk.UintBuilder[uint32]:
0-1: x 01 # delta encoding: const
1-5: x 00000000 # 32-bit constant: 0

# Initialize all four writers.

init widths=(8, 16, 32, 64)
Expand Down
13 changes: 12 additions & 1 deletion sstable/colblk/uints.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,18 @@ func (b *UintBuilder[T]) Finish(col, rows int, offset uint32, buf []byte) uint32
minimum, maximum = computeMinMax(b.array.elems.Slice(rows))
w = deltaWidth(uint64(maximum - minimum))
}
return uintColumnFinish[T](minimum, b.array.elems.Slice(rows), w, offset, buf)

// NB: In some circumstances, it's possible for b.array.elems.ptr to be nil.
// Specifically, if the builder is initialized using InitWithDefault and no
// non-default values exist, no array will have been allocated (we lazily
// allocate b.array.elems.ptr). It's illegal to try to construct an unsafe
// slice from a nil ptr with non-zero rows. Only attempt to construct the
// values slice if there's actually a non-nil ptr.
var valuesSlice []T
if b.array.elems.ptr != nil {
valuesSlice = b.array.elems.Slice(rows)
}
return uintColumnFinish[T](minimum, valuesSlice, w, offset, buf)
}

// uintColumnFinish finishes the column of unsigned integers of type T, encoding
Expand Down

0 comments on commit cda4471

Please sign in to comment.