From 47adf4dd8f24b355edb692d21c8e4c03ca52b63b Mon Sep 17 00:00:00 2001 From: Rebekah Davis Date: Thu, 26 Sep 2024 16:08:08 -0400 Subject: [PATCH] Bug fix: Reads no longer fail after dropping a fixed attribute and adding it back as var-sized. --- test/src/unit-cppapi-schema-evolution.cc | 2 +- tiledb/sm/query/readers/reader_base.cc | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/test/src/unit-cppapi-schema-evolution.cc b/test/src/unit-cppapi-schema-evolution.cc index 07bcd729385..d2059d566fb 100644 --- a/test/src/unit-cppapi-schema-evolution.cc +++ b/test/src/unit-cppapi-schema-evolution.cc @@ -808,7 +808,7 @@ TEST_CASE( TEST_CASE( "C++ API: SchemaEvolution, drop fixed attribute and add back as var-sized", - "[!mayfail][cppapi][schema][evolution][add][drop]") { + "[cppapi][schema][evolution][add][drop]") { test::VFSTestSetup vfs_test_setup; Context ctx{vfs_test_setup.ctx()}; auto array_uri{ diff --git a/tiledb/sm/query/readers/reader_base.cc b/tiledb/sm/query/readers/reader_base.cc index 083d202fa15..be1ded8587f 100644 --- a/tiledb/sm/query/readers/reader_base.cc +++ b/tiledb/sm/query/readers/reader_base.cc @@ -130,6 +130,13 @@ bool ReaderBase::skip_field( return true; } + // If an attribute exists but has changed from fixed->var or var->fixed after + // schema evolution, ignore for this fragment's tile offsets + if ((array_schema_.var_size(name) && !schema->var_size(name)) || + (!array_schema_.var_size(name) && schema->var_size(name))) { + return true; + } + // If the fragment doesn't include timestamps if (timestamps_not_present(name, frag_idx)) { return true; @@ -1135,7 +1142,14 @@ uint64_t ReaderBase::get_attribute_tile_size( tile_size += fragment_metadata_[f]->tile_size(name, t); - if (array_schema_.var_size(name)) { + /** + * Note: There is a distinct case in which a schema may evolve from + * fixed-sized to var-sized. In this scenario, the LoadedFragmentMetadata + * contains fixed tiles. The tile_var_size should be calculated iff + * both the current _and_ loaded attributes are var-sized. + */ + if (array_schema_.var_size(name) && + fragment_metadata_[f]->array_schema()->var_size(name)) { tile_size += fragment_metadata_[f]->loaded_metadata()->tile_var_size(name, t); }