ClickHouse
94 строки · 2.8 Кб
1#include "config.h"
2
3#if USE_ULID
4
5#include <Columns/ColumnFixedString.h>
6#include <DataTypes/DataTypeFixedString.h>
7#include <Functions/FunctionFactory.h>
8#include <Functions/FunctionHelpers.h>
9#include <Functions/IFunction.h>
10#include <Interpreters/Context.h>
11
12#include <ulid.h>
13
14
15namespace DB
16{
17
18namespace ErrorCodes
19{
20extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
21}
22
23class FunctionGenerateULID : public IFunction
24{
25public:
26static constexpr size_t ULID_LENGTH = 26;
27
28static constexpr auto name = "generateULID";
29
30static FunctionPtr create(ContextPtr /*context*/)
31{
32return std::make_shared<FunctionGenerateULID>();
33}
34
35String getName() const override { return name; }
36
37size_t getNumberOfArguments() const override { return 0; }
38
39bool isVariadic() const override { return true; }
40bool isDeterministic() const override { return false; }
41bool isDeterministicInScopeOfQuery() const override { return false; }
42bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
43
44DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
45{
46if (arguments.size() > 1)
47throw Exception(
48ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
49"Number of arguments for function {} doesn't match: passed {}, should be 0 or 1.",
50getName(), arguments.size());
51
52return std::make_shared<DataTypeFixedString>(ULID_LENGTH);
53}
54
55bool useDefaultImplementationForConstants() const override { return true; }
56
57ColumnPtr executeImpl(const ColumnsWithTypeAndName & /*arguments*/, const DataTypePtr &, size_t input_rows_count) const override
58{
59auto col_res = ColumnFixedString::create(ULID_LENGTH);
60auto & vec_res = col_res->getChars();
61
62vec_res.resize(input_rows_count * ULID_LENGTH);
63
64ulid_generator generator;
65ulid_generator_init(&generator, 0);
66
67for (size_t offset = 0, size = vec_res.size(); offset < size; offset += ULID_LENGTH)
68ulid_generate(&generator, reinterpret_cast<char *>(&vec_res[offset]));
69
70return col_res;
71}
72};
73
74
75REGISTER_FUNCTION(GenerateULID)
76{
77factory.registerFunction<FunctionGenerateULID>(FunctionDocumentation
78{
79.description=R"(
80Generates a Universally Unique Lexicographically Sortable Identifier (ULID).
81This function takes an optional argument, the value of which is discarded to generate different values in case the function is called multiple times.
82The function returns a value of type FixedString(26).
83)",
84.examples{
85{"ulid", "SELECT generateULID()", ""},
86{"multiple", "SELECT generateULID(1), generateULID(2)", ""}},
87.categories{"ULID"}
88},
89FunctionFactory::CaseSensitive);
90}
91
92}
93
94#endif
95