diff --git a/changelogs/unreleased/gh-10123-vy-tuple-field-lookup-fix.md b/changelogs/unreleased/gh-10123-vy-tuple-field-lookup-fix.md new file mode 100644 index 0000000000000000000000000000000000000000..201f3af65239141f4911cd715f10a698fc2bb3f3 --- /dev/null +++ b/changelogs/unreleased/gh-10123-vy-tuple-field-lookup-fix.md @@ -0,0 +1,4 @@ +## bugfix/vinyl + +* Fixed a bug when internal optimization algorithm caused a crash while a read + thread tried to look up a tuple field (gh-10123). diff --git a/src/box/tuple.h b/src/box/tuple.h index f0873279909740da73c514f90acb4c82d73d71bf..df0cad361bd46a0f0ddac35fd060173f476c9a18 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -1106,19 +1106,23 @@ tuple_field_raw_by_part(struct tuple_format *format, const char *data, const uint32_t *field_map, struct key_part *part, int multikey_idx) { - if (unlikely(part->format_epoch != format->epoch)) { - assert(format->epoch != 0); - part->format_epoch = format->epoch; - /* - * Clear the offset slot cache, since it's stale. - * The cache will be reset by the lookup. - */ - part->offset_slot_cache = TUPLE_OFFSET_SLOT_NIL; + int32_t *offset_slot_cache = NULL; + if (cord_is_main()) { + offset_slot_cache = &part->offset_slot_cache; + if (unlikely(part->format_epoch != format->epoch)) { + assert(format->epoch != 0); + part->format_epoch = format->epoch; + /* + * Clear the offset slot cache, since it's stale. + * The cache will be reset by the lookup. + */ + *offset_slot_cache = TUPLE_OFFSET_SLOT_NIL; + } } return tuple_field_raw_by_path(format, data, field_map, part->fieldno, part->path, part->path_len, TUPLE_INDEX_BASE, - &part->offset_slot_cache, multikey_idx); + offset_slot_cache, multikey_idx); } /**