@@ -463,50 +463,119 @@ TEST_CASE(
463463 Array array_r (ctx, array_name, TILEDB_READ);
464464 Subarray subarray (ctx, array_r);
465465
466+ // If read_range_oob_error is false, the range will be cropped with a
467+ // warning and the query will succeed.
468+ auto read_range_oob_error = GENERATE (true , false );
466469 auto expected = TILEDB_ERR;
470+ int fill_val = tiledb::sm::constants::empty_int32;
471+ std::vector<int > expected_data (16 , fill_val);
472+ expected_data[0 ] = 1 ;
473+ expected_data[1 ] = 2 ;
474+ expected_data[4 ] = 3 ;
475+ expected_data[5 ] = 4 ;
467476 SECTION (" - Upper bound OOB" ) {
468477 int range[] = {0 , 100 };
469478 auto r = Range (&range[0 ], &range[1 ], sizeof (int ));
470- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (0 , r).ok ());
479+ if (read_range_oob_error) {
480+ CHECK_FALSE (
481+ subarray.ptr ()
482+ .get ()
483+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
484+ .ok ());
485+ } else {
486+ CHECK (subarray.ptr ()
487+ .get ()
488+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
489+ .ok ());
490+ // The subarray will warn and crop to full domain ranges.
491+ expected = TILEDB_OK;
492+ }
471493 }
472494
473495 SECTION (" - Lower bound OOB" ) {
474496 int range[] = {-1 , 2 };
475497 auto r = Range (&range[0 ], &range[1 ], sizeof (int ));
476- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (0 , r).ok ());
498+ if (read_range_oob_error) {
499+ CHECK_FALSE (
500+ subarray.ptr ()
501+ .get ()
502+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
503+ .ok ());
504+ } else {
505+ // Warn and crop dim0 to [0, 2] with [0, 3] implicitly set on dim1.
506+ CHECK (subarray.ptr ()
507+ .get ()
508+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
509+ .ok ());
510+ expected_data.resize (12 );
511+ expected = TILEDB_OK;
512+ }
477513 }
478514
479515 SECTION (" - Second range OOB" ) {
480516 int range[] = {1 , 4 };
481517 auto r = Range (&range[0 ], &range[1 ], sizeof (int ));
482- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (0 , r).ok ());
483518 int range2[] = {10 , 20 };
484519 auto r2 = Range (&range2[0 ], &range2[1 ], sizeof (int ));
485- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (1 , r2).ok ());
520+ if (read_range_oob_error) {
521+ CHECK_FALSE (
522+ subarray.ptr ()
523+ .get ()
524+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
525+ .ok ());
526+ CHECK_FALSE (
527+ subarray.ptr ()
528+ .get ()
529+ ->subarray_ ->add_range (1 , std::move (r2), read_range_oob_error)
530+ .ok ());
531+ } else {
532+ // Warn and crop dim0 to [1, 3] and dim1 to [3, 3]
533+ CHECK (subarray.ptr ()
534+ .get ()
535+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
536+ .ok ());
537+ CHECK (subarray.ptr ()
538+ .get ()
539+ ->subarray_ ->add_range (1 , std::move (r2), read_range_oob_error)
540+ .ok ());
541+ expected_data = {fill_val, fill_val, fill_val};
542+ expected = TILEDB_OK;
543+ }
486544 }
487545
488546 SECTION (" - Valid ranges" ) {
489547 int range[] = {0 , 1 };
490548 auto r = Range (&range[0 ], &range[1 ], sizeof (int ));
491- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (0 , r).ok ());
492- CHECK (subarray.ptr ().get ()->subarray_ ->add_range_unsafe (1 , r).ok ());
549+ CHECK (subarray.ptr ()
550+ .get ()
551+ ->subarray_ ->add_range (0 , std::move (r), read_range_oob_error)
552+ .ok ());
553+ CHECK (subarray.ptr ()
554+ .get ()
555+ ->subarray_ ->add_range (1 , std::move (r), read_range_oob_error)
556+ .ok ());
557+ expected_data = data_w;
493558 expected = TILEDB_OK;
494559 }
495560
496- Query query (ctx, array_r);
497- query.set_subarray (subarray);
498- query.set_config (cfg);
499-
500- std::vector<int > a (4 );
501- query.set_data_buffer (" a" , a);
502- tiledb::test::ServerQueryBuffers buffers;
503- CHECK (
504- submit_query_wrapper (
505- ctx, array_name, &query, buffers, true , query_v2, false ) == expected);
506-
507- if (expected == TILEDB_OK) {
508- CHECK (query.query_status () == tiledb::Query::Status::COMPLETE);
509- CHECK (a == std::vector<int >{1 , 2 , 3 , 4 });
561+ // If the Subarray threw an exception when adding OOB ranges it will be unset.
562+ if (!read_range_oob_error || expected == TILEDB_OK) {
563+ Query query (ctx, array_r);
564+ query.set_subarray (subarray);
565+ query.set_config (cfg);
566+
567+ std::vector<int > a (expected_data.size ());
568+ query.set_data_buffer (" a" , a);
569+ tiledb::test::ServerQueryBuffers buffers;
570+ CHECK (
571+ submit_query_wrapper (
572+ ctx, array_name, &query, buffers, true , query_v2, false ) ==
573+ expected);
574+
575+ if (expected == TILEDB_OK) {
576+ CHECK (query.query_status () == tiledb::Query::Status::COMPLETE);
577+ CHECK (a == expected_data);
578+ }
510579 }
511580
512581 if (vfs.is_dir (array_name)) {
0 commit comments