@@ -302,30 +302,25 @@ TEST_CASE_METHOD(
302302 for (const auto & fs : fs_vec_) {
303303 std::string temp_dir = fs->temp_dir ();
304304 std::string array_name = temp_dir;
305+ std::string attr_name = " a" ;
305306 // serialization is not supported for memfs arrays
306307 if (serialize_ &&
307308 tiledb::sm::utils::parse::starts_with (array_name, " mem://" )) {
308309 continue ;
309310 }
310311
311- std::string attr_name = " a" ;
312-
313312 // Create new TileDB context with file lock config disabled, rest the
314313 // same.
315314 tiledb_ctx_free (&ctx_);
316315 tiledb_vfs_free (&vfs_);
317-
318316 tiledb_config_t * config = nullptr ;
319317 tiledb_error_t * error = nullptr ;
320318 REQUIRE (tiledb_config_alloc (&config, &error) == TILEDB_OK);
321319 REQUIRE (error == nullptr );
322-
323320 REQUIRE (vfs_test_init (fs_vec_, &ctx_, &vfs_, config).ok ());
324-
325321 tiledb_config_free (&config);
326322
327323 create_temp_dir (temp_dir);
328-
329324 create_dense_vector (array_name, attr_name, datatype);
330325
331326 // Prepare cell buffers
@@ -366,12 +361,92 @@ TEST_CASE_METHOD(
366361 tiledb_array_free (&array);
367362 tiledb_query_free (&query);
368363
364+ uint64_t ts_open = 0 ;
365+ if (datatype == TILEDB_BLOB) {
366+ // For the BLOB datatype, test with and without schema evolution.
367+ auto evolve = GENERATE (true , false );
368+ if (evolve) {
369+ // Ensure the BLOB type can evolve to both GEOM types.
370+ auto new_type = GENERATE (TILEDB_GEOM_WKB, TILEDB_GEOM_WKT);
371+ // Add a second attribute on the schema and drop the original.
372+ tiledb_array_schema_evolution_t * schema_evolution;
373+ rc = tiledb_array_schema_evolution_alloc (ctx_, &schema_evolution);
374+ REQUIRE (rc == TILEDB_OK);
375+ tiledb_attribute_t * b;
376+ rc = tiledb_attribute_alloc (ctx_, " b" , TILEDB_BLOB, &b);
377+ REQUIRE (rc == TILEDB_OK);
378+ rc = tiledb_array_schema_evolution_add_attribute (
379+ ctx_, schema_evolution, b);
380+ REQUIRE (rc == TILEDB_OK);
381+ rc = tiledb_array_schema_evolution_drop_attribute (
382+ ctx_, schema_evolution, attr_name.c_str ());
383+ REQUIRE (rc == TILEDB_OK);
384+ // Set timestamp to avoid race condition
385+ ts_open = tiledb_timestamp_now_ms ();
386+ ts_open = ts_open + 1 ;
387+ rc = tiledb_array_schema_evolution_set_timestamp_range (
388+ ctx_, schema_evolution, ts_open, ts_open);
389+ rc = tiledb_array_evolve (ctx_, array_name.c_str (), schema_evolution);
390+ REQUIRE (rc == TILEDB_OK);
391+
392+ // Add back the original attribute as new_type and drop "b".
393+ tiledb_array_schema_evolution_t * schema_evolution2;
394+ rc = tiledb_array_schema_evolution_alloc (ctx_, &schema_evolution2);
395+ REQUIRE (rc == TILEDB_OK);
396+ tiledb_attribute_t * attr;
397+ rc = tiledb_attribute_alloc (ctx_, attr_name.c_str (), new_type, &attr);
398+ REQUIRE (rc == TILEDB_OK);
399+ rc = tiledb_array_schema_evolution_add_attribute (
400+ ctx_, schema_evolution2, attr);
401+ REQUIRE (rc == TILEDB_OK);
402+ rc = tiledb_array_schema_evolution_drop_attribute (
403+ ctx_, schema_evolution2, " b" );
404+ REQUIRE (rc == TILEDB_OK);
405+ // Set timestamp to avoid race condition
406+ ts_open = tiledb_timestamp_now_ms ();
407+ ts_open = ts_open + 2 ;
408+ rc = tiledb_array_schema_evolution_set_timestamp_range (
409+ ctx_, schema_evolution2, ts_open, ts_open);
410+ if (serialize_) {
411+ // Serialize the array schema evolution
412+ tiledb_buffer_t * buffer;
413+ rc = tiledb_serialize_array_schema_evolution (
414+ ctx_,
415+ schema_evolution2,
416+ (tiledb_serialization_type_t )tiledb::sm::SerializationType::CAPNP,
417+ 0 ,
418+ &buffer);
419+ REQUIRE (rc == TILEDB_OK);
420+ rc = tiledb_deserialize_array_schema_evolution (
421+ ctx_,
422+ buffer,
423+ (tiledb_serialization_type_t )tiledb::sm::SerializationType::CAPNP,
424+ 1 ,
425+ &schema_evolution2);
426+ REQUIRE (rc == TILEDB_OK);
427+ tiledb_buffer_free (&buffer);
428+ }
429+ rc = tiledb_array_evolve (ctx_, array_name.c_str (), schema_evolution2);
430+ REQUIRE (rc == TILEDB_OK);
431+
432+ // Clean up
433+ tiledb_attribute_free (&b);
434+ tiledb_attribute_free (&attr);
435+ tiledb_array_schema_evolution_free (&schema_evolution);
436+ tiledb_array_schema_evolution_free (&schema_evolution2);
437+ }
438+ }
439+
369440 int buffer_read[10 ];
370441 uint64_t buffer_read_size = sizeof (buffer_read);
371442
372443 // Open array
373444 rc = tiledb_array_alloc (ctx_, array_name.c_str (), &array);
374445 CHECK (rc == TILEDB_OK);
446+ if (ts_open != 0 ) {
447+ rc = tiledb_array_set_open_timestamp_end (ctx_, array, ts_open + 2 );
448+ REQUIRE (rc == TILEDB_OK);
449+ }
375450 rc = tiledb_array_open (ctx_, array, TILEDB_READ);
376451 CHECK (rc == TILEDB_OK);
377452
0 commit comments