Skip to content

FEATURE: Add function signatures to information returned when querying system.functions  #36023

@sarah-mdv

Description

@sarah-mdv

Use case :

Dynamic access to function signatures would be useful for clickhouse context-aware autocompletion and syntax highlighting.
As of now, this information is only available in the documentation and not programmatically accessible.

Proposed solution :

Add a signature column to the system.functions table which includes a list of expected arguments as strings. Some token could indicate a variable number of arguments for a specific argument type.
(Optional) Add a argument_type column that is a list of the same length as in the args column where each position maps to a list of possible types accepted for that argument.

Example:

Current :
SELECT name, is_aggregate, case_insensitive, origin FROM system.functions WHERE name = 'uniq' OR name = 'has' OR name = 'concat';
current_functions_system

Proposed :
SELECT name, is_aggregate, case_insensitive, origin, arguments, argument_types FROM system.functions WHERE name = 'uniq' OR name = 'has' OR name = 'concat';
github_issue_sys_function_suggestion

Additional context :

Multiple IDEs and visualisation platforms offer function signature completion for Clickhouse but so far they run on hard-coded files (see Grafana-clickhouse support for example). However, these files must be updated regularly to accommodate Clickhouse’s rapidly growing set of available functions.

For reasons of maintainability, it would be very helpful to have dynamic access to function signatures.

Proposed implementation :

A rough idea of how this could be perhaps implemented is to use reflection to gather the data types from all functions. They could then be provided to the system.functions fillRows function below.

void fillRow(MutableColumns & res_columns, const String & name, UInt64 is_aggregate, const String & create_query, FunctionOrigin function_origin, const Factory & f)
{
res_columns[0]->insert(name);
res_columns[1]->insert(is_aggregate);
if constexpr (std::is_same_v<Factory, UserDefinedSQLFunctionFactory> || std::is_same_v<Factory, UserDefinedExecutableFunctionFactory>)
{
res_columns[2]->insert(false);
res_columns[3]->insertDefault();
}
else
{
res_columns[2]->insert(f.isCaseInsensitive(name));
if (f.isAlias(name))
res_columns[3]->insert(f.aliasTo(name));
else
res_columns[3]->insertDefault();
}
res_columns[4]->insert(create_query);
res_columns[5]->insert(static_cast<Int8>(function_origin));
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions