1#pragma once
2#include <Columns/IColumn.h>
3#include <Common/UInt128.h>
4
5namespace DB
6{
7
8class IColumnUnique : public IColumn
9{
10public:
11 using ColumnUniquePtr = IColumn::template immutable_ptr<IColumnUnique>;
12 using MutableColumnUniquePtr = IColumn::template mutable_ptr<IColumnUnique>;
13
14 /// Column always contains Null if it's Nullable and empty string if it's String or Nullable(String).
15 /// So, size may be greater than the number of inserted unique values.
16 virtual const ColumnPtr & getNestedColumn() const = 0;
17 /// The same as getNestedColumn, but removes null map if nested column is nullable.
18 virtual const ColumnPtr & getNestedNotNullableColumn() const = 0;
19
20 virtual bool nestedColumnIsNullable() const = 0;
21
22 /// Returns array with StringRefHash calculated for each row of getNestedNotNullableColumn() column.
23 /// Returns nullptr if nested column doesn't contain strings. Otherwise calculates hash (if it wasn't).
24 /// Uses thread-safe cache.
25 virtual const UInt64 * tryGetSavedHash() const = 0;
26
27 size_t size() const override { return getNestedNotNullableColumn()->size(); }
28
29 /// Appends new value at the end of column (column's size is increased by 1).
30 /// Is used to transform raw strings to Blocks (for example, inside input format parsers)
31 virtual size_t uniqueInsert(const Field & x) = 0;
32
33 virtual size_t uniqueInsertFrom(const IColumn & src, size_t n) = 0;
34 /// Appends range of elements from other column.
35 /// Could be used to concatenate columns.
36 virtual MutableColumnPtr uniqueInsertRangeFrom(const IColumn & src, size_t start, size_t length) = 0;
37
38 struct IndexesWithOverflow
39 {
40 MutableColumnPtr indexes;
41 MutableColumnPtr overflowed_keys;
42 };
43 /// Like uniqueInsertRangeFrom, but doesn't insert keys if inner dictionary has more than max_dictionary_size keys.
44 /// Keys that won't be inserted into dictionary will be into overflowed_keys, indexes will be calculated for
45 /// concatenation of nested column (which can be got from getNestedColumn() function) and overflowed_keys.
46 virtual IndexesWithOverflow uniqueInsertRangeWithOverflow(const IColumn & src, size_t start,
47 size_t length, size_t max_dictionary_size) = 0;
48
49 /// Appends data located in specified memory chunk if it is possible (throws an exception if it cannot be implemented).
50 /// Is used to optimize some computations (in aggregation, for example).
51 /// Parameter length could be ignored if column values have fixed size.
52 virtual size_t uniqueInsertData(const char * pos, size_t length) = 0;
53
54 virtual size_t getDefaultValueIndex() const = 0; /// Nullable ? getNullValueIndex : getNestedTypeDefaultValueIndex
55 virtual size_t getNullValueIndex() const = 0; /// Throws if not nullable.
56 virtual size_t getNestedTypeDefaultValueIndex() const = 0; /// removeNullable()->getDefault() value index
57 virtual bool canContainNulls() const = 0;
58
59 virtual size_t uniqueDeserializeAndInsertFromArena(const char * pos, const char *& new_pos) = 0;
60
61 /// Returns dictionary hash which is sipHash is applied to each row of nested column.
62 virtual UInt128 getHash() const = 0;
63
64 const char * getFamilyName() const override { return "ColumnUnique"; }
65
66 void insert(const Field &) override
67 {
68 throw Exception("Method insert is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
69 }
70
71 void insertRangeFrom(const IColumn &, size_t, size_t) override
72 {
73 throw Exception("Method insertRangeFrom is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
74 }
75
76 void insertData(const char *, size_t) override
77 {
78 throw Exception("Method insertData is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
79 }
80
81 void insertDefault() override
82 {
83 throw Exception("Method insertDefault is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
84 }
85
86 void popBack(size_t) override
87 {
88 throw Exception("Method popBack is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
89 }
90
91 void gather(ColumnGathererStream &) override
92 {
93 throw Exception("Method gather is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
94 }
95
96 const char * deserializeAndInsertFromArena(const char *) override
97 {
98 throw Exception("Method deserializeAndInsertFromArena is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
99 }
100
101 ColumnPtr index(const IColumn &, size_t) const override
102 {
103 throw Exception("Method index is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
104 }
105
106 ColumnPtr cut(size_t, size_t) const override
107 {
108 throw Exception("Method cut is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
109 }
110
111 ColumnPtr filter(const IColumn::Filter &, ssize_t) const override
112 {
113 throw Exception("Method filter is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
114 }
115
116 ColumnPtr permute(const IColumn::Permutation &, size_t) const override
117 {
118 throw Exception("Method permute is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
119 }
120
121 ColumnPtr replicate(const IColumn::Offsets &) const override
122 {
123 throw Exception("Method replicate is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
124 }
125
126 void getPermutation(bool, size_t, int, IColumn::Permutation &) const override
127 {
128 throw Exception("Method getPermutation is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
129 }
130
131 std::vector<MutableColumnPtr> scatter(IColumn::ColumnIndex, const IColumn::Selector &) const override
132 {
133 throw Exception("Method scatter is not supported for ColumnUnique.", ErrorCodes::NOT_IMPLEMENTED);
134 }
135};
136
137using ColumnUniquePtr = IColumnUnique::ColumnUniquePtr;
138using MutableColumnUniquePtr = IColumnUnique::MutableColumnUniquePtr;
139
140}
141