Skip to content

Commit 435534b

Browse files
committed
GH-30894: [C++][Python] Fix Table::Slice returning incorrect length for tables with no columns
1 parent 6378639 commit 435534b

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

cpp/src/arrow/table.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class SimpleTable : public Table {
101101

102102
std::shared_ptr<Table> Slice(int64_t offset, int64_t length) const override {
103103
auto sliced = columns_;
104-
int64_t num_rows = length;
104+
int64_t num_rows = std::max<int64_t>(0, std::min(length, this->num_rows() - offset));
105105
for (auto& column : sliced) {
106106
column = column->Slice(offset, length);
107107
num_rows = column->length();

cpp/src/arrow/table_test.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,23 @@ TEST_F(TestTable, Slice) {
13191319
*three->Slice(length + length / 3, 2 * (length - length / 3)));
13201320
}
13211321

1322+
TEST_F(TestTable, SliceZeroColumns) {
1323+
const int64_t length = 10;
1324+
auto empty_columns_table = Table::Make(::arrow::schema({}),std::vector<std::shared_ptr<ChunkedArray>>{}, length);
1325+
ASSERT_EQ(empty_columns_table->num_rows(), length);
1326+
ASSERT_EQ(empty_columns_table->Slice(3)->num_rows(), length - 3);
1327+
ASSERT_EQ(empty_columns_table->Slice(0)->num_rows(), length);
1328+
ASSERT_EQ(empty_columns_table->Slice(3, 100)->num_rows(), length - 3);
1329+
ASSERT_EQ(empty_columns_table->Slice(3, 4)->num_rows(), 4);
1330+
ASSERT_EQ(empty_columns_table->Slice(length + 5)->num_rows(), 0);
1331+
1332+
MakeExample1(length);
1333+
auto table = Table::Make(schema_, columns_);
1334+
ASSERT_OK_AND_ASSIGN(auto no_columns, table->SelectColumns({}));
1335+
ASSERT_EQ(no_columns->Slice(1)->num_rows(), table->Slice(1)->num_rows());
1336+
ASSERT_EQ(no_columns->Slice(1, 4)->num_rows(), 4);
1337+
}
1338+
13221339
TEST_F(TestTable, RemoveColumn) {
13231340
const int64_t length = 10;
13241341
MakeExample1(length);

python/pyarrow/tests/test_table.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,22 @@ def test_table_slice_getitem():
13611361
return _table_like_slice_tests(pa.table)
13621362

13631363

1364+
def test_table_slice_no_columns():
1365+
table = pa.table({'col': range(3)})
1366+
empty = table.select([])
1367+
assert empty.num_rows == 3
1368+
1369+
# slice(offset) clamps to the remaining rows
1370+
assert empty.slice(1).num_rows == 2
1371+
assert empty.slice(0).num_rows == 3
1372+
# slice(offset, length) must not exceed the remaining rows
1373+
assert empty.slice(1, 4).num_rows == 2
1374+
# consistent with __getitem__ slicing, which already worked
1375+
assert empty[1:].num_rows == 2
1376+
# offset past the end yields an empty table
1377+
assert empty.slice(5).num_rows == 0
1378+
1379+
13641380
@pytest.mark.pandas
13651381
def test_slice_zero_length_table():
13661382
# ARROW-7907: a segfault on this code was fixed after 0.16.0

0 commit comments

Comments
 (0)