Merge pull request #44662 from evillique/ulid

Add generateULID function
This commit is contained in:
Nikolay Degterinsky 2023-02-16 11:21:23 +01:00 committed by GitHub
commit e61947bf47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 181 additions and 0 deletions

3
.gitmodules vendored
View File

@ -296,6 +296,9 @@
[submodule "contrib/libdivide"]
path = contrib/libdivide
url = https://github.com/ridiculousfish/libdivide
[submodule "contrib/ulid-c"]
path = contrib/ulid-c
url = https://github.com/ClickHouse/ulid-c.git
[submodule "contrib/aws-crt-cpp"]
path = contrib/aws-crt-cpp
url = https://github.com/ClickHouse/aws-crt-cpp

View File

@ -191,6 +191,8 @@ add_contrib (xxHash-cmake xxHash)
add_contrib (google-benchmark-cmake google-benchmark)
add_contrib (ulid-c-cmake ulid-c)
# Put all targets defined here and in subdirectories under "contrib/<immediate-subdir>" folders in GUI-based IDEs.
# Some of third-party projects may override CMAKE_FOLDER or FOLDER property of their targets, so they would not appear
# in "contrib/..." as originally planned, so we workaround this by fixing FOLDER properties of all targets manually,

1
contrib/ulid-c vendored Submodule

@ -0,0 +1 @@
Subproject commit c433b6783cf918b8f996dacd014cb2b68c7de419

View File

@ -0,0 +1,16 @@
option (ENABLE_ULID "Enable ulid" ${ENABLE_LIBRARIES})
if (NOT ENABLE_ULID)
message(STATUS "Not using ulid")
return()
endif()
set (LIBRARY_DIR "${ClickHouse_SOURCE_DIR}/contrib/ulid-c")
set (SRCS
"${LIBRARY_DIR}/src/ulid.c"
)
add_library(_ulid ${SRCS})
target_include_directories(_ulid SYSTEM PUBLIC "${LIBRARY_DIR}/include")
add_library(ch_contrib::ulid ALIAS _ulid)

View File

@ -0,0 +1,53 @@
---
slug: /en/sql-reference/functions/ulid-functions
sidebar_position: 54
sidebar_label: ULID
---
# Functions for Working with ULID
## generateULID
Generates the [ULID](https://github.com/ulid/spec).
**Syntax**
``` sql
generateULID([x])
```
**Arguments**
- `x` — [Expression](../../sql-reference/syntax.md#syntax-expressions) resulting in any of the [supported data types](../../sql-reference/data-types/index.md#data_types). The resulting value is discarded, but the expression itself if used for bypassing [common subexpression elimination](../../sql-reference/functions/index.md#common-subexpression-elimination) if the function is called multiple times in one query. Optional parameter.
**Returned value**
The [FixedString](../data-types/fixedstring.md) type value.
**Usage example**
``` sql
SELECT generateULID()
```
``` text
┌─generateULID()─────────────┐
│ 01GNB2S2FGN2P93QPXDNB4EN2R │
└────────────────────────────┘
```
**Usage example if it is needed to generate multiple values in one row**
```sql
SELECT generateULID(1), generateULID(2)
```
``` text
┌─generateULID(1)────────────┬─generateULID(2)────────────┐
│ 01GNB2SGG4RHKVNT9ZGA4FFMNP │ 01GNB2SGG4V0HMQVH4VBVPSSRB │
└────────────────────────────┴────────────────────────────┘
```
## See Also
- [UUID](../../sql-reference/functions/uuid-functions.md)

View File

@ -550,6 +550,10 @@ if (ENABLE_NLP)
dbms_target_link_libraries (PUBLIC ch_contrib::nlp_data)
endif()
if (TARGET ch_contrib::ulid)
dbms_target_link_libraries (PUBLIC ch_contrib::ulid)
endif()
if (TARGET ch_contrib::bzip2)
target_link_libraries (clickhouse_common_io PRIVATE ch_contrib::bzip2)
endif()

View File

@ -56,3 +56,4 @@
#cmakedefine01 USE_BLAKE3
#cmakedefine01 USE_SKIM
#cmakedefine01 USE_OPENSSL_INTREE
#cmakedefine01 USE_ULID

View File

@ -0,0 +1,94 @@
#include "config.h"
#if USE_ULID
#include <Columns/ColumnFixedString.h>
#include <DataTypes/DataTypeFixedString.h>
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionHelpers.h>
#include <Functions/IFunction.h>
#include <Interpreters/Context.h>
#include <ulid.h>
namespace DB
{
namespace ErrorCodes
{
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
}
class FunctionGenerateULID : public IFunction
{
public:
static constexpr size_t ULID_LENGTH = 26;
static constexpr auto name = "generateULID";
static FunctionPtr create(ContextPtr /*context*/)
{
return std::make_shared<FunctionGenerateULID>();
}
String getName() const override { return name; }
size_t getNumberOfArguments() const override { return 0; }
bool isVariadic() const override { return true; }
bool isDeterministic() const override { return false; }
bool isDeterministicInScopeOfQuery() const override { return false; }
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() > 1)
throw Exception(
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"Number of arguments for function {} doesn't match: passed {}, should be 0 or 1.",
getName(), arguments.size());
return std::make_shared<DataTypeFixedString>(ULID_LENGTH);
}
bool useDefaultImplementationForConstants() const override { return true; }
ColumnPtr executeImpl(const ColumnsWithTypeAndName & /*arguments*/, const DataTypePtr &, size_t input_rows_count) const override
{
auto col_res = ColumnFixedString::create(ULID_LENGTH);
auto & vec_res = col_res->getChars();
vec_res.resize(input_rows_count * ULID_LENGTH);
ulid_generator generator;
ulid_generator_init(&generator, 0);
for (size_t offset = 0, size = vec_res.size(); offset < size; offset += ULID_LENGTH)
ulid_generate(&generator, reinterpret_cast<char *>(&vec_res[offset]));
return col_res;
}
};
REGISTER_FUNCTION(GenerateULID)
{
factory.registerFunction<FunctionGenerateULID>(
{
R"(
Generates a Universally Unique Lexicographically Sortable Identifier (ULID).
This function takes an optional argument, the value of which is discarded to generate different values in case the function is called multiple times.
The function returns a value of type FixedString(26).
)",
Documentation::Examples{
{"ulid", "SELECT generateULID()"},
{"multiple", "SELECT generateULID(1), generateULID(2)"}},
Documentation::Categories{"ULID"}
},
FunctionFactory::CaseSensitive);
}
}
#endif

View File

@ -94,6 +94,9 @@ endif()
if (ENABLE_NLP)
set(USE_NLP 1)
endif()
if (TARGET ch_contrib::ulid)
set(USE_ULID 1)
endif()
if (TARGET ch_contrib::llvm)
set(USE_EMBEDDED_COMPILER 1)
endif()

View File

@ -0,0 +1 @@
1 FixedString(26)

View File

@ -0,0 +1,3 @@
-- Tags: no-fasttest
SELECT generateULID(1) != generateULID(2), toTypeName(generateULID());