Skip to content

Walk an array of struct values at the struct's own stride - #13

Merged
estebanzimanyi merged 2 commits into
MobilityDB:mainfrom
estebanzimanyi:fix/struct-array-stride
Sep 2, 2026
Merged

estebanzimanyi merged 2 commits into
MobilityDB:mainfrom
estebanzimanyi:fix/struct-array-stride

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

An array return whose element is a catalog struct — Span, TBox, STBox,
Match, GeoPoseFrame — is unpacked as an array of pointers: element i is
read as the eight bytes at i * IntPtr.Size and used as an address, which
for a 24-byte Span is that Span's own spantype, basetype and bound flags.
68 wrappers return such an array, spanset_spans, set_spans,
geo_stboxes and tnumber_tboxes among them.

The stride is the struct's size, taken from the field layout the catalog
records: every field at the offset the catalog gives it, the whole padded
to a multiple of its widest field — Span 24, TBox 56, STBox 80, Match 8.
Element i is the address i strides into the block, so spanset_spans over
{[8, 10], [11, 12]} answers those two spans instead of two addresses
that happened never to be dereferenced.

A C type the mapping table does not name falls through to IntPtr, the
pointer-width opaque handle. The `_t` spellings libclang leaves unreduced
— int8_t through uint64_t — and `unsigned char` are absent from that
table, so 530 of the 4825 bound functions declared a scalar at pointer
width: 246 int64_t, 140 uint64_t, 38 uint32_t and 24 unsigned char
arguments, and 72 int64_t, 58 uint64_t, 56 uint32_t and one unsigned char
returns. A uint32_t returned as IntPtr reads eight bytes of a register the
ABI defines four of, so the value carries whatever the upper half held.

The enum types come from the catalog's own `enums` rather than from names
listed one at a time. The five listed names covered MeosType, interpType
and tempSubtype, missed IndexSearchOp, SPTreeKind, MeosPixType, MeosOper,
SkipListType and nullHandleType across 43 further parameters and returns,
and one of them — spanType — names no catalog enum at all. Reading the set
from the catalog is what keeps the next enum from arriving as a pointer.
An array return whose element is a catalog struct — Span, TBox, STBox,
Match, GeoPoseFrame — is unpacked as an array of pointers: element i is
read as the eight bytes at i * IntPtr.Size and used as an address, which
for a 24-byte Span is that Span's own spantype, basetype and bound flags.
68 wrappers return such an array, `spanset_spans`, `set_spans`,
`geo_stboxes` and `tnumber_tboxes` among them.

The stride is the struct's size, taken from the field layout the catalog
records: every field at the offset the catalog gives it, the whole padded
to a multiple of its widest field — Span 24, TBox 56, STBox 80, Match 8.
Element i is the address i strides into the block, so `spanset_spans` over
`{[8, 10], [11, 12]}` answers those two spans instead of two addresses
that happened never to be dereferenced.
@estebanzimanyi
estebanzimanyi merged commit feb1777 into MobilityDB:main Sep 2, 2026
1 check passed
@estebanzimanyi
estebanzimanyi deleted the fix/struct-array-stride branch September 2, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant