mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 00:52:02 +00:00
Treat query as function argument.
This commit is contained in:
parent
fbf06f9858
commit
b40998ca00
@ -152,7 +152,7 @@ void QueryNormalizer::visitChildren(const ASTPtr & node, Data & data)
|
||||
{
|
||||
if (const auto * func_node = node->as<ASTFunction>())
|
||||
{
|
||||
if (func_node->query)
|
||||
if (func_node->tryGetQueryArgument())
|
||||
{
|
||||
if (func_node->name != "view")
|
||||
throw Exception("Query argument can only be used in the `view` TableFunction", ErrorCodes::BAD_ARGUMENTS);
|
||||
|
@ -48,7 +48,6 @@ ASTPtr ASTFunction::clone() const
|
||||
auto res = std::make_shared<ASTFunction>(*this);
|
||||
res->children.clear();
|
||||
|
||||
if (query) { res->query = query->clone(); res->children.push_back(res->query); }
|
||||
if (arguments) { res->arguments = arguments->clone(); res->children.push_back(res->arguments); }
|
||||
if (parameters) { res->parameters = parameters->clone(); res->children.push_back(res->parameters); }
|
||||
|
||||
@ -112,6 +111,16 @@ static bool highlightStringLiteralWithMetacharacters(const ASTPtr & node, const
|
||||
}
|
||||
|
||||
|
||||
ASTSelectWithUnionQuery * ASTFunction::tryGetQueryArgument() const
|
||||
{
|
||||
if (arguments && arguments->children.size() == 1)
|
||||
{
|
||||
return arguments->children[0]->as<ASTSelectWithUnionQuery>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
|
||||
{
|
||||
FormatStateStacked nested_need_parens = frame;
|
||||
@ -119,7 +128,7 @@ void ASTFunction::formatImplWithoutAlias(const FormatSettings & settings, Format
|
||||
nested_need_parens.need_parens = true;
|
||||
nested_dont_need_parens.need_parens = false;
|
||||
|
||||
if (query)
|
||||
if (auto * query = tryGetQueryArgument())
|
||||
{
|
||||
std::string nl_or_nothing = settings.one_line ? "" : "\n";
|
||||
std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' ');
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <Parsers/ASTWithAlias.h>
|
||||
#include <Parsers/ASTExpressionList.h>
|
||||
#include <Parsers/ASTSelectWithUnionQuery.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -13,7 +14,6 @@ class ASTFunction : public ASTWithAlias
|
||||
{
|
||||
public:
|
||||
String name;
|
||||
ASTPtr query; // It's possible for a function to accept a query as its only argument.
|
||||
ASTPtr arguments;
|
||||
/// parameters - for parametric aggregate function. Example: quantile(0.9)(x) - what in first parens are 'parameters'.
|
||||
ASTPtr parameters;
|
||||
@ -26,6 +26,8 @@ public:
|
||||
|
||||
void updateTreeHashImpl(SipHash & hash_state) const override;
|
||||
|
||||
ASTSelectWithUnionQuery * tryGetQueryArgument() const;
|
||||
|
||||
protected:
|
||||
void formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
|
||||
void appendColumnNameImpl(WriteBuffer & ostr) const override;
|
||||
|
@ -260,8 +260,10 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
++pos;
|
||||
auto function_node = std::make_shared<ASTFunction>();
|
||||
tryGetIdentifierNameInto(identifier, function_node->name);
|
||||
function_node->query = query;
|
||||
function_node->children.push_back(function_node->query);
|
||||
auto expr_list_with_single_query = std::make_shared<ASTExpressionList>();
|
||||
expr_list_with_single_query->children.push_back(query);
|
||||
function_node->arguments = expr_list_with_single_query;
|
||||
function_node->children.push_back(function_node->arguments);
|
||||
node = function_node;
|
||||
return true;
|
||||
}
|
||||
|
@ -20,18 +20,15 @@ StoragePtr TableFunctionView::executeImpl(const ASTPtr & ast_function, const Con
|
||||
{
|
||||
if (const auto * function = ast_function->as<ASTFunction>())
|
||||
{
|
||||
if (function->query)
|
||||
if (auto * select = function->tryGetQueryArgument())
|
||||
{
|
||||
if (auto * select = function->query->as<ASTSelectWithUnionQuery>())
|
||||
{
|
||||
auto sample = InterpreterSelectWithUnionQuery::getSampleBlock(function->query, context);
|
||||
auto columns = ColumnsDescription(sample.getNamesAndTypesList());
|
||||
ASTCreateQuery create;
|
||||
create.select = select;
|
||||
auto res = StorageView::create(StorageID(getDatabaseName(), table_name), create, columns);
|
||||
res->startup();
|
||||
return res;
|
||||
}
|
||||
auto sample = InterpreterSelectWithUnionQuery::getSampleBlock(function->arguments->children[0] /* ASTPtr */, context);
|
||||
auto columns = ColumnsDescription(sample.getNamesAndTypesList());
|
||||
ASTCreateQuery create;
|
||||
create.select = select;
|
||||
auto res = StorageView::create(StorageID(getDatabaseName(), table_name), create, columns);
|
||||
res->startup();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
throw Exception("Table function '" + getName() + "' requires a query argument.", ErrorCodes::BAD_ARGUMENTS);
|
||||
|
Loading…
Reference in New Issue
Block a user