diff --git a/cpp/src/lists/explode.cu b/cpp/src/lists/explode.cu
index 2b495deb47f..5f6f1c308ac 100644
--- a/cpp/src/lists/explode.cu
+++ b/cpp/src/lists/explode.cu
@@ -62,22 +62,27 @@ std::unique_ptr
build_table(
std::vector> columns = gathered_table.release()->release();
- columns.insert(columns.begin() + explode_column_idx,
- explode_col_gather_map
- ? std::move(detail::gather(table_view({sliced_child}),
- explode_col_gather_map->begin(),
- explode_col_gather_map->end(),
- cudf::out_of_bounds_policy::NULLIFY,
- stream,
- mr)
- ->release()[0])
- : std::make_unique(sliced_child, stream, mr));
+ auto inserted = columns.insert(columns.begin() + explode_column_idx,
+ explode_col_gather_map
+ ? std::move(detail::gather(table_view({sliced_child}),
+ explode_col_gather_map->begin(),
+ explode_col_gather_map->end(),
+ cudf::out_of_bounds_policy::NULLIFY,
+ stream,
+ mr)
+ ->release()[0])
+ : std::make_unique(sliced_child, stream, mr));
if (position_array) {
size_type position_size = position_array->size();
+ // the null mask for position matches the exploded column's gather map, so copy it over
+ rmm::device_buffer nullmask =
+ explode_col_gather_map ? copy_bitmask(*inserted->get()) : rmm::device_buffer(0, stream);
columns.insert(columns.begin() + explode_column_idx,
- std::make_unique(
- data_type(type_to_id()), position_size, position_array->release()));
+ std::make_unique(data_type(type_to_id()),
+ position_size,
+ position_array->release(),
+ std::move(nullmask)));
}
return std::make_unique(std::move(columns));
diff --git a/cpp/tests/lists/explode_tests.cpp b/cpp/tests/lists/explode_tests.cpp
index 4c7ded0efd7..ded3d2b9193 100644
--- a/cpp/tests/lists/explode_tests.cpp
+++ b/cpp/tests/lists/explode_tests.cpp
@@ -530,7 +530,7 @@ TEST_F(ExplodeOuterTest, SingleNull)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 0, 1, 0, 0, 1};
+ FCW expected_pos_col{{0, 0, 1, 0, 0, 1}, {0, 1, 1, 0, 1, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -561,7 +561,7 @@ TEST_F(ExplodeOuterTest, Nulls)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 2, 0, 0, 1};
+ FCW expected_pos_col{{0, 1, 2, 0, 0, 1}, {1, 1, 1, 0, 1, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -591,7 +591,7 @@ TEST_F(ExplodeOuterTest, AllNulls)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 0, 0};
+ FCW expected_pos_col{{0, 0, 0}, {0, 0, 0}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -624,7 +624,7 @@ TEST_F(ExplodeOuterTest, SequentialNulls)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 2, 0, 1, 0, 0, 0, 1, 2};
+ FCW expected_pos_col{{0, 1, 2, 0, 1, 0, 0, 0, 1, 2}, {1, 1, 0, 1, 1, 0, 0, 1, 1, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -655,7 +655,7 @@ TEST_F(ExplodeOuterTest, MoreEmptyThanData)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 0, 0, 0, 0, 0};
+ FCW expected_pos_col{{0, 1, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -685,7 +685,7 @@ TEST_F(ExplodeOuterTest, TrailingEmptys)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 0, 0, 0, 0};
+ FCW expected_pos_col{{0, 1, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -718,7 +718,7 @@ TEST_F(ExplodeOuterTest, LeadingNulls)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 0, 0, 0, 0, 1};
+ FCW expected_pos_col{{0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 1, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -753,7 +753,7 @@ TEST_F(ExplodeOuterTest, NullsInList)
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 2, 0, 1, 2, 3, 0, 0, 1, 2};
+ FCW expected_pos_col{{0, 1, 2, 0, 1, 2, 3, 0, 0, 1, 2}, {1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -813,7 +813,7 @@ TEST_F(ExplodeOuterTest, NestedNulls)
auto ret = cudf::explode_outer(t, 0);
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 0, 0, 1, 2};
+ FCW expected_pos_col{{0, 1, 0, 0, 1, 2}, {1, 1, 0, 1, 1, 1}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(t, 0);
@@ -884,7 +884,8 @@ TEST_F(ExplodeOuterTest, NullsInNestedDoubleExplode)
CUDF_TEST_EXPECT_TABLES_EQUAL(ret->view(), expected);
- FCW expected_pos_col{0, 1, 0, 0, 1, 2, 0, 1, 0, 1, 0, 0, 1};
+ FCW expected_pos_col{{0, 1, 0, 0, 1, 2, 0, 1, 0, 1, 0, 0, 1},
+ {1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}};
cudf::table_view pos_expected({expected_pos_col, expected_a, expected_b});
auto pos_ret = cudf::explode_outer_position(first_explode_ret->view(), 0);