From: Kristian Nielsen Date: May 6 2009 7:00am Subject: Re: Questions about write_row and rnd_next List-Archive: http://lists.mysql.com/internals/36589 Message-Id: <87hbzyk95k.fsf@knielsen-hq.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Vyacheslav Akhmechet writes: > On Wed, May 6, 2009 at 1:38 AM, Kristian Nielsen > 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 a "record". 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 columns. The table has two pre-allocated buffers for records, table->record[0] and table->record[1]. 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[0]. So you can call them to get data out of table->record[0] 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->record[0]: table->field->get_ptr(&my_ptr, bufptr - table->record[0]) which is a bit strange and takes a bit of getting used to. Hope this helps, - Kristian.