diff --git a/dbms/src/Functions/h3IsValid.cpp b/dbms/src/Functions/h3IsValid.cpp new file mode 100644 index 00000000000..8d0430caddb --- /dev/null +++ b/dbms/src/Functions/h3IsValid.cpp @@ -0,0 +1,77 @@ +#include "config_functions.h" +#if USE_H3 +# include +# include +# include +# include +# include +# include + + +extern "C" { +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdocumentation" +# endif + +# include + +# ifdef __clang__ +# pragma clang diagnostic pop +# endif +} + +namespace DB +{ +class FunctionH3IsValid : public IFunction +{ +public: + static constexpr auto name = "h3IsValid"; + + static FunctionPtr create(const Context &) { return std::make_shared(); } + + std::string getName() const override { return name; } + + size_t getNumberOfArguments() const override { return 1; } + bool useDefaultImplementationForConstants() const override { return true; } + + DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override + { + auto arg = arguments[0].get(); + if (!WhichDataType(arg).isUInt64()) + throw Exception( + "Illegal type " + arg->getName() + " of argument " + std::to_string(1) + " of function " + getName() + ". Must be UInt64", + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + return std::make_shared(); + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override + { + const auto col_hindex = block.getByPosition(arguments[0]).column.get(); + + auto dst = ColumnVector::create(); + auto & dst_data = dst->getData(); + dst_data.resize(input_rows_count); + + for (const auto row : ext::range(0, input_rows_count)) + { + const UInt64 hindex = col_hindex->getUInt(row); + + UInt8 is_valid = H3_EXPORT(h3IsValid)(hindex) == 0 ? 0 : 1; + + dst_data[row] = is_valid; + } + + block.getByPosition(result).column = std::move(dst); + } +}; + + +void registerFunctionH3IsValid(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} +#endif diff --git a/dbms/src/Functions/registerFunctionsGeo.cpp b/dbms/src/Functions/registerFunctionsGeo.cpp index 092599722e6..a6af3471233 100644 --- a/dbms/src/Functions/registerFunctionsGeo.cpp +++ b/dbms/src/Functions/registerFunctionsGeo.cpp @@ -15,6 +15,7 @@ void registerFunctionGeohashesInBox(FunctionFactory & factory); #if USE_H3 void registerFunctionGeoToH3(FunctionFactory &); void registerFunctionH3GetResolution(FunctionFactory &); +void registerFunctionH3IsValid(FunctionFactory &); #endif void registerFunctionsGeo(FunctionFactory & factory) @@ -29,6 +30,7 @@ void registerFunctionsGeo(FunctionFactory & factory) #if USE_H3 registerFunctionGeoToH3(factory); registerFunctionH3GetResolution(factory); + registerFunctionH3IsValid(factory); #endif } diff --git a/dbms/tests/queries/0_stateless/01041_h3_is_valid.reference b/dbms/tests/queries/0_stateless/01041_h3_is_valid.reference new file mode 100644 index 00000000000..d9ff83f1949 --- /dev/null +++ b/dbms/tests/queries/0_stateless/01041_h3_is_valid.reference @@ -0,0 +1,4 @@ +1 +1 +0 +0 diff --git a/dbms/tests/queries/0_stateless/01041_h3_is_valid.sql b/dbms/tests/queries/0_stateless/01041_h3_is_valid.sql new file mode 100644 index 00000000000..05885561844 --- /dev/null +++ b/dbms/tests/queries/0_stateless/01041_h3_is_valid.sql @@ -0,0 +1,4 @@ +SELECT h3IsValid(581276613233082367); +SELECT h3IsValid(621807531097128959); +SELECT h3IsValid(Cast(0, 'UInt64')); +SELECT h3IsValid(100000000000000000);