ClickHouse
241 строка · 6.5 Кб
1#include <Processors/Chunk.h>
2#include <IO/WriteHelpers.h>
3#include <IO/Operators.h>
4#include <Columns/ColumnSparse.h>
5#include <Columns/ColumnConst.h>
6#include <DataTypes/DataTypeLowCardinality.h>
7
8namespace DB
9{
10
11namespace ErrorCodes
12{
13extern const int LOGICAL_ERROR;
14extern const int POSITION_OUT_OF_BOUND;
15}
16
17Chunk::Chunk(DB::Columns columns_, UInt64 num_rows_) : columns(std::move(columns_)), num_rows(num_rows_)
18{
19checkNumRowsIsConsistent();
20}
21
22Chunk::Chunk(Columns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_)
23: columns(std::move(columns_))
24, num_rows(num_rows_)
25, chunk_info(std::move(chunk_info_))
26{
27checkNumRowsIsConsistent();
28}
29
30static Columns unmuteColumns(MutableColumns && mutable_columns)
31{
32Columns columns;
33columns.reserve(mutable_columns.size());
34for (auto & col : mutable_columns)
35columns.emplace_back(std::move(col));
36
37return columns;
38}
39
40Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_)
41: columns(unmuteColumns(std::move(columns_))), num_rows(num_rows_)
42{
43checkNumRowsIsConsistent();
44}
45
46Chunk::Chunk(MutableColumns columns_, UInt64 num_rows_, ChunkInfoPtr chunk_info_)
47: columns(unmuteColumns(std::move(columns_)))
48, num_rows(num_rows_)
49, chunk_info(std::move(chunk_info_))
50{
51checkNumRowsIsConsistent();
52}
53
54Chunk Chunk::clone() const
55{
56return Chunk(getColumns(), getNumRows(), chunk_info);
57}
58
59void Chunk::setColumns(Columns columns_, UInt64 num_rows_)
60{
61columns = std::move(columns_);
62num_rows = num_rows_;
63checkNumRowsIsConsistent();
64}
65
66void Chunk::setColumns(MutableColumns columns_, UInt64 num_rows_)
67{
68columns = unmuteColumns(std::move(columns_));
69num_rows = num_rows_;
70checkNumRowsIsConsistent();
71}
72
73void Chunk::checkNumRowsIsConsistent()
74{
75for (size_t i = 0; i < columns.size(); ++i)
76{
77auto & column = columns[i];
78if (column->size() != num_rows)
79throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid number of rows in Chunk column {}: expected {}, got {}",
80column->getName() + " position " + toString(i), toString(num_rows), toString(column->size()));
81}
82}
83
84MutableColumns Chunk::mutateColumns()
85{
86size_t num_columns = columns.size();
87MutableColumns mutable_columns(num_columns);
88for (size_t i = 0; i < num_columns; ++i)
89mutable_columns[i] = IColumn::mutate(std::move(columns[i]));
90
91columns.clear();
92num_rows = 0;
93
94return mutable_columns;
95}
96
97MutableColumns Chunk::cloneEmptyColumns() const
98{
99size_t num_columns = columns.size();
100MutableColumns mutable_columns(num_columns);
101for (size_t i = 0; i < num_columns; ++i)
102mutable_columns[i] = columns[i]->cloneEmpty();
103return mutable_columns;
104}
105
106Columns Chunk::detachColumns()
107{
108num_rows = 0;
109return std::move(columns);
110}
111
112void Chunk::addColumn(ColumnPtr column)
113{
114if (empty())
115num_rows = column->size();
116else if (column->size() != num_rows)
117throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid number of rows in Chunk column {}, got {}",
118column->getName()+ ": expected " + toString(num_rows), toString(column->size()));
119
120columns.emplace_back(std::move(column));
121}
122
123void Chunk::addColumn(size_t position, ColumnPtr column)
124{
125if (position >= columns.size())
126throw Exception(ErrorCodes::POSITION_OUT_OF_BOUND,
127"Position {} out of bound in Chunk::addColumn(), max position = {}",
128position, columns.size() - 1);
129if (empty())
130num_rows = column->size();
131else if (column->size() != num_rows)
132throw Exception(ErrorCodes::LOGICAL_ERROR,
133"Invalid number of rows in Chunk column {}: expected {}, got {}",
134column->getName(), num_rows, column->size());
135
136columns.emplace(columns.begin() + position, std::move(column));
137}
138
139void Chunk::erase(size_t position)
140{
141if (columns.empty())
142throw Exception(ErrorCodes::POSITION_OUT_OF_BOUND, "Chunk is empty");
143
144if (position >= columns.size())
145throw Exception(ErrorCodes::POSITION_OUT_OF_BOUND, "Position {} out of bound in Chunk::erase(), max position = {}",
146toString(position), toString(columns.size() - 1));
147
148columns.erase(columns.begin() + position);
149}
150
151UInt64 Chunk::bytes() const
152{
153UInt64 res = 0;
154for (const auto & column : columns)
155res += column->byteSize();
156
157return res;
158}
159
160UInt64 Chunk::allocatedBytes() const
161{
162UInt64 res = 0;
163for (const auto & column : columns)
164res += column->allocatedBytes();
165
166return res;
167}
168
169std::string Chunk::dumpStructure() const
170{
171WriteBufferFromOwnString out;
172for (const auto & column : columns)
173out << ' ' << column->dumpStructure();
174
175return out.str();
176}
177
178void Chunk::append(const Chunk & chunk)
179{
180append(chunk, 0, chunk.getNumRows());
181}
182
183void Chunk::append(const Chunk & chunk, size_t from, size_t length)
184{
185MutableColumns mutable_columns = mutateColumns();
186for (size_t position = 0; position < mutable_columns.size(); ++position)
187{
188auto column = chunk.getColumns()[position];
189mutable_columns[position]->insertRangeFrom(*column, from, length);
190}
191size_t rows = mutable_columns[0]->size();
192setColumns(std::move(mutable_columns), rows);
193}
194
195void ChunkMissingValues::setBit(size_t column_idx, size_t row_idx)
196{
197RowsBitMask & mask = rows_mask_by_column_id[column_idx];
198mask.resize(row_idx + 1);
199mask[row_idx] = true;
200}
201
202const ChunkMissingValues::RowsBitMask & ChunkMissingValues::getDefaultsBitmask(size_t column_idx) const
203{
204static RowsBitMask none;
205auto it = rows_mask_by_column_id.find(column_idx);
206if (it != rows_mask_by_column_id.end())
207return it->second;
208return none;
209}
210
211void convertToFullIfConst(Chunk & chunk)
212{
213size_t num_rows = chunk.getNumRows();
214auto columns = chunk.detachColumns();
215for (auto & column : columns)
216column = column->convertToFullColumnIfConst();
217chunk.setColumns(std::move(columns), num_rows);
218}
219
220void convertToFullIfSparse(Chunk & chunk)
221{
222size_t num_rows = chunk.getNumRows();
223auto columns = chunk.detachColumns();
224for (auto & column : columns)
225column = recursiveRemoveSparse(column);
226chunk.setColumns(std::move(columns), num_rows);
227}
228
229Chunk cloneConstWithDefault(const Chunk & chunk, size_t num_rows)
230{
231auto columns = chunk.cloneEmptyColumns();
232for (auto & column : columns)
233{
234column->insertDefault();
235column = ColumnConst::create(std::move(column), num_rows);
236}
237
238return Chunk(std::move(columns), num_rows);
239}
240
241}
242