Vyacheslav Akhmechet <coffeemug@stripped> writes:
> On Wed, May 6, 2009 at 1:38 AM, Kristian Nielsen
> <knielsen@stripped> wrote:
>> Hope this helps
> Thank you, this really helps. Am I correct to assume that table->field
> is simply a pointer to structures that are stored in the buffer passed
> to write_row (a cast, essentially)? When I access the fields from
No, this does not sound right.
> write_row I get the correct values, but I am not sure what the
> relationship between these data structures and the buffer passed to
> write_row is.
This is really central to how the storage handler interface works. You need to
study the code yourself a bit to work efficiently with it I think. From
memory, the basic idea is this:
The buffer passed to write_row etc. is a fixed-size buffer of bytes holding
the data for one row. It has a certain format, basically it contains NULL bits
and fractional bitfields, followed by data for each column in sequence, padded
to maximum length so the offsets of a field are constant. This is often called
The table->field list has an entry for each column in the table. Each entry is
a class with methods for accessing the data of that field stored inside a
record. This list is constant for the table, it is kind of the metadata for
The table has two pre-allocated buffers for records, table->record and
table->record. They are used for most record data to avoid malloc()
overhead. So usually the buffer passed into write_row() and similar methods is
actually a pointer to one of these.
Now, the Field objects in table->field are pre-initialised with a pointer
directly into table->record. So you can call them to get data out of
table->record without passing any explicit buffer pointer. You will see
some of the Field methods have a variant that takes a row_offset, so to access
data in another buffer bufptr, you need to pass the pointer difference to
table->field->get_ptr(&my_ptr, bufptr - table->record)
which is a bit strange and takes a bit of getting used to.
Hope this helps,