Bug #111079 InnoDB SDI index description has fields out-of-order
Submitted: 18 May 2023 18:01 Modified: 19 May 2023 12:40
Reporter: Jeremy Cole (Basic Quality Contributor) (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: SDI

[18 May 2023 18:01] Jeremy Cole
Description:
The internal SDI index's table description is created in-memory as (type, id, compressed_len, uncompressed_len, data), however it's read and written to as (type, id, uncompressed_len, compressed_len, data). That is, the order of the compressed_len and uncompressed_len fields is reversed compared to the definition.

Since all access to this index is positional as columns 2 and 3 as far as I could find, and the field types are the same, this doesn't end up mattering in actual usage. However, in memory in the index definition, the column names are incorrect, and this should be fixed to avoid future confusion or mishaps.

Index creation/definition occurs in storage/innobase/dict/dict0crea.cc:

651 dict_index_t *dict_sdi_create_idx_in_mem(space_id_t space, bool space_discarded,
652                                          uint32_t in_flags, bool is_create) {
...
692   dict_mem_table_add_col(table, heap, "type", DATA_INT,
693                          DATA_NOT_NULL | DATA_UNSIGNED, 4, true);
694   dict_mem_table_add_col(table, heap, "id", DATA_INT,
695                          DATA_NOT_NULL | DATA_UNSIGNED, 8, true);
696   dict_mem_table_add_col(table, heap, "compressed_len", DATA_INT,
697                          DATA_NOT_NULL | DATA_UNSIGNED, 4, true);
698   dict_mem_table_add_col(table, heap, "uncompressed_len", DATA_INT,
699                          DATA_NOT_NULL | DATA_UNSIGNED, 4, true);
700   dict_mem_table_add_col(table, heap, "data", DATA_BLOB, DATA_NOT_NULL, 0,
701                          true);

Reading and writing occurs in storage/innobase/api/api0api.cc:

2716 static ib_tpl_t ib_sdi_create_insert_tuple(ib_crsr_t ib_crsr,
2717                                            const sdi_key_t *sdi_key,
2718                                            uint32_t uncomp_len,
2719                                            uint32_t comp_len, const void *sdi) {
...
2723   ib_tpl_t tuple = ib_clust_read_tuple_create(ib_crsr);
2724   ib_col_set_value(tuple, 0, &sdi_key->type, SDI_TYPE_LEN, false);
2725   ib_col_set_value(tuple, 1, &sdi_key->id, SDI_KEY_LEN, false);
2726   ib_col_set_value(tuple, 2, &uncomp_len, 4, false);
2727   ib_col_set_value(tuple, 3, &comp_len, 4, false);
2728   ib_col_set_value(tuple, 4, sdi, comp_len, false);

and

2935 dberr_t ib_sdi_get(uint32_t tablespace_id, const ib_sdi_key_t *ib_sdi_key,
2936                    void *comp_sdi, uint32_t *comp_sdi_len,
2937                    uint32_t *uncomp_sdi_len, trx_t *trx) {
...
2975       ib_tuple_read_u32(tuple, 2, uncomp_sdi_len);
2976       ib_tuple_read_u32(tuple, 3, comp_sdi_len);

How to repeat:
Examine the code.

Suggested fix:
Reverse the order of the compressed_len and uncompressed_len fields in dict_sdi_create_idx_in_mem() in storage/innobase/dict/dict0crea.cc.
[19 May 2023 12:21] MySQL Verification Team
Hi Mr. Cole,

Thank you for your bug report.

As far as we can see, both reads and writes put uncompressed length and compressed length in the same order.

It is only the metadata that differs from this order. Which practically means that it can not cause any serious bug.

Do you agree ?????
[19 May 2023 12:40] MySQL Verification Team
Hi Jeremy,

Actually, although the error is in the title of the columns only, we decided to verify it.

It is a low priority bug ......