ClickHouse
93 строки · 3.2 Кб
1#include <Functions/IFunction.h>2#include <Functions/FunctionHelpers.h>3#include <Functions/FunctionFactory.h>4#include <DataTypes/DataTypesNumber.h>5#include <Core/ColumnNumbers.h>6#include <Columns/ColumnNullable.h>7#include <Columns/ColumnLowCardinality.h>8#include <Columns/ColumnVariant.h>9
10
11namespace DB12{
13namespace
14{
15
16/// Implements the function isNull which returns true if a value
17/// is null, false otherwise.
18class FunctionIsNull : public IFunction19{
20public:21static constexpr auto name = "isNull";22
23static FunctionPtr create(ContextPtr)24{25return std::make_shared<FunctionIsNull>();26}27
28std::string getName() const override29{30return name;31}32
33size_t getNumberOfArguments() const override { return 1; }34bool useDefaultImplementationForNulls() const override { return false; }35bool useDefaultImplementationForLowCardinalityColumns() const override { return false; }36bool useDefaultImplementationForConstants() const override { return true; }37bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }38ColumnNumbers getArgumentsThatDontImplyNullableReturnType(size_t /*number_of_arguments*/) const override { return {0}; }39
40DataTypePtr getReturnTypeImpl(const DataTypes &) const override41{42return std::make_shared<DataTypeUInt8>();43}44
45ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t) const override46{47const ColumnWithTypeAndName & elem = arguments[0];48
49if (isVariant(elem.type))50{51const auto & discriminators = checkAndGetColumn<ColumnVariant>(*elem.column)->getLocalDiscriminators();52auto res = DataTypeUInt8().createColumn();53auto & data = typeid_cast<ColumnUInt8 &>(*res).getData();54data.reserve(discriminators.size());55for (auto discr : discriminators)56data.push_back(discr == ColumnVariant::NULL_DISCRIMINATOR);57return res;58}59
60if (elem.type->isLowCardinalityNullable())61{62const auto * low_cardinality_column = checkAndGetColumn<ColumnLowCardinality>(*elem.column);63size_t null_index = low_cardinality_column->getDictionary().getNullValueIndex();64auto res = DataTypeUInt8().createColumn();65auto & data = typeid_cast<ColumnUInt8 &>(*res).getData();66data.reserve(low_cardinality_column->size());67for (size_t i = 0; i != low_cardinality_column->size(); ++i)68data.push_back(low_cardinality_column->getIndexAt(i) == null_index);69return res;70}71
72if (const auto * nullable = checkAndGetColumn<ColumnNullable>(*elem.column))73{74/// Merely return the embedded null map.75return nullable->getNullMapColumnPtr();76}77else78{79/// Since no element is nullable, return a zero-constant column representing80/// a zero-filled null map.81return DataTypeUInt8().createColumnConst(elem.column->size(), 0u);82}83}84};85
86}
87
88REGISTER_FUNCTION(IsNull)89{
90factory.registerFunction<FunctionIsNull>({}, FunctionFactory::CaseInsensitive);91}
92
93}
94