1#include <Processors/Chunk.h>
2#include <IO/WriteHelpers.h>
3#include <IO/Operators.h>
4
5namespace DB
6{
7
8namespace ErrorCodes
9{
10 extern const int LOGICAL_ERROR;
11 extern const int POSITION_OUT_OF_BOUND;
12}
13
14Chunk::Chunk(DB::Columns columns_, UInt64 num_rows_) : columns(std::move(columns_)), num_rows(num_rows_)
15{
16 checkNumRowsIsConsistent();
17}
18
19Chunk::Chunk(Columns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_)
20 : columns(std::move(columns_)), num_rows(num_rows_), chunk_info(std::move(chunk_info_))
21{
22 checkNumRowsIsConsistent();
23}
24
25static Columns unmuteColumns(MutableColumns && mut_columns)
26{
27 Columns columns;
28 columns.reserve(mut_columns.size());
29 for (auto & col : mut_columns)
30 columns.emplace_back(std::move(col));
31
32 return columns;
33}
34
35Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_)
36 : columns(unmuteColumns(std::move(columns_))), num_rows(num_rows_)
37{
38 checkNumRowsIsConsistent();
39}
40
41Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_)
42 : columns(unmuteColumns(std::move(columns_))), num_rows(num_rows_), chunk_info(std::move(chunk_info_))
43{
44 checkNumRowsIsConsistent();
45}
46
47Chunk Chunk::clone() const
48{
49 return Chunk(getColumns(), getNumRows());
50}
51
52void Chunk::setColumns(Columns columns_, UInt64 num_rows_)
53{
54 columns = std::move(columns_);
55 num_rows = num_rows_;
56 checkNumRowsIsConsistent();
57}
58
59void Chunk::setColumns(MutableColumns columns_, UInt64 num_rows_)
60{
61 columns = unmuteColumns(std::move(columns_));
62 num_rows = num_rows_;
63 checkNumRowsIsConsistent();
64}
65
66void Chunk::checkNumRowsIsConsistent()
67{
68 for (auto & column : columns)
69 if (column->size() != num_rows)
70 throw Exception("Invalid number of rows in Chunk column " + column->getName()+ ": expected " +
71 toString(num_rows) + ", got " + toString(column->size()), ErrorCodes::LOGICAL_ERROR);
72}
73
74MutableColumns Chunk::mutateColumns()
75{
76 size_t num_columns = columns.size();
77 MutableColumns mut_columns(num_columns);
78 for (size_t i = 0; i < num_columns; ++i)
79 mut_columns[i] = (*std::move(columns[i])).mutate();
80
81 columns.clear();
82 num_rows = 0;
83
84 return mut_columns;
85}
86
87MutableColumns Chunk::cloneEmptyColumns() const
88{
89 size_t num_columns = columns.size();
90 MutableColumns mut_columns(num_columns);
91 for (size_t i = 0; i < num_columns; ++i)
92 mut_columns[i] = columns[i]->cloneEmpty();
93 return mut_columns;
94}
95
96Columns Chunk::detachColumns()
97{
98 num_rows = 0;
99 return std::move(columns);
100}
101
102void Chunk::addColumn(ColumnPtr column)
103{
104 if (column->size() != num_rows)
105 throw Exception("Invalid number of rows in Chunk column " + column->getName()+ ": expected " +
106 toString(num_rows) + ", got " + toString(column->size()), ErrorCodes::LOGICAL_ERROR);
107
108 columns.emplace_back(std::move(column));
109}
110
111void Chunk::erase(size_t position)
112{
113 if (columns.empty())
114 throw Exception("Chunk is empty", ErrorCodes::POSITION_OUT_OF_BOUND);
115
116 if (position >= columns.size())
117 throw Exception("Position " + toString(position) + " out of bound in Chunk::erase(), max position = "
118 + toString(columns.size() - 1), ErrorCodes::POSITION_OUT_OF_BOUND);
119
120 columns.erase(columns.begin() + position);
121}
122
123UInt64 Chunk::bytes() const
124{
125 UInt64 res = 0;
126 for (const auto & column : columns)
127 res += column->byteSize();
128
129 return res;
130}
131
132UInt64 Chunk::allocatedBytes() const
133{
134 UInt64 res = 0;
135 for (const auto & column : columns)
136 res += column->allocatedBytes();
137
138 return res;
139}
140
141std::string Chunk::dumpStructure() const
142{
143 WriteBufferFromOwnString out;
144 for (auto & column : columns)
145 out << ' ' << column->dumpStructure();
146
147 return out.str();
148}
149
150
151void ChunkMissingValues::setBit(size_t column_idx, size_t row_idx)
152{
153 RowsBitMask & mask = rows_mask_by_column_id[column_idx];
154 mask.resize(row_idx + 1);
155 mask[row_idx] = true;
156}
157
158const ChunkMissingValues::RowsBitMask & ChunkMissingValues::getDefaultsBitmask(size_t column_idx) const
159{
160 static RowsBitMask none;
161 auto it = rows_mask_by_column_id.find(column_idx);
162 if (it != rows_mask_by_column_id.end())
163 return it->second;
164 return none;
165}
166
167}
168