diff --git a/cpp/src/lists/interleave_columns.cu b/cpp/src/lists/interleave_columns.cu index 4d1d6448dd0..b9b73d98ed2 100644 --- a/cpp/src/lists/interleave_columns.cu +++ b/cpp/src/lists/interleave_columns.cu @@ -169,6 +169,10 @@ struct compute_string_sizes_and_interleave_lists_fn { auto const start_str_idx = list_offsets[list_id]; auto const end_str_idx = list_offsets[list_id + 1]; + // In case of empty list (i.e. it doesn't contain any string element), we just ignore it because + // there will not be anything to store for that list in the child column. + if (start_str_idx == end_str_idx) { return; } + // read_idx and write_idx are indices of string elements. size_type write_idx = dst_list_offsets[idx]; diff --git a/cpp/tests/lists/combine/concatenate_rows_tests.cpp b/cpp/tests/lists/combine/concatenate_rows_tests.cpp index 8aae523d12b..17d31c3e387 100644 --- a/cpp/tests/lists/combine/concatenate_rows_tests.cpp +++ b/cpp/tests/lists/combine/concatenate_rows_tests.cpp @@ -72,7 +72,7 @@ struct ListConcatenateRowsTypedTest : public cudf::test::BaseFixture { using TypesForTest = cudf::test::Concat; -TYPED_TEST_CASE(ListConcatenateRowsTypedTest, TypesForTest); +TYPED_TEST_SUITE(ListConcatenateRowsTypedTest, TypesForTest); TYPED_TEST(ListConcatenateRowsTypedTest, ConcatenateEmptyColumns) { @@ -110,10 +110,12 @@ TYPED_TEST(ListConcatenateRowsTypedTest, SimpleInputNoNull) { using ListsCol = cudf::test::lists_column_wrapper; - auto const col1 = ListsCol{{1, 2}, {3, 4}, {5, 6}}.release(); - auto const col2 = ListsCol{{7, 8}, {9, 10}, {11, 12}}.release(); - auto const expected = ListsCol{{1, 2, 7, 8}, {3, 4, 9, 10}, {5, 6, 11, 12}}.release(); - auto const results = cudf::lists::concatenate_rows(TView{{col1->view(), col2->view()}}); + auto const col1 = ListsCol{{1, 2}, {3, 4}, {5, 6}}.release(); + auto const empty_lists = ListsCol{ListsCol{}, ListsCol{}, ListsCol{}}.release(); + auto const col2 = ListsCol{{7, 8}, {9, 10}, {11, 12}}.release(); + auto const expected = ListsCol{{1, 2, 7, 8}, {3, 4, 9, 10}, {5, 6, 11, 12}}.release(); + auto const results = + cudf::lists::concatenate_rows(TView{{col1->view(), empty_lists->view(), col2->view()}}); CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*expected, *results, verbosity); } @@ -121,11 +123,13 @@ TYPED_TEST(ListConcatenateRowsTypedTest, SimpleInputWithNullableChild) { using ListsCol = cudf::test::lists_column_wrapper; - auto const col1 = ListsCol{{1, 2}, ListsCol{{null}, null_at(0)}, {5, 6}}.release(); - auto const col2 = ListsCol{{7, 8}, {9, 10}, {11, 12}}.release(); + auto const col1 = ListsCol{{1, 2}, ListsCol{{null}, null_at(0)}, {5, 6}}.release(); + auto const empty_lists = ListsCol{{ListsCol{}, ListsCol{}, ListsCol{}}, null_at(2)}.release(); + auto const col2 = ListsCol{{7, 8}, {9, 10}, {11, 12}}.release(); auto const expected = ListsCol{{1, 2, 7, 8}, ListsCol{{null, 9, 10}, null_at(0)}, {5, 6, 11, 12}}.release(); - auto const results = cudf::lists::concatenate_rows(TView{{col1->view(), col2->view()}}); + auto const results = + cudf::lists::concatenate_rows(TView{{col1->view(), empty_lists->view(), col2->view()}}); CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*expected, *results, verbosity); } @@ -466,3 +470,19 @@ TEST_F(ListConcatenateRowsTest, SlicedStringsColumnsInputWithNulls) CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*expected, *results, verbosity); } } + +TEST_F(ListConcatenateRowsTest, StringsColumnsWithEmptyListTest) +{ + auto const col1 = StrListsCol{{"1", "2", "3", "4"}}.release(); + auto const col2 = StrListsCol{{"a", "b", "c"}}.release(); + auto const col3 = StrListsCol{StrListsCol{}}.release(); + auto const col4 = StrListsCol{{"x", "y", "" /*NULL*/, "z"}, null_at(2)}.release(); + auto const col5 = StrListsCol{{StrListsCol{}}, null_at(0)}.release(); + auto const expected = + StrListsCol{{"1", "2", "3", "4", "a", "b", "c", "x", "y", "" /*NULL*/, "z"}, null_at(9)} + .release(); + auto const results = cudf::lists::concatenate_rows( + TView{{col1->view(), col2->view(), col3->view(), col4->view(), col5->view()}}); + + CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(*expected, *results, verbosity); +}