← Back to team overview

maria-developers team mailing list archive

table_share->field vs table->field

 

Hi all,

I ran into a strange problem:

I am working on a storage engine for MariaDB. To access field
information I usually do as written in the documentation:

    for (Field** field = table->field; *field; ++field) { /* some code here */ }

This works fine in most cases (for writing - read handler::write_row -
it seems to work always) but sometimes (I think always in the
index_next method) accessing **(table->field) results in a
segmentation fault (but *(table->field) is not null, but something
like 0x5e6f4c6d4578244d). Strange enough, this error does not happen
always. In the debugger I saw, that table_share->field points to the
correct location there so I replaces table->field in the above loop
with table_share->field. But this also seems to not work - it now
crashes on other queries (also on updates, but after restarting
MariaDB it also crashes on a full table scan).

So my question: how can I access the fields in a reliable manner? I
need to do that to set/get the BLOB/TEXT fields. We have a method in
our handler called set_blobs that resets the pointer in the record to
the blobs, which looks like the following:

void ha_kvstore::set_blobs(uchar *buf, kvid key, btree::buffer &raw_data)
{
    auto current_read_pos = raw_data.const_ptr() + table_share->reclength;
    for (Field** field = table->field; *field; ++field) {
        if (!((*field)->flags & BLOB_FLAG))
            continue;
        (*field)->table = table;
        Field_blob* blob = *((Field_blob**)field);
        uint32 packlength = blob->pack_length_no_ptr();
        bmove((*field)->ptr + packlength, &current_read_pos, sizeof(char*));
        current_read_pos += blob->get_length();
    }
}

The storage engine always crashes in this code. What are we doing wrong?

Any help is appreciated!

Best Markus


Follow ups