ClickHouse

Форк
0
/
isNotNull.cpp 
120 строк · 4.2 Кб
1
#include <Columns/ColumnLowCardinality.h>
2
#include <Columns/ColumnNullable.h>
3
#include <Columns/ColumnVariant.h>
4
#include <Core/ColumnNumbers.h>
5
#include <DataTypes/DataTypesNumber.h>
6
#include <Functions/FunctionFactory.h>
7
#include <Functions/FunctionHelpers.h>
8
#include <Functions/IFunction.h>
9
#include <Functions/PerformanceAdaptors.h>
10
#include <Common/assert_cast.h>
11

12
namespace DB
13
{
14
namespace
15
{
16

17
/// Implements the function isNotNull which returns true if a value
18
/// is not null, false otherwise.
19
class FunctionIsNotNull : public IFunction
20
{
21
public:
22
    static constexpr auto name = "isNotNull";
23

24
    static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionIsNotNull>(); }
25

26
    std::string getName() const override
27
    {
28
        return name;
29
    }
30

31
    size_t getNumberOfArguments() const override { return 1; }
32
    bool useDefaultImplementationForNulls() const override { return false; }
33
    bool useDefaultImplementationForConstants() const override { return true; }
34
    bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }
35
    bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
36
    ColumnNumbers getArgumentsThatDontImplyNullableReturnType(size_t /*number_of_arguments*/) const override { return {0}; }
37

38
    DataTypePtr getReturnTypeImpl(const DataTypes &) const override
39
    {
40
        return std::make_shared<DataTypeUInt8>();
41
    }
42

43
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
44
    {
45
        const ColumnWithTypeAndName & elem = arguments[0];
46

47
        if (isVariant(elem.type))
48
        {
49
            const auto & discriminators = checkAndGetColumn<ColumnVariant>(*elem.column)->getLocalDiscriminators();
50
            auto res = DataTypeUInt8().createColumn();
51
            auto & data = typeid_cast<ColumnUInt8 &>(*res).getData();
52
            data.resize(discriminators.size());
53
            for (size_t i = 0; i < discriminators.size(); ++i)
54
                data[i] = discriminators[i] != ColumnVariant::NULL_DISCRIMINATOR;
55
            return res;
56
        }
57

58
        if (elem.type->isLowCardinalityNullable())
59
        {
60
            const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(*elem.column);
61
            const size_t null_index = low_cardinality_column->getDictionary().getNullValueIndex();
62
            auto res = DataTypeUInt8().createColumn();
63
            auto & data = typeid_cast<ColumnUInt8 &>(*res).getData();
64
            data.resize(low_cardinality_column->size());
65
            for (size_t i = 0; i != low_cardinality_column->size(); ++i)
66
                data[i] = (low_cardinality_column->getIndexAt(i) != null_index);
67
            return res;
68
        }
69

70
        if (const auto * nullable = checkAndGetColumn<ColumnNullable>(*elem.column))
71
        {
72
            /// Return the negated null map.
73
            auto res_column = ColumnUInt8::create(input_rows_count);
74
            const auto & src_data = nullable->getNullMapData();
75
            auto & res_data = assert_cast<ColumnUInt8 &>(*res_column).getData();
76
            vector(src_data, res_data);
77
            return res_column;
78
        }
79
        else
80
        {
81
            /// Since no element is nullable, return a constant one.
82
            return DataTypeUInt8().createColumnConst(elem.column->size(), 1u);
83
        }
84
    }
85

86
private:
87
    MULTITARGET_FUNCTION_AVX2_SSE42(
88
    MULTITARGET_FUNCTION_HEADER(static void NO_INLINE), vectorImpl, MULTITARGET_FUNCTION_BODY((const PaddedPODArray<UInt8> & null_map, PaddedPODArray<UInt8> & res) /// NOLINT
89
    {
90
        size_t size = null_map.size();
91
        for (size_t i = 0; i < size; ++i)
92
            res[i] = !null_map[i];
93
    }))
94

95
    static void NO_INLINE vector(const PaddedPODArray<UInt8> & null_map, PaddedPODArray<UInt8> & res)
96
    {
97
#if USE_MULTITARGET_CODE
98
        if (isArchSupported(TargetArch::AVX2))
99
        {
100
            vectorImplAVX2(null_map, res);
101
            return;
102
        }
103

104
        if (isArchSupported(TargetArch::SSE42))
105
        {
106
            vectorImplSSE42(null_map, res);
107
            return;
108
        }
109
#endif
110
        vectorImpl(null_map, res);
111
    }
112
};
113
}
114

115
REGISTER_FUNCTION(IsNotNull)
116
{
117
    factory.registerFunction<FunctionIsNotNull>();
118
}
119

120
}
121

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.