• Sergei Golubchik's avatar
    bugfix: UPDATE and virtual BLOBs · f73bdb68
    Sergei Golubchik authored
    When updating a table with virtual BLOB columns, the following might happen:
    - an old record is read from the table, it has no virtual blob values
    - update_virtual_fields() is run, vcol blob gets its value into the
      record. But only a pointer to the value is in the table->record[0],
      the value is in Field_blob::value String (but it doesn't have to be!
      it can be in the record, if the column is just a copy of another
      columns: ... b VARCHAR, c BLOB AS (b) ...)
    - store_record(table,record[1]), old record now is in record[1]
    - fill_record() prepares new values in record[0], vcol blob is updated,
      new value replaces the old one in the Field_blob::value
    - now both record[1] and record[0] have a pointer that points to the
      *new* vcol blob value. Or record[1] has a pointer to nowhere if
      Field_blob::value had to realloc.
    
    To resolve this we unlink vcol blobs from the pointer to the
    data (in the record[1]). Because the value is not *always* in
    the Field_blob::value String, we need to remember what blobs
    were unlinked. The orphan memory must be freed manually.
    
    To complicate the matter, ha_update_row() is also used in
    multi-update, in REPLACE, in INSERT ... ON DUPLICATE KEY UPDATE,
    also on REPLACE ... SELECT, REPLACE DELAYED, and LOAD DATA REPLACE, etc
    f73bdb68
sql_insert.h 2.09 KB