55
66namespace clickhouse {
77
8- ColumnArray::ColumnArray (ColumnRef data)
9- : ColumnArray(data, std::make_shared<ColumnUInt64>())
10- {
8+ namespace {
9+ std::shared_ptr<ColumnUInt64> make_single_offset (size_t value) {
10+ auto res = std::make_shared<ColumnUInt64>();
11+ if (value != 0 ) {
12+ res->Append (value);
13+ }
14+ return res;
15+ }
16+ } // namespace
17+
18+ ColumnArray::ColumnArray (ColumnRef data) : ColumnArray(data, make_single_offset(data->Size ())) {
1119}
1220
1321ColumnArray::ColumnArray (ColumnRef data, std::shared_ptr<ColumnUInt64> offsets)
1422 : Column(Type::CreateArray(data->Type ()))
1523 , data_(data)
1624 , offsets_(offsets)
1725{
26+ const auto rows = offsets_->Size ();
27+ const auto expected_values = rows > 0 ? offsets_->At (rows - 1 ) : 0 ;
28+ std::uint64_t prev = 0 ;
29+ // Ensure the offset array is internally consistent
30+ for (const auto & o : offsets_->GetWritableData ()) {
31+ if (o < prev) {
32+ throw ValidationError (" offsets must be monotonically increasing" );
33+ }
34+ prev = o;
35+ }
36+ if (data_->Size () != expected_values) {
37+ throw ValidationError (" Mismatch between data and offsets: Expected " + std::to_string (expected_values) +
38+ " values in data, but got " + std::to_string (data_->Size ()));
39+ }
1840}
1941
2042ColumnArray::ColumnArray (ColumnArray&& other)
@@ -41,11 +63,15 @@ ColumnRef ColumnArray::Slice(size_t begin, size_t size) const {
4163 if (size && begin + size > Size ())
4264 throw ValidationError (" Slice indexes are out of bounds" );
4365
44- auto result = std::make_shared<ColumnArray>(data_->Slice (GetOffset (begin), GetOffset (begin + size) - GetOffset (begin)));
45- for (size_t i = 0 ; i < size; i++)
46- result->AddOffset (GetSize (begin + i));
66+ auto sliced_data = data_->Slice (GetOffset (begin), GetOffset (begin + size) - GetOffset (begin));
67+ auto offsets = std::make_shared<ColumnUInt64>();
68+ auto offset = uint64_t {0 };
69+ for (size_t i = 0 ; i < size; i++) {
70+ offset += GetSize (begin + i);
71+ offsets->Append (offset);
72+ }
4773
48- return result ;
74+ return std::make_shared<ColumnArray>( std::move (sliced_data), std::move (offsets)) ;
4975}
5076
5177ColumnRef ColumnArray::CloneEmpty () const {
0 commit comments