Skip to content

Commit bff8bba

Browse files
committed
ColumnConstable
1 parent c380e31 commit bff8bba

File tree

5 files changed

+645
-1
lines changed

5 files changed

+645
-1
lines changed

src/Columns/ColumnConstable.cpp

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#include <IO/WriteHelpers.h>
2+
3+
#include <Columns/ColumnConstable.h>
4+
#include <Columns/ColumnConst.h>
5+
#include <Columns/ColumnsCommon.h>
6+
#include <Common/HashTable/Hash.h>
7+
#include <Common/WeakHash.h>
8+
#include <Common/iota.h>
9+
#include <Common/typeid_cast.h>
10+
11+
#include <base/defines.h>
12+
13+
#if defined(MEMORY_SANITIZER)
14+
#include <sanitizer/msan_interface.h>
15+
#endif
16+
17+
18+
namespace DB
19+
{
20+
21+
namespace ErrorCodes
22+
{
23+
extern const int LOGICAL_ERROR;
24+
extern const int NOT_IMPLEMENTED;
25+
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
26+
}
27+
28+
ColumnConstable::ColumnConstable(const ColumnPtr & data_, size_t s_)
29+
: data(data_), s(s_)
30+
{
31+
/// Squash Constable of Const or Constable.
32+
while (true)
33+
{
34+
if (const ColumnConstable * const_data = typeid_cast<const ColumnConstable *>(data.get()))
35+
{
36+
data = const_data->getDataColumnPtr();
37+
continue;
38+
}
39+
if (const ColumnConst * const_data = typeid_cast<const ColumnConst *>(data.get()))
40+
{
41+
data = const_data->getDataColumnPtr();
42+
continue;
43+
}
44+
break;
45+
}
46+
47+
is_const = (data->size() == 1);
48+
49+
/// Check that the value is initialized. We do it earlier, before it will be used, to ease debugging.
50+
#if defined(MEMORY_SANITIZER)
51+
if (data->isFixedAndContiguous())
52+
{
53+
StringRef value = data->getDataAt(0);
54+
__msan_check_mem_is_initialized(value.data, value.size);
55+
}
56+
#endif
57+
}
58+
59+
void ColumnConstable::convertDataToFullColumn()
60+
{
61+
if (!is_const)
62+
return;
63+
if (s != 1)
64+
data = data->replicate(Offsets(1, s));
65+
is_const = false;
66+
}
67+
68+
ColumnPtr ColumnConstable::convertToFullColumn() const
69+
{
70+
if (!is_const || s == 1)
71+
return data;
72+
return data->replicate(Offsets(1, s));
73+
}
74+
75+
ColumnPtr ColumnConstable::removeLowCardinality() const
76+
{
77+
return ColumnConstable::create(data->convertToFullColumnIfLowCardinality(), s);
78+
}
79+
80+
ColumnPtr ColumnConstable::filter(const Filter & filt, ssize_t result_size_hint) const
81+
{
82+
if (!is_const)
83+
return data->filter(filt, result_size_hint);
84+
85+
if (s != filt.size())
86+
throw Exception(ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH, "Size of filter ({}) doesn't match size of column ({})",
87+
filt.size(), toString(s));
88+
89+
size_t new_size = countBytesInFilter(filt);
90+
return cloneResized(new_size);
91+
}
92+
93+
void ColumnConstable::expand(const Filter & mask, bool inverted)
94+
{
95+
if (mask.size() < s)
96+
throw Exception(ErrorCodes::LOGICAL_ERROR, "Mask size should be no less than data size.");
97+
98+
size_t bytes_count = countBytesInFilter(mask);
99+
if (inverted)
100+
bytes_count = mask.size() - bytes_count;
101+
102+
if (bytes_count < s)
103+
throw Exception(ErrorCodes::LOGICAL_ERROR, "Not enough bytes in mask");
104+
if (bytes_count > s)
105+
throw Exception(ErrorCodes::LOGICAL_ERROR, "Too many bytes in mask");
106+
107+
s = mask.size();
108+
}
109+
110+
111+
ColumnPtr ColumnConstable::replicate(const Offsets & offsets) const
112+
{
113+
if (!is_const)
114+
return data->replicate(offsets);
115+
116+
if (s != offsets.size())
117+
throw Exception(ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH, "Size of offsets ({}) doesn't match size of column ({})",
118+
offsets.size(), toString(s));
119+
120+
size_t replicated_size = 0 == s ? 0 : offsets.back();
121+
return ColumnConst::create(data, replicated_size);
122+
}
123+
124+
ColumnPtr ColumnConstable::permute(const Permutation & perm, size_t limit) const
125+
{
126+
if (!is_const)
127+
return data->permute(perm, limit);
128+
129+
limit = getLimitForPermutation(size(), perm.size(), limit);
130+
return ColumnConst::create(data, limit);
131+
}
132+
133+
ColumnPtr ColumnConstable::index(const IColumn & indexes, size_t limit) const
134+
{
135+
if (!is_const)
136+
return data->index(indexes, limit);
137+
138+
if (limit == 0)
139+
limit = indexes.size();
140+
141+
if (indexes.size() < limit)
142+
throw Exception(ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH, "Size of indexes ({}) is less than required ({})",
143+
indexes.size(), toString(limit));
144+
145+
return ColumnConst::create(data, limit);
146+
}
147+
148+
MutableColumns ColumnConstable::scatter(ColumnIndex num_columns, const Selector & selector) const
149+
{
150+
if (!is_const)
151+
return data->scatter(num_columns, selector);
152+
153+
if (s != selector.size())
154+
throw Exception(ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH, "Size of selector ({}) doesn't match size of column ({})",
155+
selector.size(), toString(s));
156+
157+
std::vector<size_t> counts = countColumnsSizeInSelector(num_columns, selector);
158+
159+
MutableColumns res(num_columns);
160+
for (size_t i = 0; i < num_columns; ++i)
161+
res[i] = cloneResized(counts[i]);
162+
163+
return res;
164+
}
165+
166+
void ColumnConstable::gather(ColumnGathererStream &)
167+
{
168+
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot gather into constant column {}", getName());
169+
}
170+
171+
void ColumnConstable::getPermutation(PermutationSortDirection /*direction*/, PermutationSortStability /*stability*/,
172+
size_t /*limit*/, int /*nan_direction_hint*/, Permutation & res) const
173+
{
174+
res.resize_exact(s);
175+
iota(res.data(), s, IColumn::Permutation::value_type(0));
176+
}
177+
178+
void ColumnConstable::updatePermutation(PermutationSortDirection /*direction*/, PermutationSortStability /*stability*/,
179+
size_t, int, Permutation &, EqualRanges &) const
180+
{
181+
}
182+
183+
WeakHash32 ColumnConstable::getWeakHash32() const
184+
{
185+
WeakHash32 element_hash = data->getWeakHash32();
186+
if (!is_const)
187+
return element_hash;
188+
return WeakHash32(s, element_hash.getData()[0]);
189+
}
190+
191+
void ColumnConstable::compareColumn(
192+
const IColumn & rhs,
193+
size_t rhs_row_num,
194+
PaddedPODArray<UInt64> * row_indexes,
195+
PaddedPODArray<Int8> & compare_results,
196+
int direction,
197+
int nan_direction_hint) const
198+
{
199+
if (!is_const)
200+
return data->compareColumn(rhs, rhs_row_num, row_indexes, compare_results, direction, nan_direction_hint);
201+
Int8 res = compareAt(1, 1, rhs, nan_direction_hint);
202+
std::fill(compare_results.begin(), compare_results.end(), res);
203+
}
204+
205+
ColumnConstable::Ptr createColumnConstable(const ColumnPtr & column, Field value)
206+
{
207+
auto data = column->cloneEmpty();
208+
data->insert(value);
209+
return ColumnConstable::create(std::move(data), 1);
210+
}
211+
212+
ColumnConstable::Ptr createColumnConstable(const ColumnPtr & column, size_t const_value_index)
213+
{
214+
auto data = column->cloneEmpty();
215+
data->insertFrom(*column, const_value_index);
216+
return ColumnConstable::create(std::move(data), 1);
217+
}
218+
219+
ColumnConstable::Ptr createColumnConstableWithDefaultValue(const ColumnPtr & column)
220+
{
221+
auto data = column->cloneEmpty();
222+
data->insertDefault();
223+
return ColumnConstable::create(std::move(data), 1);
224+
}
225+
226+
227+
}

0 commit comments

Comments
 (0)