diff --git a/docs/en/sql-reference/statements/show.md b/docs/en/sql-reference/statements/show.md index 1c399d2072b..e94718394de 100644 --- a/docs/en/sql-reference/statements/show.md +++ b/docs/en/sql-reference/statements/show.md @@ -638,3 +638,16 @@ Outputs the content of the [system.table_engines](../../operations/system-tables **See Also** - [system.table_engines](../../operations/system-tables/table_engines.md) table + +## SHOW FUNCTIONS + +``` sql +SHOW FUNCTIONS [LIKE | ILIKE ''] +``` + +Outputs the content of the [system.functions](../../operations/system-tables/functions.md) table. + +If either `LIKE` or `ILIKE` clause is specified, the query returns a list of system functions whose names match the provided ``. + +**See Also** +- [system.functions](../../operations/system-tables/functions.md) table diff --git a/src/Interpreters/InterpreterFactory.cpp b/src/Interpreters/InterpreterFactory.cpp index 27c94119750..de3a3d68d39 100644 --- a/src/Interpreters/InterpreterFactory.cpp +++ b/src/Interpreters/InterpreterFactory.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -203,6 +205,10 @@ std::unique_ptr InterpreterFactory::get(ASTPtr & query, ContextMut { return std::make_unique(query, context); } + else if (query->as()) + { + return std::make_unique(query, context); + } else if (query->as()) { return std::make_unique(query, context); diff --git a/src/Interpreters/InterpreterShowFunctionsQuery.cpp b/src/Interpreters/InterpreterShowFunctionsQuery.cpp new file mode 100644 index 00000000000..efadb929451 --- /dev/null +++ b/src/Interpreters/InterpreterShowFunctionsQuery.cpp @@ -0,0 +1,46 @@ +#include + +#include +#include +#include +#include + +namespace DB +{ + +InterpreterShowFunctionsQuery::InterpreterShowFunctionsQuery(const ASTPtr & query_ptr_, ContextMutablePtr context_) + : WithMutableContext(context_), query_ptr(query_ptr_) +{ +} + +BlockIO InterpreterShowFunctionsQuery::execute() +{ + return executeQuery(getRewrittenQuery(), getContext(), true); +} + +String InterpreterShowFunctionsQuery::getRewrittenQuery() +{ + constexpr const char * functions_table = "functions"; + + const auto & query = query_ptr->as(); + + DatabasePtr systemDb = DatabaseCatalog::instance().getSystemDatabase(); + + String rewritten_query = fmt::format( + R"( +SELECT * +FROM {}.{})", + systemDb->getDatabaseName(), + functions_table); + + if (!query.like.empty()) + { + rewritten_query += " WHERE name "; + rewritten_query += query.case_insensitive_like ? "ILIKE " : "LIKE "; + rewritten_query += fmt::format("'{}'", query.like); + } + + return rewritten_query; +} + +} diff --git a/src/Interpreters/InterpreterShowFunctionsQuery.h b/src/Interpreters/InterpreterShowFunctionsQuery.h new file mode 100644 index 00000000000..f15e1ae67b2 --- /dev/null +++ b/src/Interpreters/InterpreterShowFunctionsQuery.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +namespace DB +{ + +class Context; + +class InterpreterShowFunctionsQuery : public IInterpreter, WithMutableContext +{ +public: + InterpreterShowFunctionsQuery(const ASTPtr & query_ptr_, ContextMutablePtr context_); + + BlockIO execute() override; + + bool ignoreQuota() const override { return true; } + bool ignoreLimits() const override { return true; } + +private: + ASTPtr query_ptr; + + String getRewrittenQuery(); +}; + +} diff --git a/src/Parsers/ASTShowFunctionsQuery.cpp b/src/Parsers/ASTShowFunctionsQuery.cpp new file mode 100644 index 00000000000..9253dcf5cb2 --- /dev/null +++ b/src/Parsers/ASTShowFunctionsQuery.cpp @@ -0,0 +1,25 @@ +#include + +#include + +namespace DB +{ + +ASTPtr ASTShowFunctionsQuery::clone() const +{ + auto res = std::make_shared(*this); + res->children.clear(); + cloneOutputOptions(*res); + return res; +} + +void ASTShowFunctionsQuery::formatQueryImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const +{ + settings.ostr << (settings.hilite ? hilite_keyword : "") << "SHOW FUNCTIONS" << (settings.hilite ? hilite_none : ""); + + if (!like.empty()) + settings.ostr << (settings.hilite ? hilite_keyword : "") << (case_insensitive_like ? " ILIKE " : " LIKE ") + << (settings.hilite ? hilite_none : "") << DB::quote << like; +} + +} diff --git a/src/Parsers/ASTShowFunctionsQuery.h b/src/Parsers/ASTShowFunctionsQuery.h new file mode 100644 index 00000000000..6993f939888 --- /dev/null +++ b/src/Parsers/ASTShowFunctionsQuery.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +namespace DB +{ + +class ASTShowFunctionsQuery : public ASTQueryWithOutput +{ +public: + bool case_insensitive_like = false; + String like; + + String getID(char) const override { return "ShowFunctions"; } + ASTPtr clone() const override; + QueryKind getQueryKind() const override { return QueryKind::Show; } + +protected: + void formatQueryImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override; +}; + +} diff --git a/src/Parsers/ParserQueryWithOutput.cpp b/src/Parsers/ParserQueryWithOutput.cpp index a2391495071..9a71bc222b5 100644 --- a/src/Parsers/ParserQueryWithOutput.cpp +++ b/src/Parsers/ParserQueryWithOutput.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ bool ParserQueryWithOutput::parseImpl(Pos & pos, ASTPtr & node, Expected & expec ParserShowTablesQuery show_tables_p; ParserShowColumnsQuery show_columns_p; ParserShowEnginesQuery show_engine_p; + ParserShowFunctionsQuery show_functions_p; ParserShowIndexesQuery show_indexes_p; ParserSelectWithUnionQuery select_p; ParserTablePropertiesQuery table_p; @@ -71,6 +73,7 @@ bool ParserQueryWithOutput::parseImpl(Pos & pos, ASTPtr & node, Expected & expec || show_tables_p.parse(pos, query, expected) || show_columns_p.parse(pos, query, expected) || show_engine_p.parse(pos, query, expected) + || show_functions_p.parse(pos, query, expected) || show_indexes_p.parse(pos, query, expected) || table_p.parse(pos, query, expected) || describe_cache_p.parse(pos, query, expected) diff --git a/src/Parsers/ParserShowFunctionsQuery.cpp b/src/Parsers/ParserShowFunctionsQuery.cpp new file mode 100644 index 00000000000..524d936c4f1 --- /dev/null +++ b/src/Parsers/ParserShowFunctionsQuery.cpp @@ -0,0 +1,35 @@ +#include + +#include +#include +#include +#include + +namespace DB +{ + +bool ParserShowFunctionsQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) +{ + ASTPtr like; + + auto query = std::make_shared(); + if (!ParserKeyword("SHOW FUNCTIONS").ignore(pos, expected)) + return false; + + if (bool insensitive = ParserKeyword("ILIKE").ignore(pos, expected); insensitive || ParserKeyword("LIKE").ignore(pos, expected)) + { + if (insensitive) + query->case_insensitive_like = true; + + if (!ParserStringLiteral().parse(pos, like, expected)) + return false; + } + + if (like) + query->like = like->as().value.safeGet(); + node = query; + + return true; +} + +} diff --git a/src/Parsers/ParserShowFunctionsQuery.h b/src/Parsers/ParserShowFunctionsQuery.h new file mode 100644 index 00000000000..25241d180db --- /dev/null +++ b/src/Parsers/ParserShowFunctionsQuery.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace DB +{ + +/** Parses queries of the form + * SHOW FUNCTIONS [LIKE | ILIKE ''] + */ +class ParserShowFunctionsQuery : public IParserBase +{ +protected: + const char * getName() const override { return "SHOW FUNCTIONS query"; } + + bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override; +}; + +} diff --git a/tests/queries/0_stateless/00419_show_sql_queries.sh b/tests/queries/0_stateless/00419_show_sql_queries.sh index 607703b385a..99252eeb1ba 100755 --- a/tests/queries/0_stateless/00419_show_sql_queries.sh +++ b/tests/queries/0_stateless/00419_show_sql_queries.sh @@ -8,3 +8,4 @@ $CLICKHOUSE_CLIENT -q "SHOW PROCESSLIST" &>/dev/null $CLICKHOUSE_CLIENT -q "SHOW DATABASES" &>/dev/null $CLICKHOUSE_CLIENT -q "SHOW TABLES" &>/dev/null $CLICKHOUSE_CLIENT -q "SHOW ENGINES" &>/dev/null +$CLICKHOUSE_CLIENT -q "SHOW FUNCTIONS" &>/dev/null diff --git a/tests/queries/0_stateless/02875_show_functions.reference b/tests/queries/0_stateless/02875_show_functions.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/02875_show_functions.sh b/tests/queries/0_stateless/02875_show_functions.sh new file mode 100755 index 00000000000..6f8da63ca9e --- /dev/null +++ b/tests/queries/0_stateless/02875_show_functions.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=../shell_config.sh +. "$CURDIR"/../shell_config.sh + +diff -q <($CLICKHOUSE_CLIENT -q "SELECT * from system.functions") \ + <($CLICKHOUSE_CLIENT -q "SHOW FUNCTIONS") + +diff -q <($CLICKHOUSE_CLIENT -q "SELECT * FROM system.functions WHERE name ILIKE 'quantile%'") \ + <($CLICKHOUSE_CLIENT -q "SHOW FUNCTIONS ILIKE 'quantile%'") + +diff -q <($CLICKHOUSE_CLIENT -q "SELECT * FROM system.functions WHERE name LIKE 'median%'") \ + <($CLICKHOUSE_CLIENT -q "SHOW FUNCTIONS LIKE 'median%'")