3232
3333#ifdef TILEDB_SERIALIZATION
3434
35+ #include " test/support/src/helpers.h"
3536#include " test/support/src/mem_helpers.h"
3637#include " test/support/tdb_catch.h"
3738#include " tiledb/api/c_api/buffer/buffer_api_internal.h"
4142#include " tiledb/sm/c_api/tiledb_serialization.h"
4243#include " tiledb/sm/c_api/tiledb_struct_def.h"
4344#include " tiledb/sm/cpp_api/tiledb"
45+ #include " tiledb/sm/cpp_api/tiledb_experimental"
4446#include " tiledb/sm/crypto/encryption_key.h"
4547#include " tiledb/sm/enums/array_type.h"
4648#include " tiledb/sm/enums/encryption_type.h"
@@ -67,6 +69,7 @@ struct RequestHandlerFx {
6769 Config cfg_;
6870 Context ctx_;
6971 EncryptionKey enc_key_;
72+ shared_ptr<ArraySchema> schema_;
7073};
7174
7275struct HandleLoadArraySchemaRequestFx : RequestHandlerFx {
@@ -75,11 +78,17 @@ struct HandleLoadArraySchemaRequestFx : RequestHandlerFx {
7578 }
7679
7780 virtual shared_ptr<ArraySchema> create_schema () override ;
78- shared_ptr<ArraySchema> call_handler (
81+
82+ std::tuple<
83+ shared_ptr<ArraySchema>,
84+ std::unordered_map<std::string, shared_ptr<ArraySchema>>>
85+ call_handler (
7986 serialization::LoadArraySchemaRequest req, SerializationType stype);
8087
8188 shared_ptr<const Enumeration> create_string_enumeration (
8289 std::string name, std::vector<std::string>& values);
90+
91+ shared_ptr<ArraySchema> schema_add_attribute (const std::string& attr_name);
8392};
8493
8594struct HandleQueryPlanRequestFx : RequestHandlerFx {
@@ -116,15 +125,23 @@ struct HandleConsolidationPlanRequestFx : RequestHandlerFx {
116125
117126TEST_CASE_METHOD (
118127 HandleLoadArraySchemaRequestFx,
119- " tiledb_handle_load_array_schema_request - default request " ,
128+ " tiledb_handle_load_array_schema_request - no enumerations " ,
120129 " [request_handler][load_array_schema][default]" ) {
121130 auto stype = GENERATE (SerializationType::JSON, SerializationType::CAPNP);
122131
123132 create_array ();
124- auto schema =
125- call_handler (serialization::LoadArraySchemaRequest (false ), stype);
133+ auto schema_response =
134+ call_handler (serialization::LoadArraySchemaRequest (cfg_), stype);
135+ auto schema = std::get<0 >(schema_response);
126136 REQUIRE (schema->has_enumeration (" enmr" ));
127137 REQUIRE (schema->get_loaded_enumeration_names ().size () == 0 );
138+ tiledb::test::schema_equiv (*schema, *schema_);
139+
140+ // We did not evolve the schema so there should only be one.
141+ auto all_schemas = std::get<1 >(schema_response);
142+ REQUIRE (all_schemas.size () == 1 );
143+ tiledb::test::schema_equiv (
144+ *all_schemas.find (schema->name ())->second , *schema_);
128145}
129146
130147TEST_CASE_METHOD (
@@ -134,12 +151,57 @@ TEST_CASE_METHOD(
134151 auto stype = GENERATE (SerializationType::JSON, SerializationType::CAPNP);
135152
136153 create_array ();
137- auto schema =
138- call_handler (serialization::LoadArraySchemaRequest (true ), stype);
154+ REQUIRE (cfg_.set (" rest.load_enumerations_on_array_open" , " true" ).ok ());
155+ auto schema_response =
156+ call_handler (serialization::LoadArraySchemaRequest (cfg_), stype);
157+ auto schema = std::get<0 >(schema_response);
139158 REQUIRE (schema->has_enumeration (" enmr" ));
140159 REQUIRE (schema->get_loaded_enumeration_names ().size () == 1 );
141160 REQUIRE (schema->get_loaded_enumeration_names ()[0 ] == " enmr" );
142161 REQUIRE (schema->get_enumeration (" enmr" ) != nullptr );
162+ tiledb::test::schema_equiv (*schema, *schema_);
163+
164+ // We did not evolve the schema so there should only be one.
165+ auto all_schemas = std::get<1 >(schema_response);
166+ REQUIRE (all_schemas.size () == 1 );
167+ tiledb::test::schema_equiv (
168+ *all_schemas.find (schema->name ())->second , *schema_);
169+ }
170+
171+ TEST_CASE_METHOD (
172+ HandleLoadArraySchemaRequestFx,
173+ " tiledb_handle_load_array_schema_request - multiple schemas" ,
174+ " [request_handler][load_array_schema][schema-evolution]" ) {
175+ auto stype = GENERATE (SerializationType::JSON, SerializationType::CAPNP);
176+ std::string load_enums = GENERATE (" true" , " false" );
177+
178+ create_array ();
179+
180+ std::vector<shared_ptr<ArraySchema>> all_schemas{schema_};
181+ all_schemas.push_back (schema_add_attribute (" b" ));
182+ all_schemas.push_back (schema_add_attribute (" c" ));
183+ all_schemas.push_back (schema_add_attribute (" d" ));
184+
185+ REQUIRE (cfg_.set (" rest.load_enumerations_on_array_open" , load_enums).ok ());
186+ auto schema_response =
187+ call_handler (serialization::LoadArraySchemaRequest (cfg_), stype);
188+ auto schema = std::get<0 >(schema_response);
189+ if (load_enums == " true" ) {
190+ REQUIRE (schema->has_enumeration (" enmr" ));
191+ REQUIRE (schema->get_loaded_enumeration_names ().size () == 1 );
192+ REQUIRE (schema->get_loaded_enumeration_names ()[0 ] == " enmr" );
193+ REQUIRE (schema->get_enumeration (" enmr" ) != nullptr );
194+ }
195+ // The latest schema should be equal to the last applied evolution.
196+ tiledb::test::schema_equiv (*schema, *all_schemas.back ());
197+
198+ // Validate schemas returned from the request in the order they were created.
199+ auto r_all_schemas = std::get<1 >(schema_response);
200+ std::map<std::string, shared_ptr<ArraySchema>> resp (
201+ r_all_schemas.begin (), r_all_schemas.end ());
202+ for (int i = 0 ; const auto & s : resp) {
203+ tiledb::test::schema_equiv (*s.second , *all_schemas[i++]);
204+ }
143205}
144206
145207TEST_CASE_METHOD (
@@ -346,7 +408,9 @@ TEST_CASE_METHOD(
346408RequestHandlerFx::RequestHandlerFx (const std::string uri)
347409 : memory_tracker_(tiledb::test::create_test_memory_tracker())
348410 , uri_(uri)
349- , ctx_(cfg_) {
411+ , ctx_(cfg_)
412+ , schema_(make_shared<ArraySchema>(
413+ ArrayType::DENSE, ctx_.resources().ephemeral_memory_tracker())) {
350414 delete_array ();
351415 throw_if_not_ok (enc_key_.set_key (EncryptionType::NO_ENCRYPTION, nullptr , 0 ));
352416}
@@ -405,9 +469,28 @@ HandleLoadArraySchemaRequestFx::create_string_enumeration(
405469 tiledb::test::create_test_memory_tracker ());
406470}
407471
472+ shared_ptr<ArraySchema> HandleLoadArraySchemaRequestFx::schema_add_attribute (
473+ const std::string& attr_name) {
474+ tiledb::Context ctx;
475+ tiledb::ArraySchemaEvolution ase (ctx);
476+ auto attr = tiledb::Attribute::create<int32_t >(ctx, attr_name);
477+ ase.add_attribute (attr);
478+ // Evolve and update the original schema member variable.
479+ schema_ = ase.ptr ()->array_schema_evolution_ ->evolve_schema (schema_);
480+ // Apply the schema evolution.
481+ Array::evolve_array_schema (
482+ this ->ctx_ .resources (),
483+ this ->uri_ ,
484+ ase.ptr ()->array_schema_evolution_ ,
485+ this ->enc_key_ );
486+
487+ // Return the new evolved schema for validation.
488+ return schema_;
489+ }
490+
408491shared_ptr<ArraySchema> HandleLoadArraySchemaRequestFx::create_schema () {
409492 // Create a schema to serialize
410- auto schema =
493+ schema_ =
411494 make_shared<ArraySchema>(HERE (), ArrayType::SPARSE, memory_tracker_);
412495 auto dim =
413496 make_shared<Dimension>(HERE (), " dim1" , Datatype::INT32, memory_tracker_);
@@ -416,20 +499,23 @@ shared_ptr<ArraySchema> HandleLoadArraySchemaRequestFx::create_schema() {
416499
417500 auto dom = make_shared<Domain>(HERE (), memory_tracker_);
418501 throw_if_not_ok (dom->add_dimension (dim));
419- throw_if_not_ok (schema ->set_domain (dom));
502+ throw_if_not_ok (schema_ ->set_domain (dom));
420503
421504 std::vector<std::string> values = {" pig" , " cow" , " chicken" , " dog" , " cat" };
422505 auto enmr = create_string_enumeration (" enmr" , values);
423- schema ->add_enumeration (enmr);
506+ schema_ ->add_enumeration (enmr);
424507
425508 auto attr = make_shared<Attribute>(HERE (), " attr" , Datatype::INT32);
426509 attr->set_enumeration_name (" enmr" );
427- throw_if_not_ok (schema ->add_attribute (attr));
510+ throw_if_not_ok (schema_ ->add_attribute (attr));
428511
429- return schema ;
512+ return schema_ ;
430513}
431514
432- shared_ptr<ArraySchema> HandleLoadArraySchemaRequestFx::call_handler (
515+ std::tuple<
516+ shared_ptr<ArraySchema>,
517+ std::unordered_map<std::string, shared_ptr<ArraySchema>>>
518+ HandleLoadArraySchemaRequestFx::call_handler (
433519 serialization::LoadArraySchemaRequest req, SerializationType stype) {
434520 // If this looks weird, its because we're using the public C++ API to create
435521 // these objets instead of the internal APIs elsewhere in this test suite.
@@ -451,7 +537,7 @@ shared_ptr<ArraySchema> HandleLoadArraySchemaRequestFx::call_handler(
451537 REQUIRE (rval == TILEDB_OK);
452538
453539 return serialization::deserialize_load_array_schema_response (
454- stype, resp_buf->buffer (), memory_tracker_);
540+ uri_, stype, resp_buf->buffer (), memory_tracker_);
455541}
456542
457543shared_ptr<ArraySchema> HandleQueryPlanRequestFx::create_schema () {
0 commit comments