#include #include #include namespace DB { namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } #define DECLARE_SEVERAL_IMPLEMENTATIONS(...) \ DECLARE_DEFAULT_CODE (__VA_ARGS__) \ DECLARE_AVX2_SPECIFIC_CODE(__VA_ARGS__) DECLARE_SEVERAL_IMPLEMENTATIONS( class FunctionGenerateUUIDv4 : public IFunction { public: static constexpr auto name = "generateUUIDv4"; String getName() const override { return name; } size_t getNumberOfArguments() const override { return 0; } bool isDeterministicInScopeOfQuery() const override { return false; } bool useDefaultImplementationForNulls() const override { return false; } bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; } bool isVariadic() const override { return true; } 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(); } bool isDeterministic() const override { return false; } ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr &, size_t input_rows_count) const override { auto col_res = ColumnVector::create(); typename ColumnVector::Container & vec_to = col_res->getData(); size_t size = input_rows_count; vec_to.resize(size); /// RandImpl is target-dependent and is not the same in different TargetSpecific namespaces. RandImpl::execute(reinterpret_cast(vec_to.data()), vec_to.size() * sizeof(UUID)); for (UUID & uuid : vec_to) { /// https://tools.ietf.org/html/rfc4122#section-4.4 UUIDHelpers::getUUIDHigh(uuid) = (UUIDHelpers::getUUIDHigh(uuid) & 0xffffffffffff0fffull) | 0x0000000000004000ull; UUIDHelpers::getUUIDLow(uuid) = (UUIDHelpers::getUUIDLow(uuid) & 0x3fffffffffffffffull) | 0x8000000000000000ull; } return col_res; } }; ) // DECLARE_SEVERAL_IMPLEMENTATIONS #undef DECLARE_SEVERAL_IMPLEMENTATIONS class FunctionGenerateUUIDv4 : public TargetSpecific::Default::FunctionGenerateUUIDv4 { public: explicit FunctionGenerateUUIDv4(ContextPtr context) : selector(context) { selector.registerImplementation(); #if USE_MULTITARGET_CODE selector.registerImplementation(); #endif } ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override { return selector.selectAndExecute(arguments, result_type, input_rows_count); } static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } private: ImplementationSelector selector; }; REGISTER_FUNCTION(GenerateUUIDv4) { factory.registerFunction(); } }