diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-11-20 15:47:16 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-11-20 15:47:16 +0200 |
commit | 5b686af2ec4968522f1196fbbcb16600f066e734 (patch) | |
tree | aa88590bab7f601ecd157673c4140c6ec6daf467 /storage/innobase/btr | |
parent | b40cab657bb5d748423f2637fa96d135d4b9e804 (diff) | |
parent | 6cedb671e99038f1a10e0d8504f835aaabed9780 (diff) | |
download | mariadb-git-5b686af2ec4968522f1196fbbcb16600f066e734.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'storage/innobase/btr')
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 0d256f7f2cb..535620db0f2 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -483,14 +483,55 @@ incompatible: /* This metadata record includes a BLOB that identifies any dropped or reordered columns. */ ulint trx_id_offset = index->trx_id_offset; - if (!trx_id_offset) { - /* The PRIMARY KEY contains variable-length columns. - For the metadata record, variable-length columns are - always written with zero length. The DB_TRX_ID will - start right after any fixed-length columns. */ + /* If !index->trx_id_offset, the PRIMARY KEY contains + variable-length columns. For the metadata record, + variable-length columns should be written with zero + length. However, before MDEV-21088 was fixed, for + variable-length encoded PRIMARY KEY column of type + CHAR, we wrote more than zero bytes. That is why we + must determine the actual length of each PRIMARY KEY + column. The DB_TRX_ID will start right after any + PRIMARY KEY columns. */ + ut_ad(index->n_uniq); + + /* We cannot invoke rec_get_offsets() before + index->table->deserialise_columns(). Therefore, + we must duplicate some logic here. */ + if (trx_id_offset) { + } else if (index->table->not_redundant()) { + /* PRIMARY KEY columns can never be NULL. + We can skip the null flag bitmap. */ + const byte* lens = rec - (REC_N_NEW_EXTRA_BYTES + 1) + - index->n_core_null_bytes; + unsigned n_add = rec_get_n_add_field(lens); + ut_ad(index->n_core_fields + n_add >= index->n_fields); + lens -= n_add; + for (uint i = index->n_uniq; i--; ) { - trx_id_offset += index->fields[i].fixed_len; + const dict_field_t& f = index->fields[i]; + unsigned len = f.fixed_len; + if (!len) { + len = *lens--; + if ((len & 0x80) + && DATA_BIG_COL(f.col)) { + /* 1exxxxxxx xxxxxxxx */ + len &= 0x3f; + len <<= 8; + len |= *lens--; + } + } + trx_id_offset += len; } + } else if (rec_get_1byte_offs_flag(rec)) { + trx_id_offset = rec_1_get_field_end_info( + rec, index->n_uniq - 1); + ut_ad(!(trx_id_offset & REC_1BYTE_SQL_NULL_MASK)); + trx_id_offset &= ~REC_1BYTE_SQL_NULL_MASK; + } else { + trx_id_offset = rec_2_get_field_end_info( + rec, index->n_uniq - 1); + ut_ad(!(trx_id_offset & REC_2BYTE_SQL_NULL_MASK)); + trx_id_offset &= ~REC_2BYTE_SQL_NULL_MASK; } const byte* ptr = rec + trx_id_offset |