aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Columns/ColumnFunction.h
blob: c21e88744e01e3f774c379b0972510c6b076e36f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#pragma once

#include <Core/Field.h>
#include <Core/NamesAndTypes.h>
#include <Core/ColumnsWithTypeAndName.h>
#include <Columns/IColumn.h>

namespace DB
{
namespace ErrorCodes
{
    extern const int NOT_IMPLEMENTED;
}

class IFunctionBase;
using FunctionBasePtr = std::shared_ptr<const IFunctionBase>;

/** A column containing a lambda expression.
  * Behaves like a constant-column. Contains an expression, but not input or output data.
  */
class ColumnFunction final : public COWHelper<IColumn, ColumnFunction>
{
private:
    friend class COWHelper<IColumn, ColumnFunction>;

    ColumnFunction(
        size_t size,
        FunctionBasePtr function_,
        const ColumnsWithTypeAndName & columns_to_capture,
        bool is_short_circuit_argument_ = false,
        bool is_function_compiled_ = false,
        bool recursively_convert_result_to_full_column_if_low_cardinality_ = false);

public:
    const char * getFamilyName() const override { return "Function"; }
    TypeIndex getDataType() const override { return TypeIndex::Function; }

    MutableColumnPtr cloneResized(size_t size) const override;

    size_t size() const override { return elements_size; }

    ColumnPtr cut(size_t start, size_t length) const override;
    ColumnPtr replicate(const Offsets & offsets) const override;
    ColumnPtr filter(const Filter & filt, ssize_t result_size_hint) const override;
    void expand(const Filter & mask, bool inverted) override;
    ColumnPtr permute(const Permutation & perm, size_t limit) const override;
    ColumnPtr index(const IColumn & indexes, size_t limit) const override;

    std::vector<MutableColumnPtr> scatter(IColumn::ColumnIndex num_columns,
                                          const IColumn::Selector & selector) const override;

    void getExtremes(Field &, Field &) const override {}

    size_t byteSize() const override;
    size_t byteSizeAt(size_t n) const override;
    size_t allocatedBytes() const override;

    void appendArguments(const ColumnsWithTypeAndName & columns);
    ColumnWithTypeAndName reduce() const;

    Field operator[](size_t) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot get value from {}", getName());
    }

    void get(size_t, Field &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot get value from {}", getName());
    }

    StringRef getDataAt(size_t) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot get value from {}", getName());
    }

    bool isDefaultAt(size_t) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "isDefaultAt is not implemented for {}", getName());
    }

    void insert(const Field &) override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot insert into {}", getName());
    }

    void insertDefault() override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot insert into {}", getName());
    }

    void insertFrom(const IColumn & src, size_t n) override;
    void insertRangeFrom(const IColumn &, size_t start, size_t length) override;

    void insertData(const char *, size_t) override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot insert into {}", getName());
    }

    StringRef serializeValueIntoArena(size_t, Arena &, char const *&, const UInt8 *) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot serialize from {}", getName());
    }

    const char * deserializeAndInsertFromArena(const char *) override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot deserialize to {}", getName());
    }

    const char * skipSerializedInArena(const char*) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot skip serialized {}", getName());
    }

    void updateHashWithValue(size_t, SipHash &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "updateHashWithValue is not implemented for {}", getName());
    }

    void updateWeakHash32(WeakHash32 &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "updateWeakHash32 is not implemented for {}", getName());
    }

    void updateHashFast(SipHash &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "updateHashFast is not implemented for {}", getName());
    }

    void popBack(size_t) override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "popBack is not implemented for {}", getName());
    }

    int compareAt(size_t, size_t, const IColumn &, int) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "compareAt is not implemented for {}", getName());
    }

    void compareColumn(const IColumn &, size_t, PaddedPODArray<UInt64> *, PaddedPODArray<Int8> &, int, int) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "compareColumn is not implemented for {}", getName());
    }

    bool hasEqualValues() const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "hasEqualValues is not implemented for {}", getName());
    }

    void getPermutation(IColumn::PermutationSortDirection, IColumn::PermutationSortStability,
                        size_t, int, Permutation &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "getPermutation is not implemented for {}", getName());
    }

    void updatePermutation(IColumn::PermutationSortDirection, IColumn::PermutationSortStability,
                        size_t, int, Permutation &, EqualRanges &) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "updatePermutation is not implemented for {}", getName());
    }

    void gather(ColumnGathererStream &) override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Method gather is not supported for {}", getName());
    }

    double getRatioOfDefaultRows(double) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Method getRatioOfDefaultRows is not supported for {}", getName());
    }

    UInt64 getNumberOfDefaultRows() const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Method getNumberOfDefaultRows is not supported for {}", getName());
    }

    void getIndicesOfNonDefaultRows(Offsets &, size_t, size_t) const override
    {
        throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Method getIndicesOfNonDefaultRows is not supported for {}", getName());
    }

    bool isShortCircuitArgument() const { return is_short_circuit_argument; }

    DataTypePtr getResultType() const;

    /// Create copy of this column, but with recursively_convert_result_to_full_column_if_low_cardinality = true
    ColumnPtr recursivelyConvertResultToFullColumnIfLowCardinality() const;

private:
    size_t elements_size;
    FunctionBasePtr function;
    ColumnsWithTypeAndName captured_columns;

    /// Determine if it's used as a lazy executed argument for short-circuit function.
    /// It's needed to distinguish between lazy executed argument and
    /// argument with ColumnFunction column (some functions can return it)
    /// See ExpressionActions.cpp for details.
    bool is_short_circuit_argument;

    /// Special flag for lazy executed argument for short-circuit function.
    /// If true, call recursiveRemoveLowCardinality on the result column
    /// when function will be executed.
    /// It's used when short-circuit function uses default implementation
    /// for low cardinality arguments.
    bool recursively_convert_result_to_full_column_if_low_cardinality = false;

    /// Determine if passed function is compiled. Used for profiling.
    bool is_function_compiled;

    void appendArgument(const ColumnWithTypeAndName & column);

    void addOffsetsForReplication(const IColumn::Offsets & offsets);
};

const ColumnFunction * checkAndGetShortCircuitArgument(const ColumnPtr & column);

}