Merge pull request #49300 from ClickHouse/rs/functdocs

Introduce more fields for in-source function documentation
This commit is contained in:
Robert Schulze 2023-05-12 11:36:04 +02:00 committed by GitHub
commit 922420420c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 629 additions and 667 deletions

View File

@ -1,30 +0,0 @@
#include <Common/Documentation.h>
namespace DB
{
std::string Documentation::examplesAsString() const
{
std::string res;
for (const auto & [example_name, example_query] : examples)
{
res += example_name + ":\n\n";
res += "```sql\n";
res += example_query + "\n";
res += "```\n";
}
return res;
}
std::string Documentation::categoriesAsString() const
{
if (categories.empty())
return "";
std::string res = categories[0];
for (size_t i = 1; i < categories.size(); ++i)
res += ", " + categories[i];
return res;
}
}

View File

@ -0,0 +1,44 @@
#include <Common/FunctionDocumentation.h>
namespace DB
{
std::string FunctionDocumentation::argumentsAsString() const
{
std::string res;
for (const auto & [name, desc] : arguments)
{
res += "- " + name + ":" + desc + "\n";
}
return res;
}
std::string FunctionDocumentation::examplesAsString() const
{
std::string res;
for (const auto & [name, query, result] : examples)
{
res += name + ":\n\n";
res += "``` sql\n";
res += query + "\n";
res += "```\n\n";
res += "``` text\n";
res += result + "\n";
res += "```\n";
}
return res;
}
std::string FunctionDocumentation::categoriesAsString() const
{
if (categories.empty())
return "";
auto it = categories.begin();
std::string res = *it;
for (; it != categories.end(); ++it)
res += ", " + *it;
return res;
}
}

View File

@ -1,15 +1,14 @@
#pragma once
#include <set>
#include <string>
#include <vector>
#include <map>
namespace DB
{
/** Embedded reference documentation for high-level server components,
* such as SQL functions, table functions, data types, table engines, etc.
/** Embedded reference documentation for functions.
*
* The advantages of embedded documentation are:
* - it is easy to write and update with code;
@ -34,50 +33,49 @@ namespace DB
* - examples (queries that can be referenced from the text by names);
* - categories - one or a few text strings like {"Mathematical", "Array Processing"};
*
* Only the description is mandatory.
*
* The description should be represented in Markdown (or just plaintext).
* Some extensions for Markdown are added:
* - [example:name] will reference to an example with the corresponding name.
*
* Documentation does not support multiple languages.
* The only available language is English.
*
* TODO: Allow to specify Syntax, Argument(s) and a Returned Value.
* TODO: Organize Examples as a struct of ExampleName, ExampleQuery and ExampleResult.
*/
struct Documentation
struct FunctionDocumentation
{
using Description = std::string;
using Syntax = std::string;
using Argument = std::string;
struct Argument
{
std::string name;
std::string description;
};
using Arguments = std::vector<Argument>;
using ReturnedValue = std::string;
using ExampleName = std::string;
using ExampleQuery = std::string;
using Examples = std::map<ExampleName, ExampleQuery>;
struct Example
{
std::string name;
std::string query;
std::string result;
};
using Examples = std::vector<Example>;
using Category = std::string;
using Categories = std::vector<Category>;
using Categories = std::set<Category>;
using Related = std::string;
Description description;
Examples examples;
Categories categories;
Documentation(Description description_) : description(std::move(description_)) {} /// NOLINT
Documentation(Description description_, Examples examples_) : description(std::move(description_)), examples(std::move(examples_)) {}
Documentation(Description description_, Examples examples_, Categories categories_)
: description(std::move(description_)), examples(std::move(examples_)), categories(std::move(categories_)) {}
/// TODO: Please remove this constructor. Documentation should always be non-empty.
Documentation() = default;
Description description; /// E.g. "Returns the position (in bytes, starting at 1) of a substring needle in a string haystack."
Syntax syntax; /// E.g. "position(haystack, needle)"
Arguments arguments; /// E.g. ["haystack — String in which the search is performed. String.", "needle — Substring to be searched. String."]
ReturnedValue returned_value; /// E.g. "Starting position in bytes and counting from 1, if the substring was found."
Examples examples; ///
Categories categories; /// E.g. {"String Search"}
std::string argumentsAsString() const;
std::string examplesAsString() const;
std::string categoriesAsString() const;
};

View File

@ -29,7 +29,7 @@ const String & getFunctionCanonicalNameIfAny(const String & name)
void FunctionFactory::registerFunction(
const std::string & name,
FunctionCreator creator,
Documentation doc,
FunctionDocumentation doc,
CaseSensitiveness case_sensitiveness)
{
if (!functions.emplace(name, FunctionFactoryData{creator, doc}).second)
@ -141,7 +141,7 @@ FunctionFactory & FunctionFactory::instance()
return ret;
}
Documentation FunctionFactory::getDocumentation(const std::string & name) const
FunctionDocumentation FunctionFactory::getDocumentation(const std::string & name) const
{
auto it = functions.find(name);
if (it == functions.end())

View File

@ -3,7 +3,7 @@
#include <Interpreters/Context_fwd.h>
#include <Common/register_objects.h>
#include <Common/IFactoryWithAliases.h>
#include <Common/Documentation.h>
#include <Common/FunctionDocumentation.h>
#include <Functions/IFunction.h>
#include <Functions/IFunctionAdaptors.h>
@ -17,7 +17,7 @@ namespace DB
{
using FunctionCreator = std::function<FunctionOverloadResolverPtr(ContextPtr)>;
using FunctionFactoryData = std::pair<FunctionCreator, Documentation>;
using FunctionFactoryData = std::pair<FunctionCreator, FunctionDocumentation>;
/** Creates function by name.
* Function could use for initialization (take ownership of shared_ptr, for example)
@ -29,13 +29,13 @@ public:
static FunctionFactory & instance();
template <typename Function>
void registerFunction(Documentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive)
void registerFunction(FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive)
{
registerFunction<Function>(Function::name, std::move(doc), case_sensitiveness);
}
template <typename Function>
void registerFunction(const std::string & name, Documentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive)
void registerFunction(const std::string & name, FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive)
{
if constexpr (std::is_base_of_v<IFunction, Function>)
registerFunction(name, &adaptFunctionToOverloadResolver<Function>, std::move(doc), case_sensitiveness);
@ -63,10 +63,10 @@ public:
void registerFunction(
const std::string & name,
FunctionCreator creator,
Documentation doc = {},
FunctionDocumentation doc = {},
CaseSensitiveness case_sensitiveness = CaseSensitive);
Documentation getDocumentation(const std::string & name) const;
FunctionDocumentation getDocumentation(const std::string & name) const;
private:
using Functions = std::unordered_map<std::string, Value>;

View File

@ -8,14 +8,14 @@ namespace DB
REGISTER_FUNCTION(ToDecimalString)
{
factory.registerFunction<FunctionToDecimalString>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns string representation of a number. First argument is the number of any numeric type,
second argument is the desired number of digits in fractional part. Returns String.
)",
Documentation::Examples{{"toDecimalString", "SELECT toDecimalString(2.1456,2)"}},
Documentation::Categories{"String"}
.examples{{"toDecimalString", "SELECT toDecimalString(2.1456,2)", ""}},
.categories{"String"}
}, FunctionFactory::CaseInsensitive);
}

View File

@ -169,17 +169,17 @@ public:
REGISTER_FUNCTION(ULIDStringToDateTime)
{
factory.registerFunction<FunctionULIDStringToDateTime>(
factory.registerFunction<FunctionULIDStringToDateTime>(FunctionDocumentation
{
R"(
.description=R"(
This function extracts the timestamp from a ULID and returns it as a DateTime64(3) typed value.
The function expects the ULID to be provided as the first argument, which can be either a String or a FixedString(26) data type.
An optional second argument can be passed to specify a timezone for the timestamp.
)",
Documentation::Examples{
{"ulid", "SELECT ULIDStringToDateTime(generateULID())"},
{"timezone", "SELECT ULIDStringToDateTime(generateULID(), 'Asia/Istanbul')"}},
Documentation::Categories{"ULID"}
.examples{
{"ulid", "SELECT ULIDStringToDateTime(generateULID())", ""},
{"timezone", "SELECT ULIDStringToDateTime(generateULID(), 'Asia/Istanbul')", ""}},
.categories{"ULID"}
},
FunctionFactory::CaseSensitive);
}

View File

@ -47,69 +47,69 @@ Returned value: value of the dictionary attribute parsed in the attributes da
Throws an exception if cannot parse the value of the attribute or the value does not match the attribute data type.
)" };
factory.registerFunction<FunctionDictGetNoType<DictionaryGetFunctionType::get>>(Documentation{ fmt::format(dict_get_description, "attributes data type") });
factory.registerFunction<FunctionDictGetNoType<DictionaryGetFunctionType::getOrDefault>>(Documentation{ fmt::format(dict_get_or_default_description, "attributes data type") });
factory.registerFunction<FunctionDictGetOrNull>(Documentation{ dict_get_or_null_description });
factory.registerFunction<FunctionDictGetNoType<DictionaryGetFunctionType::get>>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "attributes data type") });
factory.registerFunction<FunctionDictGetNoType<DictionaryGetFunctionType::getOrDefault>>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "attributes data type") });
factory.registerFunction<FunctionDictGetOrNull>(FunctionDocumentation{ .description=dict_get_or_null_description });
factory.registerFunction<FunctionDictGetUInt8>(Documentation{ fmt::format(dict_get_description, "UInt8") });
factory.registerFunction<FunctionDictGetUInt16>(Documentation{ fmt::format(dict_get_description, "UInt16") });
factory.registerFunction<FunctionDictGetUInt32>(Documentation{ fmt::format(dict_get_description, "UInt32") });
factory.registerFunction<FunctionDictGetUInt64>(Documentation{ fmt::format(dict_get_description, "UInt64") });
factory.registerFunction<FunctionDictGetInt8>(Documentation{ fmt::format(dict_get_description, "Int8") });
factory.registerFunction<FunctionDictGetInt16>(Documentation{ fmt::format(dict_get_description, "Int16") });
factory.registerFunction<FunctionDictGetInt32>(Documentation{ fmt::format(dict_get_description, "Int32") });
factory.registerFunction<FunctionDictGetInt64>(Documentation{ fmt::format(dict_get_description, "Int64") });
factory.registerFunction<FunctionDictGetFloat32>(Documentation{ fmt::format(dict_get_description, "Float32") });
factory.registerFunction<FunctionDictGetFloat64>(Documentation{ fmt::format(dict_get_description, "Float64") });
factory.registerFunction<FunctionDictGetDate>(Documentation{ fmt::format(dict_get_description, "Date") });
factory.registerFunction<FunctionDictGetDateTime>(Documentation{ fmt::format(dict_get_description, "DateTime") });
factory.registerFunction<FunctionDictGetUUID>(Documentation{ fmt::format(dict_get_description, "UUID") });
factory.registerFunction<FunctionDictGetIPv4>(Documentation{ fmt::format(dict_get_description, "IPv4") });
factory.registerFunction<FunctionDictGetIPv6>(Documentation{ fmt::format(dict_get_description, "IPv6") });
factory.registerFunction<FunctionDictGetString>(Documentation{ fmt::format(dict_get_description, "String") });
factory.registerFunction<FunctionDictGetUInt8>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "UInt8") });
factory.registerFunction<FunctionDictGetUInt16>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "UInt16") });
factory.registerFunction<FunctionDictGetUInt32>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "UInt32") });
factory.registerFunction<FunctionDictGetUInt64>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "UInt64") });
factory.registerFunction<FunctionDictGetInt8>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Int8") });
factory.registerFunction<FunctionDictGetInt16>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Int16") });
factory.registerFunction<FunctionDictGetInt32>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Int32") });
factory.registerFunction<FunctionDictGetInt64>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Int64") });
factory.registerFunction<FunctionDictGetFloat32>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Float32") });
factory.registerFunction<FunctionDictGetFloat64>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Float64") });
factory.registerFunction<FunctionDictGetDate>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "Date") });
factory.registerFunction<FunctionDictGetDateTime>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "DateTime") });
factory.registerFunction<FunctionDictGetUUID>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "UUID") });
factory.registerFunction<FunctionDictGetIPv4>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "IPv4") });
factory.registerFunction<FunctionDictGetIPv6>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "IPv6") });
factory.registerFunction<FunctionDictGetString>(FunctionDocumentation{ .description=fmt::format(dict_get_description, "String") });
factory.registerFunction<FunctionDictGetUInt8OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "UInt8") });
factory.registerFunction<FunctionDictGetUInt16OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "UInt16") });
factory.registerFunction<FunctionDictGetUInt32OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "UInt32") });
factory.registerFunction<FunctionDictGetUInt64OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "UInt64") });
factory.registerFunction<FunctionDictGetInt8OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Int8") });
factory.registerFunction<FunctionDictGetInt16OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Int16") });
factory.registerFunction<FunctionDictGetInt32OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Int32") });
factory.registerFunction<FunctionDictGetInt64OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Int64") });
factory.registerFunction<FunctionDictGetFloat32OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Float32") });
factory.registerFunction<FunctionDictGetFloat64OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Float64") });
factory.registerFunction<FunctionDictGetDateOrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "Date") });
factory.registerFunction<FunctionDictGetDateTimeOrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "DateTime") });
factory.registerFunction<FunctionDictGetUUIDOrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "UUID") });
factory.registerFunction<FunctionDictGetIPv4OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "IPv4") });
factory.registerFunction<FunctionDictGetIPv6OrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "IPv6") });
factory.registerFunction<FunctionDictGetStringOrDefault>(Documentation{ fmt::format(dict_get_or_default_description, "String") });
factory.registerFunction<FunctionDictGetUInt8OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "UInt8") });
factory.registerFunction<FunctionDictGetUInt16OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "UInt16") });
factory.registerFunction<FunctionDictGetUInt32OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "UInt32") });
factory.registerFunction<FunctionDictGetUInt64OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "UInt64") });
factory.registerFunction<FunctionDictGetInt8OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Int8") });
factory.registerFunction<FunctionDictGetInt16OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Int16") });
factory.registerFunction<FunctionDictGetInt32OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Int32") });
factory.registerFunction<FunctionDictGetInt64OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Int64") });
factory.registerFunction<FunctionDictGetFloat32OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Float32") });
factory.registerFunction<FunctionDictGetFloat64OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Float64") });
factory.registerFunction<FunctionDictGetDateOrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "Date") });
factory.registerFunction<FunctionDictGetDateTimeOrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "DateTime") });
factory.registerFunction<FunctionDictGetUUIDOrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "UUID") });
factory.registerFunction<FunctionDictGetIPv4OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "IPv4") });
factory.registerFunction<FunctionDictGetIPv6OrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "IPv6") });
factory.registerFunction<FunctionDictGetStringOrDefault>(FunctionDocumentation{ .description=fmt::format(dict_get_or_default_description, "String") });
factory.registerFunction<FunctionDictHas>(Documentation{ R"(
factory.registerFunction<FunctionDictHas>(FunctionDocumentation{ .description=R"(
Checks whether a key is present in a dictionary.
Accepts 2 parameters: name of the dictionary, key value - expression returning dictionary key-type value or tuple-type value - depending on the dictionary configuration.
Returned value: 0 if there is no key, 1 if there is a key, type of UInt8
)"});
factory.registerFunction<FunctionDictGetHierarchy>(Documentation{ R"(
factory.registerFunction<FunctionDictGetHierarchy>(FunctionDocumentation{ .description=R"(
Creates an array, containing all the parents of a key in the hierarchical dictionary.
Accepts 2 parameters: name of the dictionary, key value - expression returning a UInt64-type value.
Returned value: parents for the key, type of Array(UInt64)
)"});
factory.registerFunction<FunctionDictIsIn>(Documentation{ R"(
factory.registerFunction<FunctionDictIsIn>(FunctionDocumentation{ .description=R"(
Checks the ancestor of a key through the whole hierarchical chain in the dictionary.
Accepts 3 parameters: name of the dictionary, key to be checked - expression returning a UInt64-type value, alleged ancestor of the key - expression returning a UInt64-type.
Returned value: 0 if key is not a child of the ancestor, 1 if key is a child of the ancestor or if key is the ancestor, type of UInt8
)"});
factory.registerFunction<FunctionDictGetChildrenOverloadResolver>(Documentation{ R"(
factory.registerFunction<FunctionDictGetChildrenOverloadResolver>(FunctionDocumentation{ .description=R"(
Returns first-level children as an array of indexes. It is the inverse transformation for dictGetHierarchy.
Accepts 2 parameters: name of the dictionary, key value - expression returning a UInt64-type value.
Returned value: first-level descendants for the key, type of Array(UInt64)
)"});
factory.registerFunction<FunctionDictGetDescendantsOverloadResolver>(Documentation{ R"(
factory.registerFunction<FunctionDictGetDescendantsOverloadResolver>(FunctionDocumentation{ .description=R"(
Returns all descendants as if dictGetChildren function was applied level times recursively.
Accepts 3 parameters: name of the dictionary, key value - expression returning a UInt64-type value, level hierarchy level - If level = 0 returns all descendants to the end - UInt8
Returned value: descendants for the key, type of Array(UInt64)

View File

@ -15,15 +15,15 @@ REGISTER_FUNCTION(Hashing)
factory.registerFunction<FunctionSipHash64Keyed>();
factory.registerFunction<FunctionSipHash128>();
factory.registerFunction<FunctionSipHash128Keyed>();
factory.registerFunction<FunctionSipHash128Reference>({
"Like [sipHash128](#hash_functions-siphash128) but implements the 128-bit algorithm from the original authors of SipHash.",
Documentation::Examples{{"hash", "SELECT hex(sipHash128Reference('foo', '\\x01', 3))"}},
Documentation::Categories{"Hash"}
factory.registerFunction<FunctionSipHash128Reference>(FunctionDocumentation{
.description="Like [sipHash128](#hash_functions-siphash128) but implements the 128-bit algorithm from the original authors of SipHash.",
.examples{{"hash", "SELECT hex(sipHash128Reference('foo', '\\x01', 3))", ""}},
.categories{"Hash"}
});
factory.registerFunction<FunctionSipHash128ReferenceKeyed>({
"Same as [sipHash128Reference](#hash_functions-siphash128reference) but additionally takes an explicit key argument instead of using a fixed key.",
Documentation::Examples{{"hash", "SELECT hex(sipHash128ReferenceKeyed((506097522914230528, 1084818905618843912),'foo', '\\x01', 3));"}},
Documentation::Categories{"Hash"}
factory.registerFunction<FunctionSipHash128ReferenceKeyed>(FunctionDocumentation{
.description="Same as [sipHash128Reference](#hash_functions-siphash128reference) but additionally takes an explicit key argument instead of using a fixed key.",
.examples{{"hash", "SELECT hex(sipHash128ReferenceKeyed((506097522914230528, 1084818905618843912),'foo', '\\x01', 3));", ""}},
.categories{"Hash"}
});
factory.registerFunction<FunctionCityHash64>();
factory.registerFunction<FunctionFarmFingerprint64>();
@ -37,10 +37,10 @@ REGISTER_FUNCTION(Hashing)
factory.registerFunction<FunctionXxHash32>();
factory.registerFunction<FunctionXxHash64>();
factory.registerFunction<FunctionXXH3>(
{
"Calculates value of XXH3 64-bit hash function. Refer to https://github.com/Cyan4973/xxHash for detailed documentation.",
Documentation::Examples{{"hash", "SELECT xxh3('ClickHouse')"}},
Documentation::Categories{"Hash"}
FunctionDocumentation{
.description="Calculates value of XXH3 64-bit hash function. Refer to https://github.com/Cyan4973/xxHash for detailed documentation.",
.examples{{"hash", "SELECT xxh3('ClickHouse')", ""}},
.categories{"Hash"}
},
FunctionFactory::CaseSensitive);
@ -48,16 +48,16 @@ REGISTER_FUNCTION(Hashing)
factory.registerFunction<FunctionBLAKE3>(
{
R"(
FunctionDocumentation{
.description=R"(
Calculates BLAKE3 hash string and returns the resulting set of bytes as FixedString.
This cryptographic hash-function is integrated into ClickHouse with BLAKE3 Rust library.
The function is rather fast and shows approximately two times faster performance compared to SHA-2, while generating hashes of the same length as SHA-256.
It returns a BLAKE3 hash as a byte array with type FixedString(32).
)",
Documentation::Examples{
{"hash", "SELECT hex(BLAKE3('ABC'))"}},
Documentation::Categories{"Hash"}
.examples{
{"hash", "SELECT hex(BLAKE3('ABC'))", ""}},
.categories{"Hash"}
},
FunctionFactory::CaseSensitive);
}

View File

@ -100,8 +100,8 @@ namespace
REGISTER_FUNCTION(JSONArrayLength)
{
factory.registerFunction<FunctionJSONArrayLength>(Documentation{
"Returns the number of elements in the outermost JSON array. The function returns NULL if input JSON string is invalid."});
factory.registerFunction<FunctionJSONArrayLength>(FunctionDocumentation{
.description="Returns the number of elements in the outermost JSON array. The function returns NULL if input JSON string is invalid."});
/// For Spark compatibility.
factory.registerAlias("JSON_ARRAY_LENGTH", "JSONArrayLength", FunctionFactory::CaseInsensitive);

View File

@ -44,32 +44,32 @@ using FunctionCutToFirstSignificantSubdomainWithWWWRFC = FunctionStringToString<
REGISTER_FUNCTION(CutToFirstSignificantSubdomain)
{
factory.registerFunction<FunctionCutToFirstSignificantSubdomain>(
{
R"(Returns the part of the domain that includes top-level subdomains up to the "first significant subdomain" (see documentation of the `firstSignificantSubdomain`).)",
Documentation::Examples{
{"cutToFirstSignificantSubdomain1", "SELECT cutToFirstSignificantSubdomain('https://news.clickhouse.com.tr/')"},
{"cutToFirstSignificantSubdomain2", "SELECT cutToFirstSignificantSubdomain('www.tr')"},
{"cutToFirstSignificantSubdomain3", "SELECT cutToFirstSignificantSubdomain('tr')"},
FunctionDocumentation{
.description=R"(Returns the part of the domain that includes top-level subdomains up to the "first significant subdomain" (see documentation of the `firstSignificantSubdomain`).)",
.examples{
{"cutToFirstSignificantSubdomain1", "SELECT cutToFirstSignificantSubdomain('https://news.clickhouse.com.tr/')", ""},
{"cutToFirstSignificantSubdomain2", "SELECT cutToFirstSignificantSubdomain('www.tr')", ""},
{"cutToFirstSignificantSubdomain3", "SELECT cutToFirstSignificantSubdomain('tr')", ""},
},
Documentation::Categories{"URL"}
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainWithWWW>(
{
R"(Returns the part of the domain that includes top-level subdomains up to the "first significant subdomain", without stripping "www".)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Returns the part of the domain that includes top-level subdomains up to the "first significant subdomain", without stripping "www".)",
.examples{},
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainRFC>(
{
R"(Similar to `cutToFirstSignificantSubdomain` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Similar to `cutToFirstSignificantSubdomain` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
.examples{},
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainWithWWWRFC>(
{
R"(Similar to `cutToFirstSignificantSubdomainWithWWW` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Similar to `cutToFirstSignificantSubdomainWithWWW` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -43,39 +43,39 @@ using FunctionCutToFirstSignificantSubdomainCustomWithWWWRFC = FunctionCutToFirs
REGISTER_FUNCTION(CutToFirstSignificantSubdomainCustom)
{
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustom>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns the part of the domain that includes top-level subdomains up to the first significant subdomain. Accepts custom TLD list name.
Can be useful if you need fresh TLD list or you have custom.
)",
Documentation::Examples{
{"cutToFirstSignificantSubdomainCustom", "SELECT cutToFirstSignificantSubdomainCustom('bar.foo.there-is-no-such-domain', 'public_suffix_list');"},
.examples{
{"cutToFirstSignificantSubdomainCustom", "SELECT cutToFirstSignificantSubdomainCustom('bar.foo.there-is-no-such-domain', 'public_suffix_list');", ""},
},
Documentation::Categories{"URL"}
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustomWithWWW>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns the part of the domain that includes top-level subdomains up to the first significant subdomain without stripping `www`.
Accepts custom TLD list name from config.
Can be useful if you need fresh TLD list or you have custom.
)",
Documentation::Examples{{"cutToFirstSignificantSubdomainCustomWithWWW", "SELECT cutToFirstSignificantSubdomainCustomWithWWW('www.foo', 'public_suffix_list')"}},
Documentation::Categories{"URL"}
.examples{{"cutToFirstSignificantSubdomainCustomWithWWW", "SELECT cutToFirstSignificantSubdomainCustomWithWWW('www.foo', 'public_suffix_list')", ""}},
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustomRFC>(
{
R"(Similar to `cutToFirstSignificantSubdomainCustom` but follows stricter rules according to RFC 3986.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Similar to `cutToFirstSignificantSubdomainCustom` but follows stricter rules according to RFC 3986.)",
.examples{},
.categories{"URL"}
});
factory.registerFunction<FunctionCutToFirstSignificantSubdomainCustomWithWWWRFC>(
{
R"(Similar to `cutToFirstSignificantSubdomainCustomWithWWW` but follows stricter rules according to RFC 3986.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Similar to `cutToFirstSignificantSubdomainCustomWithWWW` but follows stricter rules according to RFC 3986.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -14,23 +14,23 @@ using FunctionDomainRFC = FunctionStringToString<ExtractSubstringImpl<ExtractDom
REGISTER_FUNCTION(Domain)
{
factory.registerFunction<FunctionDomain>(
factory.registerFunction<FunctionDomain>(FunctionDocumentation
{
R"(
.description=R"(
Extracts the hostname from a URL.
The URL can be specified with or without a scheme.
If the argument can't be parsed as URL, the function returns an empty string.
)",
Documentation::Examples{{"domain", "SELECT domain('svn+ssh://some.svn-hosting.com:80/repo/trunk')"}},
Documentation::Categories{"URL"}
.examples{{"domain", "SELECT domain('svn+ssh://some.svn-hosting.com:80/repo/trunk')", ""}},
.categories{"URL"}
});
factory.registerFunction<FunctionDomainRFC>(
factory.registerFunction<FunctionDomainRFC>(FunctionDocumentation
{
R"(Similar to `domain` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
.description=R"(Similar to `domain` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -15,21 +15,21 @@ using FunctionDomainWithoutWWWRFC = FunctionStringToString<ExtractSubstringImpl<
REGISTER_FUNCTION(DomainWithoutWWW)
{
factory.registerFunction<FunctionDomainWithoutWWW>(
{
R"(
FunctionDocumentation{
.description=R"(
Extracts the hostname from a URL, removing the leading "www." if present.
The URL can be specified with or without a scheme.
If the argument can't be parsed as URL, the function returns an empty string.
)",
Documentation::Examples{{"domainWithoutWWW", "SELECT domainWithoutWWW('https://www.clickhouse.com')"}},
Documentation::Categories{"URL"}
.examples{{"domainWithoutWWW", "SELECT domainWithoutWWW('https://www.clickhouse.com')", ""}},
.categories{"URL"}
});
factory.registerFunction<FunctionDomainWithoutWWWRFC>(
{
R"(Similar to `domainWithoutWWW` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Similar to `domainWithoutWWW` but follows stricter rules to be compatible with RFC 3986 and less performant.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -15,8 +15,8 @@ using FunctionFirstSignificantSubdomainRFC = FunctionStringToString<ExtractSubst
REGISTER_FUNCTION(FirstSignificantSubdomain)
{
factory.registerFunction<FunctionFirstSignificantSubdomain>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns the "first significant subdomain".
The first significant subdomain is a second-level domain if it is 'com', 'net', 'org', or 'co'.
@ -26,15 +26,15 @@ For example, firstSignificantSubdomain('https://news.clickhouse.com/') = 'clickh
The list of "insignificant" second-level domains and other implementation details may change in the future.
)",
Documentation::Examples{{"firstSignificantSubdomain", "SELECT firstSignificantSubdomain('https://news.clickhouse.com/')"}},
Documentation::Categories{"URL"}
.examples{{"firstSignificantSubdomain", "SELECT firstSignificantSubdomain('https://news.clickhouse.com/')", ""}},
.categories{"URL"}
});
factory.registerFunction<FunctionFirstSignificantSubdomainRFC>(
{
R"(Returns the "first significant subdomain" according to RFC 1034.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
FunctionDocumentation{
.description=R"(Returns the "first significant subdomain" according to RFC 1034.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -138,17 +138,15 @@ struct FunctionPortRFC : public FunctionPortImpl<true>
REGISTER_FUNCTION(Port)
{
factory.registerFunction<FunctionPort>(
factory.registerFunction<FunctionPort>(FunctionDocumentation
{
R"(Returns the port or `default_port` if there is no port in the URL (or in case of validation error).)",
Documentation::Examples{},
Documentation::Categories{"URL"}
.description=R"(Returns the port or `default_port` if there is no port in the URL (or in case of validation error).)",
.categories{"URL"}
});
factory.registerFunction<FunctionPortRFC>(
factory.registerFunction<FunctionPortRFC>(FunctionDocumentation
{
R"(Similar to `port`, but conforms to RFC 3986.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
.description=R"(Similar to `port`, but conforms to RFC 3986.)",
.categories{"URL"}
});
}

View File

@ -53,22 +53,22 @@ using FunctionTopLevelDomainRFC = FunctionStringToString<ExtractSubstringImpl<Ex
REGISTER_FUNCTION(TopLevelDomain)
{
factory.registerFunction<FunctionTopLevelDomain>(
factory.registerFunction<FunctionTopLevelDomain>(FunctionDocumentation
{
R"(
.description=R"(
Extracts the the top-level domain from a URL.
Returns an empty string if the argument cannot be parsed as a URL or does not contain a top-level domain.
)",
Documentation::Examples{{"topLevelDomain", "SELECT topLevelDomain('svn+ssh://www.some.svn-hosting.com:80/repo/trunk')"}},
Documentation::Categories{"URL"}
.examples{{"topLevelDomain", "SELECT topLevelDomain('svn+ssh://www.some.svn-hosting.com:80/repo/trunk')", ""}},
.categories{"URL"}
});
factory.registerFunction<FunctionTopLevelDomainRFC>(
factory.registerFunction<FunctionTopLevelDomainRFC>(FunctionDocumentation
{
R"(Similar to topLevelDomain, but conforms to RFC 3986.)",
Documentation::Examples{},
Documentation::Categories{"URL"}
.description=R"(Similar to topLevelDomain, but conforms to RFC 3986.)",
.examples{},
.categories{"URL"}
});
}

View File

@ -107,17 +107,17 @@ public:
/// UTC_timestamp for MySQL interface support
REGISTER_FUNCTION(UTCTimestamp)
{
factory.registerFunction<UTCTimestampOverloadResolver>({
R"(
factory.registerFunction<UTCTimestampOverloadResolver>(FunctionDocumentation{
.description=R"(
Returns the current date and time at the moment of query analysis. The function is a constant expression.
Same as `now('UTC')`. Was added only for MySQL support. `now` is preferred.
Example:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT UTCTimestamp();"}},
Documentation::Categories{"Dates and Times"}}, FunctionFactory::CaseInsensitive);
.examples{
{"typical", "SELECT UTCTimestamp();", ""}},
.categories{"Dates and Times"}}, FunctionFactory::CaseInsensitive);
factory.registerAlias("UTC_timestamp", UTCTimestampOverloadResolver::name, FunctionFactory::CaseInsensitive);
}

View File

@ -10,8 +10,7 @@ namespace DB
REGISTER_FUNCTION(UniqTheta)
{
factory.registerFunction<FunctionUniqThetaIntersect>(
{
R"(
FunctionDocumentation{.description = R"(
Two uniqThetaSketch objects to do intersect calculation(set operation ), the result is a new uniqThetaSketch.
A uniqThetaSketch object is to be constructed by aggregation function uniqTheta with -State.
@ -22,14 +21,13 @@ For more information on RoaringBitmap, see: [Theta Sketch Framework](https://dat
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "select finalizeAggregation(uniqThetaIntersect(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));"}},
Documentation::Categories{"uniqTheta"}
.examples{
{"typical", "select finalizeAggregation(uniqThetaIntersect(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));", ""}},
.categories{"uniqTheta"}
});
factory.registerFunction<FunctionUniqThetaUnion>(
{
R"(
FunctionDocumentation{.description = R"(
Two uniqThetaSketch objects to do union calculation(set operation ), the result is a new uniqThetaSketch.
A uniqThetaSketch object is to be constructed by aggregation function uniqTheta with -State.
@ -40,13 +38,12 @@ For more information on RoaringBitmap, see: [Theta Sketch Framework](https://dat
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "select finalizeAggregation(uniqThetaUnion(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));"}},
Documentation::Categories{"uniqTheta"}
.examples{
{"typical", "select finalizeAggregation(uniqThetaUnion(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));", ""}},
.categories{"uniqTheta"}
});
factory.registerFunction<FunctionUniqThetaNot>(
{
R"(
FunctionDocumentation{.description = R"(
Two uniqThetaSketch objects to do a_not_b calculation(set operation ×), the result is a new uniqThetaSketch.
A uniqThetaSketch object is to be constructed by aggregation function uniqTheta with -State.
@ -57,9 +54,9 @@ For more information on RoaringBitmap, see: [Theta Sketch Framework](https://dat
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "select finalizeAggregation(uniqThetaNot(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));"}},
Documentation::Categories{"uniqTheta"}
.examples{
{"typical", "select finalizeAggregation(uniqThetaNot(arrayReduce('uniqThetaState',[1,2]), arrayReduce('uniqThetaState',[2,3,4])));", ""}},
.categories{"uniqTheta"}
});
}

View File

@ -363,101 +363,101 @@ using FunctionMapPartialReverseSort = FunctionMapToArrayAdapter<FunctionArrayPar
REGISTER_FUNCTION(MapMiscellaneous)
{
factory.registerFunction<FunctionMapConcat>(
{
"The same as arrayConcat.",
Documentation::Examples{{"mapConcat", "SELECT mapConcat(map('k1', 'v1'), map('k2', 'v2'))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayConcat.",
.examples{{"mapConcat", "SELECT mapConcat(map('k1', 'v1'), map('k2', 'v2'))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapKeys>(
{
"Returns an array with the keys of map.",
Documentation::Examples{{"mapKeys", "SELECT mapKeys(map('k1', 'v1', 'k2', 'v2'))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="Returns an array with the keys of map.",
.examples{{"mapKeys", "SELECT mapKeys(map('k1', 'v1', 'k2', 'v2'))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapValues>(
{
"Returns an array with the values of map.",
Documentation::Examples{{"mapValues", "SELECT mapValues(map('k1', 'v1', 'k2', 'v2'))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="Returns an array with the values of map.",
.examples{{"mapValues", "SELECT mapValues(map('k1', 'v1', 'k2', 'v2'))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapContains>(
{
"Checks whether the map has the specified key.",
Documentation::Examples{{"mapContains", "SELECT mapContains(map('k1', 'v1', 'k2', 'v2'), 'k1')"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="Checks whether the map has the specified key.",
.examples{{"mapContains", "SELECT mapContains(map('k1', 'v1', 'k2', 'v2'), 'k1')", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapFilter>(
{
"The same as arrayFilter.",
Documentation::Examples{{"mapFilter", "SELECT mapFilter((k, v) -> v > 1, map('k1', 1, 'k2', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayFilter.",
.examples{{"mapFilter", "SELECT mapFilter((k, v) -> v > 1, map('k1', 1, 'k2', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapApply>(
{
"The same as arrayMap.",
Documentation::Examples{{"mapApply", "SELECT mapApply((k, v) -> (k, v * 2), map('k1', 1, 'k2', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayMap.",
.examples{{"mapApply", "SELECT mapApply((k, v) -> (k, v * 2), map('k1', 1, 'k2', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapExists>(
{
"The same as arrayExists.",
Documentation::Examples{{"mapExists", "SELECT mapExists((k, v) -> v = 1, map('k1', 1, 'k2', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayExists.",
.examples{{"mapExists", "SELECT mapExists((k, v) -> v = 1, map('k1', 1, 'k2', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapAll>(
{
"The same as arrayAll.",
Documentation::Examples{{"mapAll", "SELECT mapAll((k, v) -> v = 1, map('k1', 1, 'k2', 2))"}},
Documentation::Categories{"Map"},
factory.registerFunction<FunctionMapAll>(
FunctionDocumentation{
.description="The same as arrayAll.",
.examples{{"mapAll", "SELECT mapAll((k, v) -> v = 1, map('k1', 1, 'k2', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapSort>(
{
"The same as arraySort.",
Documentation::Examples{{"mapSort", "SELECT mapSort((k, v) -> v, map('k1', 3, 'k2', 1, 'k3', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arraySort.",
.examples{{"mapSort", "SELECT mapSort((k, v) -> v, map('k1', 3, 'k2', 1, 'k3', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapReverseSort>(
{
"The same as arrayReverseSort.",
Documentation::Examples{{"mapReverseSort", "SELECT mapReverseSort((k, v) -> v, map('k1', 3, 'k2', 1, 'k3', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayReverseSort.",
.examples{{"mapReverseSort", "SELECT mapReverseSort((k, v) -> v, map('k1', 3, 'k2', 1, 'k3', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapPartialSort>(
{
"The same as arrayReverseSort.",
Documentation::Examples{{"mapPartialSort", "SELECT mapPartialSort((k, v) -> v, 2, map('k1', 3, 'k2', 1, 'k3', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayReverseSort.",
.examples{{"mapPartialSort", "SELECT mapPartialSort((k, v) -> v, 2, map('k1', 3, 'k2', 1, 'k3', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapPartialReverseSort>(
{
"The same as arrayPartialReverseSort.",
Documentation::Examples{{"mapPartialReverseSort", "SELECT mapPartialReverseSort((k, v) -> v, 2, map('k1', 3, 'k2', 1, 'k3', 2))"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="The same as arrayPartialReverseSort.",
.examples{{"mapPartialReverseSort", "SELECT mapPartialReverseSort((k, v) -> v, 2, map('k1', 3, 'k2', 1, 'k3', 2))", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapContainsKeyLike>(
{
"Checks whether map contains key LIKE specified pattern.",
Documentation::Examples{{"mapContainsKeyLike", "SELECT mapContainsKeyLike(map('k1-1', 1, 'k2-1', 2), 'k1%')"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="Checks whether map contains key LIKE specified pattern.",
.examples{{"mapContainsKeyLike", "SELECT mapContainsKeyLike(map('k1-1', 1, 'k2-1', 2), 'k1%')", ""}},
.categories{"Map"},
});
factory.registerFunction<FunctionMapExtractKeyLike>(
{
"Returns a map with elements which key matches the specified pattern.",
Documentation::Examples{{"mapExtractKeyLike", "SELECT mapExtractKeyLike(map('k1-1', 1, 'k2-1', 2), 'k1%')"}},
Documentation::Categories{"Map"},
FunctionDocumentation{
.description="Returns a map with elements which key matches the specified pattern.",
.examples{{"mapExtractKeyLike", "SELECT mapExtractKeyLike(map('k1-1', 1, 'k2-1', 2), 'k1%')", ""}},
.categories{"Map"},
});
}

View File

@ -175,8 +175,8 @@ ColumnPtr FunctionArrayShuffleImpl<Traits>::executeGeneric(const ColumnArray & a
REGISTER_FUNCTION(ArrayShuffle)
{
factory.registerFunction<FunctionArrayShuffleImpl<FunctionArrayShuffleTraits>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns an array of the same size as the original array containing the elements in shuffled order.
Elements are being reordered in such a way that each possible permutation of those elements has equal probability of appearance.
@ -189,15 +189,16 @@ If no seed is provided a random one will be used:
It is possible to override the seed to produce stable results:
[example:explicit_seed]
)",
Documentation::Examples{
{"random_seed", "SELECT arrayShuffle([1, 2, 3, 4])"},
{"explicit_seed", "SELECT arrayShuffle([1, 2, 3, 4], 41)"},
{"materialize", "SELECT arrayShuffle(materialize([1, 2, 3]), 42), arrayShuffle([1, 2, 3], 42) FROM numbers(10)"}},
Documentation::Categories{"Array"}},
.examples{
{"random_seed", "SELECT arrayShuffle([1, 2, 3, 4])", ""},
{"explicit_seed", "SELECT arrayShuffle([1, 2, 3, 4], 41)", ""},
{"materialize", "SELECT arrayShuffle(materialize([1, 2, 3]), 42), arrayShuffle([1, 2, 3], 42) FROM numbers(10)", ""}},
.categories{"Array"}},
FunctionFactory::CaseInsensitive);
factory.registerFunction<FunctionArrayShuffleImpl<FunctionArrayPartialShuffleTraits>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns an array of the same size as the original array where elements in range [1..limit] are a random
subset of the original array. Remaining (limit..n] shall contain the elements not in [1..limit] range in undefined order.
Value of limit shall be in range [1..n]. Values outside of that range are equivalent to performing full arrayShuffle:
@ -213,14 +214,14 @@ If no seed is provided a random one will be used:
It is possible to override the seed to produce stable results:
[example:explicit_seed]
)",
Documentation::Examples{
{"no_limit1", "SELECT arrayPartialShuffle([1, 2, 3, 4], 0)"},
{"no_limit2", "SELECT arrayPartialShuffle([1, 2, 3, 4])"},
{"random_seed", "SELECT arrayPartialShuffle([1, 2, 3, 4], 2)"},
{"explicit_seed", "SELECT arrayPartialShuffle([1, 2, 3, 4], 2, 41)"},
.examples{
{"no_limit1", "SELECT arrayPartialShuffle([1, 2, 3, 4], 0)", ""},
{"no_limit2", "SELECT arrayPartialShuffle([1, 2, 3, 4])", ""},
{"random_seed", "SELECT arrayPartialShuffle([1, 2, 3, 4], 2)", ""},
{"explicit_seed", "SELECT arrayPartialShuffle([1, 2, 3, 4], 2, 41)", ""},
{"materialize",
"SELECT arrayPartialShuffle(materialize([1, 2, 3, 4]), 2, 42), arrayPartialShuffle([1, 2, 3], 2, 42) FROM numbers(10)"}},
Documentation::Categories{"Array"}},
"SELECT arrayPartialShuffle(materialize([1, 2, 3, 4]), 2, 42), arrayPartialShuffle([1, 2, 3], 2, 42) FROM numbers(10)", ""}},
.categories{"Array"}},
FunctionFactory::CaseInsensitive);
}

View File

@ -86,8 +86,8 @@ REGISTER_FUNCTION(ArraySort)
factory.registerFunction<FunctionArraySort>();
factory.registerFunction<FunctionArrayReverseSort>();
factory.registerFunction<FunctionArrayPartialSort>({
R"(
factory.registerFunction<FunctionArrayPartialSort>(FunctionDocumentation{
.description=R"(
Returns an array of the same size as the original array where elements in range `[1..limit]`
are sorted in ascending order. Remaining elements `(limit..N]` shall contain elements in unspecified order.
[example:simple_int]
@ -106,15 +106,16 @@ that the arguments of `func` will correspond to.
For more details see documentation of `arraySort`.
)",
Documentation::Examples{
{"simple_int", "SELECT arrayPartialSort(2, [5, 9, 1, 3])"},
{"simple_string", "SELECT arrayPartialSort(2, ['expenses','lasso','embolism','gladly'])"},
{"retain_sorted", "SELECT arrayResize(arrayPartialSort(2, [5, 9, 1, 3]), 2)"},
{"lambda_simple", "SELECT arrayPartialSort((x) -> -x, 2, [5, 9, 1, 3])"},
{"lambda_complex", "SELECT arrayPartialSort((x, y) -> -y, 1, [0, 1, 2], [1, 2, 3]) as res"}},
Documentation::Categories{"Array"}});
factory.registerFunction<FunctionArrayPartialReverseSort>({
R"(
.examples{
{"simple_int", "SELECT arrayPartialSort(2, [5, 9, 1, 3])", ""},
{"simple_string", "SELECT arrayPartialSort(2, ['expenses','lasso','embolism','gladly'])", ""},
{"retain_sorted", "SELECT arrayResize(arrayPartialSort(2, [5, 9, 1, 3]), 2)", ""},
{"lambda_simple", "SELECT arrayPartialSort((x) -> -x, 2, [5, 9, 1, 3])", ""},
{"lambda_complex", "SELECT arrayPartialSort((x, y) -> -y, 1, [0, 1, 2], [1, 2, 3]) as res", ""}},
.categories{"Array"}});
factory.registerFunction<FunctionArrayPartialReverseSort>(FunctionDocumentation{
.description=R"(
Returns an array of the same size as the original array where elements in range `[1..limit]`
are sorted in descending order. Remaining elements `(limit..N]` shall contain elements in unspecified order.
[example:simple_int]
@ -133,13 +134,13 @@ that the arguments of `func` will correspond to.
For more details see documentation of `arraySort`.
)",
Documentation::Examples{
{"simple_int", "SELECT arrayPartialReverseSort(2, [5, 9, 1, 3])"},
{"simple_string", "SELECT arrayPartialReverseSort(2, ['expenses','lasso','embolism','gladly'])"},
{"retain_sorted", "SELECT arrayResize(arrayPartialReverseSort(2, [5, 9, 1, 3]), 2)"},
{"lambda_simple", "SELECT arrayPartialReverseSort((x) -> -x, 2, [5, 9, 1, 3])"},
{"lambda_complex", "SELECT arrayPartialReverseSort((x, y) -> -y, 1, [0, 1, 2], [1, 2, 3]) as res"}},
Documentation::Categories{"Array"}});
.examples{
{"simple_int", "SELECT arrayPartialReverseSort(2, [5, 9, 1, 3])", ""},
{"simple_string", "SELECT arrayPartialReverseSort(2, ['expenses','lasso','embolism','gladly'])", ""},
{"retain_sorted", "SELECT arrayResize(arrayPartialReverseSort(2, [5, 9, 1, 3]), 2)", ""},
{"lambda_simple", "SELECT arrayPartialReverseSort((x) -> -x, 2, [5, 9, 1, 3])", ""},
{"lambda_complex", "SELECT arrayPartialReverseSort((x, y) -> -y, 1, [0, 1, 2], [1, 2, 3]) as res", ""}},
.categories{"Array"}});
}
}

View File

@ -66,8 +66,8 @@ using FunctionLength = FunctionStringOrArrayToT<LengthImpl, NameLength, UInt64,
REGISTER_FUNCTION(Length)
{
factory.registerFunction<FunctionLength>(
{
R"(
FunctionDocumentation{
.description=R"(
Calculates the length of the string or array.
For String or FixedString argument: calculates the number of bytes in string.
@ -87,18 +87,18 @@ and it is not the same as the visible string width.
It is ok to have ASCII NUL bytes in strings, and they will be counted as well.
[example:nul]
)",
Documentation::Examples{
{"string1", "SELECT length('Hello, world!')"},
{"arr1", "SELECT length(['Hello'], ['world'])"},
.examples{
{"string1", "SELECT length('Hello, world!')", ""},
{"arr1", "SELECT length(['Hello'], ['world'])", ""},
{"constexpr", "WITH 'hello' || toString(number) AS str\n"
"SELECT str, \n"
" isConstant(length(str)) AS str_length_is_constant, \n"
" isConstant(length(str::FixedString(6))) AS fixed_str_length_is_constant\n"
"FROM numbers(3)"},
{"unicode", "SELECT 'ёлка' AS str1, length(str1), lengthUTF8(str1), normalizeUTF8NFKD(str1) AS str2, length(str2), lengthUTF8(str2)"},
{"nul", R"(SELECT 'abc\0\0\0' AS str, length(str))"},
"FROM numbers(3)", ""},
{"unicode", "SELECT 'ёлка' AS str1, length(str1), lengthUTF8(str1), normalizeUTF8NFKD(str1) AS str2, length(str2), lengthUTF8(str2)", ""},
{"nul", R"(SELECT 'abc\0\0\0' AS str, length(str))", ""},
},
Documentation::Categories{"String", "Array"}
.categories{"String", "Array"}
},
FunctionFactory::CaseInsensitive);
}

View File

@ -82,14 +82,14 @@ using FunctionAscii = FunctionStringOrArrayToT<AsciiImpl, AsciiName, AsciiImpl::
REGISTER_FUNCTION(Ascii)
{
factory.registerFunction<FunctionAscii>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns the ASCII code point of the first character of str. The result type is Int32.
If s is empty, the result is 0. If the first character is not an ASCII character or not part of the Latin-1 Supplement range of UTF-16, the result is undefined)
)",
Documentation::Examples{{"ascii", "SELECT ascii('234')"}},
Documentation::Categories{"String"}
.examples{{"ascii", "SELECT ascii('234')", ""}},
.categories{"String"}
}, FunctionFactory::CaseInsensitive);
}

View File

@ -14,9 +14,9 @@ using FunctionAsin = FunctionMathUnary<UnaryFunctionVectorized<AsinName, asin>>;
REGISTER_FUNCTION(Asin)
{
factory.registerFunction<FunctionAsin>(
factory.registerFunction<FunctionAsin>(FunctionDocumentation
{
R"(
.description=R"(
Calculates the arcsine of the argument.
Takes arbitrary numeric type, which includes floating point and integer numbers, as well as big integers and decimals and returns Float64.
@ -35,11 +35,11 @@ For arguments outside of this range, it returns nan:
Every self-respectful data scientist knows how to apply arcsine to improve ads click-through rate with ClickHouse.
For more details, see [https://en.wikipedia.org/wiki/Inverse_trigonometric_functions].
)",
Documentation::Examples{
{"inverse", "SELECT asin(1.0) = pi() / 2, sin(asin(1)), asin(sin(1))"},
{"float32", "SELECT toTypeName(asin(1.0::Float32))"},
{"nan", "SELECT asin(1.1), asin(-2), asin(inf), asin(nan)"}},
Documentation::Categories{"Mathematical", "Trigonometric"}
.examples{
{"inverse", "SELECT asin(1.0) = pi() / 2, sin(asin(1)), asin(sin(1))", ""},
{"float32", "SELECT toTypeName(asin(1.0::Float32))", ""},
{"nan", "SELECT asin(1.1), asin(-2), asin(inf), asin(nan)", ""}},
.categories{"Mathematical", "Trigonometric"}
},
FunctionFactory::CaseInsensitive);
}

View File

@ -47,13 +47,13 @@ public:
REGISTER_FUNCTION(CanonicalRand)
{
factory.registerFunction<FunctionCanonicalRand>({
R"(
factory.registerFunction<FunctionCanonicalRand>(FunctionDocumentation{
.description=R"(
The function generates pseudo random results with independent and identically distributed uniformly distributed values in [0, 1).
Non-deterministic. Return type is Float64.
)",
Documentation::Examples{{"randCanonical", "SELECT randCanonical()"}},
Documentation::Categories{"Mathematical"}});
.examples{{"randCanonical", "SELECT randCanonical()", ""}},
.categories{"Mathematical"}});
}
}

View File

@ -155,21 +155,21 @@ using FunctionConcatWithSeparatorAssumeInjective = ConcatWithSeparatorImpl<NameC
REGISTER_FUNCTION(ConcatWithSeparator)
{
factory.registerFunction<FunctionConcatWithSeparator>({
R"(
factory.registerFunction<FunctionConcatWithSeparator>(FunctionDocumentation{
.description=R"(
Returns the concatenation strings separated by string separator. Syntax: concatWithSeparator(sep, expr1, expr2, expr3...)
)",
Documentation::Examples{{"concatWithSeparator", "SELECT concatWithSeparator('a', '1', '2', '3')"}},
Documentation::Categories{"String"}});
.examples{{"concatWithSeparator", "SELECT concatWithSeparator('a', '1', '2', '3')", ""}},
.categories{"String"}});
factory.registerFunction<FunctionConcatWithSeparatorAssumeInjective>({
R"(
factory.registerFunction<FunctionConcatWithSeparatorAssumeInjective>(FunctionDocumentation{
.description=R"(
Same as concatWithSeparator, the difference is that you need to ensure that concatWithSeparator(sep, expr1, expr2, expr3...) result is injective, it will be used for optimization of GROUP BY.
The function is named injective if it always returns different result for different values of arguments. In other words: different arguments never yield identical result.
)",
Documentation::Examples{{"concatWithSeparatorAssumeInjective", "SELECT concatWithSeparatorAssumeInjective('a', '1', '2', '3')"}},
Documentation::Categories{"String"}});
.examples{{"concatWithSeparatorAssumeInjective", "SELECT concatWithSeparatorAssumeInjective('a', '1', '2', '3')", ""}},
.categories{"String"}});
/// Compatibility with Spark:
factory.registerAlias("concat_ws", "concatWithSeparator", FunctionFactory::CaseInsensitive);

View File

@ -457,16 +457,16 @@ REGISTER_FUNCTION(DateDiff)
REGISTER_FUNCTION(TimeDiff)
{
factory.registerFunction<FunctionTimeDiff>({R"(
factory.registerFunction<FunctionTimeDiff>(FunctionDocumentation{.description=R"(
Returns the difference between two dates or dates with time values. The difference is calculated in seconds units (see toRelativeSecondNum).
It is same as `dateDiff` and was added only for MySQL support. `dateDiff` is preferred.
Example:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT timeDiff(UTCTimestamp(), now());"}},
Documentation::Categories{"Dates and Times"}}, FunctionFactory::CaseInsensitive);
.examples{
{"typical", "SELECT timeDiff(UTCTimestamp(), now());", ""}},
.categories{"Dates and Times"}}, FunctionFactory::CaseInsensitive);
}
REGISTER_FUNCTION(Age)

View File

@ -58,69 +58,54 @@ struct DivideDecimalsImpl
REGISTER_FUNCTION(DivideDecimals)
{
factory.registerFunction<FunctionsDecimalArithmetics<DivideDecimalsImpl>>(Documentation(
R"(
factory.registerFunction<FunctionsDecimalArithmetics<DivideDecimalsImpl>>(FunctionDocumentation{
.description = R"(
Performs division on two decimals. Result value will be of type [Decimal256](../../sql-reference/data-types/decimal.md).
Result scale can be explicitly specified by `result_scale` argument (const Integer in range `[0, 76]`). If not specified, the result scale is the max scale of given arguments.
:::note
These function work significantly slower than usual `divide`.
In case you don't really need controlled precision and/or need fast computation, consider using [divide](#divide).
:::
**Syntax**
```sql
divideDecimal(a, b[, result_scale])
```
**Arguments**
- `a` First value: [Decimal](../../sql-reference/data-types/decimal.md).
- `b` Second value: [Decimal](../../sql-reference/data-types/decimal.md).
- `result_scale` Scale of result: [Int/UInt](../../sql-reference/data-types/int-uint.md).
**Returned value**
- The result of division with given scale.
Type: [Decimal256](../../sql-reference/data-types/decimal.md).
**Example**
```text
:::)",
.syntax = "divideDecimal(a, b[, result_scale])",
.arguments = {
{"a", "First value: [Decimal](../../sql-reference/data-types/decimal.md)"},
{"b", "Second value: [Decimal](../../sql-reference/data-types/decimal.md)."}
},
.returned_value = "The result of division with given scale. Type: [Decimal256](../../sql-reference/data-types/decimal.md).",
.examples = {
{"", "divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)",
R"(
divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)
-5.7142857142
```
)"}, {"Difference to regular division",
**Difference from regular division:**
```sql
R"(
SELECT toDecimal64(-12, 1) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 1) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
```
```text
)",
R"(
divide(toDecimal64(-12, 1), toDecimal32(2.1, 1))
-5.7
abdivideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 1)divideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 5)
-12 2.1 -5.7 -5.71428
```
```sql
)"
},
{"",
R"(
SELECT toDecimal64(-12, 0) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 0) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
```
```text
)",
R"(
DB::Exception: Decimal result's scale is less than argument's one: While processing toDecimal64(-12, 0) / toDecimal32(2.1, 1). (ARGUMENT_OUT_OF_BOUND)
abdivideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 1)divideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 5)
-12 2.1 -5.7 -5.71428
```
)"));
)"}
}});
}
}

View File

@ -97,15 +97,15 @@ template <> struct FunctionUnaryArithmeticMonotonicity<NameFactorial>
REGISTER_FUNCTION(Factorial)
{
factory.registerFunction<FunctionFactorial>(
factory.registerFunction<FunctionFactorial>(FunctionDocumentation
{
R"(
.description=R"(
Computes the factorial of an integer value. It works with any native integer type including UInt(8|16|32|64) and Int(8|16|32|64). The return type is UInt64.
The factorial of 0 is 1. Likewise, the factorial() function returns 1 for any negative value. The maximum positive value for the input argument is 20, a value of 21 or greater will cause exception throw.
)",
Documentation::Examples{{"factorial", "SELECT factorial(10)"}},
Documentation::Categories{"Mathematical"}},
.examples{{"factorial", "SELECT factorial(10)", ""}},
.categories{"Mathematical"}},
FunctionFactory::CaseInsensitive);
}

View File

@ -21,13 +21,13 @@ namespace
REGISTER_FUNCTION(FormatReadableDecimalSize)
{
factory.registerFunction<FunctionFormatReadable<Impl>>(
{
R"(
FunctionDocumentation{
.description=R"(
Accepts the size (number of bytes). Returns a rounded size with a suffix (KB, MB, etc.) as a string.
)",
Documentation::Examples{
{"formatReadableDecimalSize", "SELECT formatReadableDecimalSize(1000)"}},
Documentation::Categories{"OtherFunctions"}
.examples{
{"formatReadableDecimalSize", "SELECT formatReadableDecimalSize(1000)", ""}},
.categories{"OtherFunctions"}
},
FunctionFactory::CaseSensitive);
}

View File

@ -74,17 +74,17 @@ public:
REGISTER_FUNCTION(GenerateULID)
{
factory.registerFunction<FunctionGenerateULID>(
factory.registerFunction<FunctionGenerateULID>(FunctionDocumentation
{
R"(
.description=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"}
.examples{
{"ulid", "SELECT generateULID()", ""},
{"multiple", "SELECT generateULID(1), generateULID(2)", ""}},
.categories{"ULID"}
},
FunctionFactory::CaseSensitive);
}

View File

@ -53,14 +53,14 @@ private:
REGISTER_FUNCTION(GetSubcolumn)
{
factory.registerFunction<FunctionGetSubcolumn>({
R"(
factory.registerFunction<FunctionGetSubcolumn>(FunctionDocumentation{
.description=R"(
Receives the expression or identifier and constant string with the name of subcolumn.
Returns requested subcolumn extracted from the expression.
)",
Documentation::Examples{{"getSubcolumn", "SELECT getSubcolumn(array_col, 'size0'), getSubcolumn(tuple_col, 'elem_name')"}},
Documentation::Categories{"OtherFunctions"}
.examples{{"getSubcolumn", "SELECT getSubcolumn(array_col, 'size0'), getSubcolumn(tuple_col, 'elem_name')", ""}},
.categories{"OtherFunctions"}
});
}

View File

@ -1,10 +1,10 @@
#include "FunctionFactory.h"
#include "FunctionsStringSearch.h"
#include "HasTokenImpl.h"
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionsStringSearch.h>
#include <Functions/HasTokenImpl.h>
#include <Common/Volnitsky.h>
namespace
namespace DB
{
struct NameHasToken
{
@ -19,14 +19,15 @@ struct NameHasTokenOrNull
using FunctionHasToken = DB::FunctionsStringSearch<DB::HasTokenImpl<NameHasToken, DB::VolnitskyCaseSensitiveToken, false>>;
using FunctionHasTokenOrNull = DB::
FunctionsStringSearch<DB::HasTokenImpl<NameHasTokenOrNull, DB::VolnitskyCaseSensitiveToken, false>, DB::ExecutionErrorPolicy::Null>;
}
REGISTER_FUNCTION(HasToken)
{
factory.registerFunction<FunctionHasToken>(
{"Performs lookup of needle in haystack using tokenbf_v1 index."}, DB::FunctionFactory::CaseSensitive);
factory.registerFunction<FunctionHasToken>(FunctionDocumentation
{.description="Performs lookup of needle in haystack using tokenbf_v1 index."}, DB::FunctionFactory::CaseSensitive);
factory.registerFunction<FunctionHasTokenOrNull>(
{"Performs lookup of needle in haystack using tokenbf_v1 index. Returns null if needle is ill-formed."},
factory.registerFunction<FunctionHasTokenOrNull>(FunctionDocumentation
{.description="Performs lookup of needle in haystack using tokenbf_v1 index. Returns null if needle is ill-formed."},
DB::FunctionFactory::CaseSensitive);
}
}

View File

@ -1,10 +1,10 @@
#include "FunctionFactory.h"
#include "FunctionsStringSearch.h"
#include "HasTokenImpl.h"
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionsStringSearch.h>
#include <Functions/HasTokenImpl.h>
#include <Common/Volnitsky.h>
namespace
namespace DB
{
struct NameHasTokenCaseInsensitive
{
@ -21,14 +21,16 @@ using FunctionHasTokenCaseInsensitive
using FunctionHasTokenCaseInsensitiveOrNull = DB::FunctionsStringSearch<
DB::HasTokenImpl<NameHasTokenCaseInsensitiveOrNull, DB::VolnitskyCaseInsensitiveToken, false>,
DB::ExecutionErrorPolicy::Null>;
}
REGISTER_FUNCTION(HasTokenCaseInsensitive)
{
factory.registerFunction<FunctionHasTokenCaseInsensitive>(
{"Performs case insensitive lookup of needle in haystack using tokenbf_v1 index."}, DB::FunctionFactory::CaseInsensitive);
FunctionDocumentation{.description="Performs case insensitive lookup of needle in haystack using tokenbf_v1 index."},
DB::FunctionFactory::CaseInsensitive);
factory.registerFunction<FunctionHasTokenCaseInsensitiveOrNull>(
{"Performs case insensitive lookup of needle in haystack using tokenbf_v1 index. Returns null if needle is ill-formed."},
FunctionDocumentation{.description="Performs case insensitive lookup of needle in haystack using tokenbf_v1 index. Returns null if needle is ill-formed."},
DB::FunctionFactory::CaseInsensitive);
}
}

View File

@ -135,8 +135,8 @@ struct NameExtractKeyValuePairsWithEscaping
REGISTER_FUNCTION(ExtractKeyValuePairs)
{
factory.registerFunction<ExtractKeyValuePairs<NameExtractKeyValuePairs, false>>(
Documentation(
R"(Extracts key-value pairs from any string. The string does not need to be 100% structured in a key value pair format;
FunctionDocumentation{
.description=R"(Extracts key-value pairs from any string. The string does not need to be 100% structured in a key value pair format;
It can contain noise (e.g. log files). The key-value pair format to be interpreted should be specified via function arguments.
@ -197,12 +197,12 @@ REGISTER_FUNCTION(ExtractKeyValuePairs)
kv
{'age':'a\\x0A\\n\\0'}
```)")
```)"}
);
factory.registerFunction<ExtractKeyValuePairs<NameExtractKeyValuePairsWithEscaping, true>>(
Documentation(
R"(Same as `extractKeyValuePairs` but with escaping support.
FunctionDocumentation{
.description=R"(Same as `extractKeyValuePairs` but with escaping support.
Escape sequences supported: `\x`, `\N`, `\a`, `\b`, `\e`, `\f`, `\n`, `\r`, `\t`, `\v` and `\0`.
Non standard escape sequences are returned as it is (including the backslash) unless they are one of the following:
@ -226,7 +226,7 @@ REGISTER_FUNCTION(ExtractKeyValuePairs)
kv
{'age':'a\n\n\0'}
```)")
```)"}
);
factory.registerAlias("str_to_map", NameExtractKeyValuePairs::name, FunctionFactory::CaseInsensitive);
factory.registerAlias("mapFromString", NameExtractKeyValuePairs::name);

View File

@ -174,15 +174,15 @@ using FunctionPositiveModulo = BinaryArithmeticOverloadResolver<PositiveModuloIm
REGISTER_FUNCTION(PositiveModulo)
{
factory.registerFunction<FunctionPositiveModulo>(
factory.registerFunction<FunctionPositiveModulo>(FunctionDocumentation
{
R"(
.description=R"(
Calculates the remainder when dividing `a` by `b`. Similar to function `modulo` except that `positiveModulo` always return non-negative number.
Returns the difference between `a` and the nearest integer not greater than `a` divisible by `b`.
In other words, the function returning the modulus (modulo) in the terms of Modular Arithmetic.
)",
Documentation::Examples{{"positiveModulo", "SELECT positiveModulo(-1, 10);"}},
Documentation::Categories{"Arithmetic"}},
.examples{{"positiveModulo", "SELECT positiveModulo(-1, 10);", ""}},
.categories{"Arithmetic"}},
FunctionFactory::CaseInsensitive);
factory.registerAlias("positive_modulo", "positiveModulo", FunctionFactory::CaseInsensitive);

View File

@ -380,8 +380,8 @@ private:
REGISTER_FUNCTION(MortonDecode)
{
factory.registerFunction<FunctionMortonDecode>({
R"(
factory.registerFunction<FunctionMortonDecode>(FunctionDocumentation{
.description=R"(
Decodes a Morton encoding (ZCurve) into the corresponding unsigned integer tuple
The function has two modes of operation:
@ -418,15 +418,15 @@ The function accepts a column of codes as a second argument:
The range tuple must be a constant:
[example:from_table_range]
)",
Documentation::Examples{
{"simple", "SELECT mortonDecode(4, 2149)"},
{"range_shrank", "SELECT mortonDecode((1,2), 1572864)"},
{"identity", "SELECT mortonDecode(1, 1)"},
{"identity_shrank", "SELECT mortonDecode(tuple(2), 32768)"},
{"from_table", "SELECT mortonDecode(2, code) FROM table"},
{"from_table_range", "SELECT mortonDecode((1,2), code) FROM table"},
.examples{
{"simple", "SELECT mortonDecode(4, 2149)", ""},
{"range_shrank", "SELECT mortonDecode((1,2), 1572864)", ""},
{"identity", "SELECT mortonDecode(1, 1)", ""},
{"identity_shrank", "SELECT mortonDecode(tuple(2), 32768)", ""},
{"from_table", "SELECT mortonDecode(2, code) FROM table", ""},
{"from_table_range", "SELECT mortonDecode((1,2), code) FROM table", ""},
},
Documentation::Categories {"ZCurve", "Morton coding"}
.categories {"ZCurve", "Morton coding"}
});
}

View File

@ -335,8 +335,8 @@ private:
REGISTER_FUNCTION(MortonEncode)
{
factory.registerFunction<FunctionMortonEncode>({
R"(
factory.registerFunction<FunctionMortonEncode>(FunctionDocumentation{
.description=R"(
Calculates Morton encoding (ZCurve) for a list of unsigned integers
The function has two modes of operation:
@ -378,15 +378,15 @@ Two arguments will have a range of maximum 2^32 (64/2) each
Three arguments: range of max 2^21 (64/3) each
And so on, all overflow will be clamped to zero
)",
Documentation::Examples{
{"simple", "SELECT mortonEncode(1, 2, 3)"},
{"range_expanded", "SELECT mortonEncode((1,2), 1024, 16)"},
{"identity", "SELECT mortonEncode(1)"},
{"identity_expanded", "SELECT mortonEncode(tuple(2), 128)"},
{"from_table", "SELECT mortonEncode(n1, n2) FROM table"},
{"from_table_range", "SELECT mortonEncode((1,2), n1, n2) FROM table"},
.examples{
{"simple", "SELECT mortonEncode(1, 2, 3)", ""},
{"range_expanded", "SELECT mortonEncode((1,2), 1024, 16)", ""},
{"identity", "SELECT mortonEncode(1)", ""},
{"identity_expanded", "SELECT mortonEncode(tuple(2), 128)", ""},
{"from_table", "SELECT mortonEncode(n1, n2) FROM table", ""},
{"from_table_range", "SELECT mortonEncode((1,2), n1, n2) FROM table", ""},
},
Documentation::Categories {"ZCurve", "Morton coding"}
.categories {"ZCurve", "Morton coding"}
});
}

View File

@ -58,8 +58,8 @@ struct MultiplyDecimalsImpl
REGISTER_FUNCTION(MultiplyDecimals)
{
factory.registerFunction<FunctionsDecimalArithmetics<MultiplyDecimalsImpl>>(Documentation(
R"(
factory.registerFunction<FunctionsDecimalArithmetics<MultiplyDecimalsImpl>>(FunctionDocumentation{
.description=R"(
Performs multiplication on two decimals. Result value will be of type [Decimal256](../../sql-reference/data-types/decimal.md).
Result scale can be explicitly specified by `result_scale` argument (const Integer in range `[0, 76]`). If not specified, the result scale is the max scale of given arguments.
@ -127,7 +127,7 @@ SELECT
Received exception from server (version 22.11.1):
Code: 407. DB::Exception: Received from localhost:9000. DB::Exception: Decimal math overflow: While processing toDecimal64(-12.647987876, 9) AS a, toDecimal64(123.967645643, 9) AS b, a * b. (DECIMAL_OVERFLOW)
```
)"));
)"});
}

View File

@ -165,12 +165,12 @@ private:
REGISTER_FUNCTION(Nested)
{
factory.registerFunction<FunctionNested>({
R"(
factory.registerFunction<FunctionNested>(FunctionDocumentation{
.description=R"(
Returns the array of tuples from multiple arrays.
)",
Documentation::Examples{{"nested", "SELECT nested(['keys', 'values'], ['key_1', 'key_2'], ['value_1','value_2'])"}},
Documentation::Categories{"OtherFunctions"}
.examples{{"nested", "SELECT nested(['keys', 'values'], ['key_1', 'key_2'], ['value_1','value_2'])", ""}},
.categories{"OtherFunctions"}
});
}

View File

@ -310,96 +310,96 @@ public:
REGISTER_FUNCTION(Distribution)
{
factory.registerFunction<FunctionRandomDistribution<UniformDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the uniform distribution in the specified range.
Accepts two parameters - minimum bound and maximum bound.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randUniform(0, 1) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randUniform(0, 1) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<NormalDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the normal distribution.
Accepts two parameters - mean and variance.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randNormal(0, 5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randNormal(0, 5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<LogNormalDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the lognormal distribution (a distribution of a random variable whose logarithm is normally distributed).
Accepts two parameters - mean and variance.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randLogNormal(0, 5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randLogNormal(0, 5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<ExponentialDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the exponential distribution.
Accepts one parameter - lambda value.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randExponential(0, 5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randExponential(0, 5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<ChiSquaredDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the chi-squared distribution (a distribution of a sum of the squares of k independent standard normal random variables).
Accepts one parameter - degree of freedom.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randChiSquared(5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randChiSquared(5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<StudentTDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the t-distribution.
Accepts one parameter - degree of freedom.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randStudentT(5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randStudentT(5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<FisherFDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the f-distribution.
The F-distribution is the distribution of X = (S1 / d1) / (S2 / d2) where d1 and d2 are degrees of freedom.
Accepts two parameters - degrees of freedom.
@ -407,69 +407,69 @@ Accepts two parameters - degrees of freedom.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randFisherF(5) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randFisherF(5) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<BernoulliDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the Bernoulli distribution.
Accepts one parameter - probability of success.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randBernoulli(0.1) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randBernoulli(0.1) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<BinomialDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the binomial distribution.
Accepts two parameters - number of experiments and probability of success in each experiment.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randBinomial(10, 0.1) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randBinomial(10, 0.1) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<NegativeBinomialDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the negative binomial distribution.
Accepts two parameters - number of experiments and probability of success in each experiment.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randNegativeBinomial(10, 0.1) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randNegativeBinomial(10, 0.1) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
factory.registerFunction<FunctionRandomDistribution<PoissonDistribution>>(
{
R"(
FunctionDocumentation{
.description=R"(
Returns a random number from the poisson distribution.
Accepts one parameter - the mean number of occurrences.
Typical usage:
[example:typical]
)",
Documentation::Examples{
{"typical", "SELECT randPoisson(3) FROM numbers(100000);"}},
Documentation::Categories{"Distribution"}
.examples{
{"typical", "SELECT randPoisson(3) FROM numbers(100000);", ""}},
.categories{"Distribution"}
});
}

View File

@ -8,7 +8,7 @@
#include <Functions/Regexps.h>
#include <Interpreters/Context.h>
#include <base/StringRef.h>
#include <Common/Documentation.h>
#include <Common/FunctionDocumentation.h>
namespace DB
{
@ -244,7 +244,7 @@ private:
REGISTER_FUNCTION(RegexpExtract)
{
factory.registerFunction<FunctionRegexpExtract>(
Documentation{"Extracts the first string in haystack that matches the regexp pattern and corresponds to the regex group index."});
FunctionDocumentation{.description="Extracts the first string in haystack that matches the regexp pattern and corresponds to the regex group index."});
/// For Spark compatibility.
factory.registerAlias("REGEXP_EXTRACT", "regexpExtract", FunctionFactory::CaseInsensitive);

View File

@ -99,43 +99,19 @@ public:
REGISTER_FUNCTION(ReverseDNSQuery)
{
factory.registerFunction<ReverseDNSQuery>(
Documentation(
R"(Performs a reverse DNS query to get the PTR records associated with the IP address.
**Syntax**
``` sql
reverseDNSQuery(address)
```
This function performs reverse DNS resolutions on both IPv4 and IPv6.
**Arguments**
- `address` An IPv4 or IPv6 address. [String](../../sql-reference/data-types/string.md).
**Returned value**
- Associated domains (PTR records).
Type: Type: [Array(String)](../../sql-reference/data-types/array.md).
**Example**
Query:
``` sql
SELECT reverseDNSQuery('192.168.0.2');
```
Result:
``` text
reverseDNSQuery('192.168.0.2')
['test2.example.com','test3.example.com']
```
)")
FunctionDocumentation{
.description = R"(Performs a reverse DNS query to get the PTR records associated with the IP address)",
.syntax = "reverseDNSQuery(address)",
.arguments = {{"address", "An IPv4 or IPv6 address. [String](../../sql-reference/data-types/string.md)"}},
.returned_value = "Associated domains (PTR records). [String](../../sql-reference/data-types/string.md).",
.examples = {{"",
"SELECT reverseDNSQuery('192.168.0.2');",
R"(
reverseDNSQuery('192.168.0.2')
['test2.example.com','test3.example.com']
)"}}
}
);
}

View File

@ -184,15 +184,15 @@ REGISTER_FUNCTION(GetOSKernelVersion)
REGISTER_FUNCTION(DisplayName)
{
factory.registerFunction<FunctionDisplayName>(
factory.registerFunction<FunctionDisplayName>(FunctionDocumentation
{
R"(
.description=R"(
Returns the value of `display_name` from config or server FQDN if not set.
[example:displayName]
)",
Documentation::Examples{{"displayName", "SELECT displayName();"}},
Documentation::Categories{"Constant", "Miscellaneous"}
.examples{{"displayName", "SELECT displayName();", ""}},
.categories{"Constant", "Miscellaneous"}
},
FunctionFactory::CaseSensitive);
}

View File

@ -112,7 +112,7 @@ struct NameSoundex
REGISTER_FUNCTION(Soundex)
{
factory.registerFunction<FunctionStringToString<SoundexImpl, NameSoundex>>(
Documentation{"Returns Soundex code of a string."}, FunctionFactory::CaseInsensitive);
FunctionDocumentation{.description="Returns Soundex code of a string."}, FunctionFactory::CaseInsensitive);
}

View File

@ -1,4 +1,4 @@
#include <Common/Documentation.h>
#include <Common/FunctionDocumentation.h>
#include "config.h"
#if USE_SSL
@ -23,8 +23,8 @@ namespace DB
REGISTER_FUNCTION(TryDecrypt)
{
factory.registerFunction<FunctionDecrypt<TryDecryptImpl>>(Documentation(
"Similar to `decrypt`, but returns NULL if decryption fails because of using the wrong key."));
factory.registerFunction<FunctionDecrypt<TryDecryptImpl>>(FunctionDocumentation{
.description="Similar to `decrypt`, but returns NULL if decryption fails because of using the wrong key."});
}
}

View File

@ -1553,33 +1553,33 @@ REGISTER_FUNCTION(VectorFunctions)
factory.registerFunction<FunctionTupleDivide>();
factory.registerFunction<FunctionTupleNegate>();
factory.registerFunction<FunctionAddTupleOfIntervals>(
factory.registerFunction<FunctionAddTupleOfIntervals>(FunctionDocumentation
{
R"(
.description=R"(
Consecutively adds a tuple of intervals to a Date or a DateTime.
[example:tuple]
)",
Documentation::Examples{
{"tuple", "WITH toDate('2018-01-01') AS date SELECT addTupleOfIntervals(date, (INTERVAL 1 DAY, INTERVAL 1 YEAR))"},
.examples{
{"tuple", "WITH toDate('2018-01-01') AS date SELECT addTupleOfIntervals(date, (INTERVAL 1 DAY, INTERVAL 1 YEAR))", ""},
},
Documentation::Categories{"Tuple", "Interval", "Date", "DateTime"}
.categories{"Tuple", "Interval", "Date", "DateTime"}
});
factory.registerFunction<FunctionSubtractTupleOfIntervals>(
factory.registerFunction<FunctionSubtractTupleOfIntervals>(FunctionDocumentation
{
R"(
.description=R"(
Consecutively subtracts a tuple of intervals from a Date or a DateTime.
[example:tuple]
)",
Documentation::Examples{
{"tuple", "WITH toDate('2018-01-01') AS date SELECT subtractTupleOfIntervals(date, (INTERVAL 1 DAY, INTERVAL 1 YEAR))"},
.examples{
{"tuple", "WITH toDate('2018-01-01') AS date SELECT subtractTupleOfIntervals(date, (INTERVAL 1 DAY, INTERVAL 1 YEAR))", ""},
},
Documentation::Categories{"Tuple", "Interval", "Date", "DateTime"}
.categories{"Tuple", "Interval", "Date", "DateTime"}
});
factory.registerFunction<FunctionTupleAddInterval>(
factory.registerFunction<FunctionTupleAddInterval>(FunctionDocumentation
{
R"(
.description=R"(
Adds an interval to another interval or tuple of intervals. The returned value is tuple of intervals.
[example:tuple]
[example:interval1]
@ -1587,16 +1587,16 @@ Adds an interval to another interval or tuple of intervals. The returned value i
If the types of the first interval (or the interval in the tuple) and the second interval are the same they will be merged into one interval.
[example:interval2]
)",
Documentation::Examples{
{"tuple", "SELECT addInterval((INTERVAL 1 DAY, INTERVAL 1 YEAR), INTERVAL 1 MONTH)"},
{"interval1", "SELECT addInterval(INTERVAL 1 DAY, INTERVAL 1 MONTH)"},
{"interval2", "SELECT addInterval(INTERVAL 1 DAY, INTERVAL 1 DAY)"},
.examples{
{"tuple", "SELECT addInterval((INTERVAL 1 DAY, INTERVAL 1 YEAR), INTERVAL 1 MONTH)", ""},
{"interval1", "SELECT addInterval(INTERVAL 1 DAY, INTERVAL 1 MONTH)", ""},
{"interval2", "SELECT addInterval(INTERVAL 1 DAY, INTERVAL 1 DAY)", ""},
},
Documentation::Categories{"Tuple", "Interval"}
.categories{"Tuple", "Interval"}
});
factory.registerFunction<FunctionTupleSubtractInterval>(
factory.registerFunction<FunctionTupleSubtractInterval>(FunctionDocumentation
{
R"(
.description=R"(
Adds an negated interval to another interval or tuple of intervals. The returned value is tuple of intervals.
[example:tuple]
[example:interval1]
@ -1604,12 +1604,12 @@ Adds an negated interval to another interval or tuple of intervals. The returned
If the types of the first interval (or the interval in the tuple) and the second interval are the same they will be merged into one interval.
[example:interval2]
)",
Documentation::Examples{
{"tuple", "SELECT subtractInterval((INTERVAL 1 DAY, INTERVAL 1 YEAR), INTERVAL 1 MONTH)"},
{"interval1", "SELECT subtractInterval(INTERVAL 1 DAY, INTERVAL 1 MONTH)"},
{"interval2", "SELECT subtractInterval(INTERVAL 2 DAY, INTERVAL 1 DAY)"},
.examples{
{"tuple", "SELECT subtractInterval((INTERVAL 1 DAY, INTERVAL 1 YEAR), INTERVAL 1 MONTH)", ""},
{"interval1", "SELECT subtractInterval(INTERVAL 1 DAY, INTERVAL 1 MONTH)", ""},
{"interval2", "SELECT subtractInterval(INTERVAL 2 DAY, INTERVAL 1 DAY)", ""},
},
Documentation::Categories{"Tuple", "Interval"}
.categories{"Tuple", "Interval"}
});
factory.registerFunction<FunctionTupleMultiplyByNumber>();

View File

@ -252,8 +252,8 @@ public:
REGISTER_FUNCTION(WidthBucket)
{
factory.registerFunction<FunctionWidthBucket>({
R"(
factory.registerFunction<FunctionWidthBucket>(FunctionDocumentation{
.description=R"(
Returns the number of the bucket in which `operand` falls in a histogram having `count` equal-width buckets spanning the range `low` to `high`. Returns `0` if `operand < low`, and returns `count+1` if `operand >= high`.
`operand`, `low`, `high` can be any native number type. `count` can only be unsigned native integer and its value cannot be zero.
@ -279,10 +279,10 @@ Result:
```
)",
Documentation::Examples{
{"simple", "SELECT widthBucket(10.15, -8.6, 23, 18)"},
.examples{
{"simple", "SELECT widthBucket(10.15, -8.6, 23, 18)", ""},
},
Documentation::Categories{"Mathematical"},
.categories{"Mathematical"},
});
factory.registerAlias("width_bucket", "widthBucket", FunctionFactory::CaseInsensitive);

View File

@ -68,9 +68,9 @@ namespace
{
auto documentation = factory.getDocumentation(name);
res_columns[6]->insert(documentation.description);
res_columns[7]->insertDefault();
res_columns[8]->insertDefault();
res_columns[9]->insertDefault();
res_columns[7]->insert(documentation.syntax);
res_columns[8]->insert(documentation.argumentsAsString());
res_columns[9]->insert(documentation.returned_value);
res_columns[10]->insert(documentation.examplesAsString());
res_columns[11]->insert(documentation.categoriesAsString());
}

View File

@ -4,7 +4,7 @@
#include <Storages/IStorage_fwd.h>
#include <Storages/ColumnsDescription.h>
#include <Access/Common/AccessType.h>
#include <Common/Documentation.h>
#include <Common/FunctionDocumentation.h>
#include <Analyzer/IQueryTreeNode.h>
#include <memory>
@ -97,7 +97,7 @@ private:
/// Properties of table function that are independent of argument types and parameters.
struct TableFunctionProperties
{
Documentation documentation;
FunctionDocumentation documentation;
/** It is determined by the possibility of modifying any data or making requests to arbitrary hostnames.
*

View File

@ -21,10 +21,10 @@ using TableFunctionDeltaLake = ITableFunctionDataLake<TableFunctionDeltaLakeName
void registerTableFunctionDeltaLake(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionDeltaLake>(
{.documentation
= {R"(The table function can be used to read the DeltaLake table stored on object store.)",
Documentation::Examples{{"deltaLake", "SELECT * FROM deltaLake(url, access_key_id, secret_access_key)"}},
Documentation::Categories{"DataLake"}},
{.documentation = {
.description=R"(The table function can be used to read the DeltaLake table stored on object store.)",
.examples{{"deltaLake", "SELECT * FROM deltaLake(url, access_key_id, secret_access_key)", ""}},
.categories{"DataLake"}},
.allow_readonly = false});
}

View File

@ -147,20 +147,16 @@ InterpreterExplainQuery TableFunctionExplain::getInterpreter(ContextPtr context)
void registerTableFunctionExplain(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionExplain>({.documentation = {R"(
Returns result of EXPLAIN query.
The function should not be called directly but can be invoked via `SELECT * FROM (EXPLAIN <query>)`.
You can use this query to process the result of EXPLAIN further using SQL (e.g., in tests).
Example:
[example:1]
)",
{{"1", "SELECT explain FROM (EXPLAIN AST SELECT * FROM system.numbers) WHERE explain LIKE '%Asterisk%'"}}
}});
factory.registerFunction<TableFunctionExplain>({.documentation = {
.description=R"(
Returns result of EXPLAIN query.
The function should not be called directly but can be invoked via `SELECT * FROM (EXPLAIN <query>)`.
You can use this query to process the result of EXPLAIN further using SQL (e.g., in tests).
Example:
[example:1]
)",
.examples={{"1", "SELECT explain FROM (EXPLAIN AST SELECT * FROM system.numbers) WHERE explain LIKE '%Asterisk%'", ""}}
}});
}
}

View File

@ -96,9 +96,9 @@ StoragePtr TableFunctionFormat::executeImpl(const ASTPtr & /*ast_function*/, Con
return res;
}
static const Documentation format_table_function_documentation =
static const FunctionDocumentation format_table_function_documentation =
{
R"(
.description=R"(
Extracts table structure from data and parses it according to specified input format.
Syntax: `format(format_name, data)`.
Parameters:
@ -106,7 +106,7 @@ Parameters:
- `data ` - String literal or constant expression that returns a string containing data in specified format.
Returned value: A table with data parsed from `data` argument according specified format and extracted schema.
)",
Documentation::Examples
.examples
{
{
"First example",
@ -131,7 +131,7 @@ Result:
124 World
```
)"
)", ""
},
{
"Second example",
@ -154,10 +154,10 @@ Result:
a Nullable(String)
```
)"
)", ""
},
},
Documentation::Categories{"format", "table-functions"}
.categories{"format", "table-functions"}
};
void registerTableFunctionFormat(TableFunctionFactory & factory)

View File

@ -21,9 +21,9 @@ void registerTableFunctionHudi(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionHudi>(
{.documentation
= {R"(The table function can be used to read the Hudi table stored on object store.)",
Documentation::Examples{{"hudi", "SELECT * FROM hudi(url, access_key_id, secret_access_key)"}},
Documentation::Categories{"DataLake"}},
= {.description=R"(The table function can be used to read the Hudi table stored on object store.)",
.examples{{"hudi", "SELECT * FROM hudi(url, access_key_id, secret_access_key)", ""}},
.categories{"DataLake"}},
.allow_readonly = false});
}
}

View File

@ -23,9 +23,9 @@ void registerTableFunctionIceberg(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionIceberg>(
{.documentation
= {R"(The table function can be used to read the Iceberg table stored on object store.)",
Documentation::Examples{{"iceberg", "SELECT * FROM iceberg(url, access_key_id, secret_access_key)"}},
Documentation::Categories{"DataLake"}},
= {.description=R"(The table function can be used to read the Iceberg table stored on object store.)",
.examples{{"iceberg", "SELECT * FROM iceberg(url, access_key_id, secret_access_key)", ""}},
.categories{"DataLake"}},
.allow_readonly = false});
}

View File

@ -270,9 +270,9 @@ void registerTableFunctionGCS(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionGCS>(
{.documentation
= {R"(The table function can be used to read the data stored on Google Cloud Storage.)",
Documentation::Examples{{"gcs", "SELECT * FROM gcs(url, hmac_key, hmac_secret)"}},
Documentation::Categories{"DataLake"}},
= {.description=R"(The table function can be used to read the data stored on Google Cloud Storage.)",
.examples{{"gcs", "SELECT * FROM gcs(url, hmac_key, hmac_secret)", ""}},
.categories{"DataLake"}},
.allow_readonly = false});
}
@ -280,9 +280,9 @@ void registerTableFunctionS3(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionS3>(
{.documentation
= {R"(The table function can be used to read the data stored on AWS S3.)",
Documentation::Examples{{"s3", "SELECT * FROM s3(url, access_key_id, secret_access_key)"}},
Documentation::Categories{"DataLake"}},
= {.description=R"(The table function can be used to read the data stored on AWS S3.)",
.examples{{"s3", "SELECT * FROM s3(url, access_key_id, secret_access_key)", ""}},
.categories{"DataLake"}},
.allow_readonly = false});
}

View File

@ -48,36 +48,29 @@ StoragePtr TableFunctionZeros<multithreaded>::executeImpl(const ASTPtr & ast_fun
void registerTableFunctionZeros(TableFunctionFactory & factory)
{
factory.registerFunction<TableFunctionZeros<true>>({.documentation = {R"(
Generates a stream of zeros (a table with one column 'zero' of type 'UInt8') of specified size.
factory.registerFunction<TableFunctionZeros<true>>({.documentation = {
.description=R"(
Generates a stream of zeros (a table with one column 'zero' of type 'UInt8') of specified size.
This table function is used in performance tests, where you want to spend as little time as possible to data generation while testing some other parts of queries.
In contrast to the `zeros_mt`, this table function is using single thread for data generation.
Example:
[example:1]
This query will test the speed of `randomPrintableASCII` function using single thread.
See also the `system.zeros` table.)",
.examples={{"1", "SELECT count() FROM zeros(100000000) WHERE NOT ignore(randomPrintableASCII(10))", ""}}
}});
This table function is used in performance tests, where you want to spend as little time as possible to data generation while testing some other parts of queries.
In contrast to the `zeros_mt`, this table function is using single thread for data generation.
Example:
[example:1]
This query will test the speed of `randomPrintableASCII` function using single thread.
See also the `system.zeros` table.
)",
{{"1", "SELECT count() FROM zeros(100000000) WHERE NOT ignore(randomPrintableASCII(10))"}}
}});
factory.registerFunction<TableFunctionZeros<false>>({.documentation = {R"(
Generates a stream of zeros (a table with one column 'zero' of type 'UInt8') of specified size.
This table function is used in performance tests, where you want to spend as little time as possible to data generation while testing some other parts of queries.
In contrast to the `zeros`, this table function is using multiple threads for data generation, according to the `max_threads` setting.
Example:
[example:1]
This query will test the speed of `randomPrintableASCII` function using multiple threads.
See also the `system.zeros` table.
)",
{{"1", "SELECT count() FROM zeros_mt(1000000000) WHERE NOT ignore(randomPrintableASCII(10))"}}
factory.registerFunction<TableFunctionZeros<false>>({.documentation = {
.description=R"(
Generates a stream of zeros (a table with one column 'zero' of type 'UInt8') of specified size.
This table function is used in performance tests, where you want to spend as little time as possible to data generation while testing some other parts of queries.
In contrast to the `zeros`, this table function is using multiple threads for data generation, according to the `max_threads` setting.
Example:
[example:1]
This query will test the speed of `randomPrintableASCII` function using multiple threads.
See also the `system.zeros` table.
)",
.examples={{"1", "SELECT count() FROM zeros_mt(1000000000) WHERE NOT ignore(randomPrintableASCII(10))", ""}}
}});
}