2021-04-14 17:51:55 +00:00
|
|
|
#include <TableFunctions/TableFunctionExecutable.h>
|
2021-08-25 19:30:22 +00:00
|
|
|
|
|
|
|
#include <Common/Exception.h>
|
2021-04-15 21:15:54 +00:00
|
|
|
#include <TableFunctions/TableFunctionFactory.h>
|
|
|
|
#include <TableFunctions/parseColumnsListForTableFunction.h>
|
|
|
|
#include <Parsers/ASTFunction.h>
|
|
|
|
#include <Parsers/ASTLiteral.h>
|
2021-11-26 18:27:16 +00:00
|
|
|
#include <Parsers/ASTSelectWithUnionQuery.h>
|
2021-04-15 21:15:54 +00:00
|
|
|
#include <Storages/StorageExecutable.h>
|
|
|
|
#include <DataTypes/DataTypeFactory.h>
|
|
|
|
#include <Interpreters/evaluateConstantExpression.h>
|
|
|
|
#include <Interpreters/interpretSubquery.h>
|
|
|
|
#include <boost/algorithm/string.hpp>
|
2021-04-14 17:51:55 +00:00
|
|
|
#include "registerTableFunctions.h"
|
|
|
|
|
2021-04-15 21:15:54 +00:00
|
|
|
|
2021-04-14 17:51:55 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
2021-04-15 21:15:54 +00:00
|
|
|
|
|
|
|
namespace ErrorCodes
|
2021-04-14 17:51:55 +00:00
|
|
|
{
|
2021-04-15 21:15:54 +00:00
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
2021-08-25 19:30:22 +00:00
|
|
|
extern const int UNSUPPORTED_METHOD;
|
2021-04-15 21:15:54 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 19:38:42 +00:00
|
|
|
void TableFunctionExecutable::parseArguments(const ASTPtr & ast_function, ContextPtr context)
|
2021-04-15 21:15:54 +00:00
|
|
|
{
|
|
|
|
const auto * function = ast_function->as<ASTFunction>();
|
|
|
|
|
|
|
|
if (!function->arguments)
|
2021-08-25 19:30:22 +00:00
|
|
|
throw Exception(ErrorCodes::LOGICAL_ERROR,
|
|
|
|
"Table function '{}' must have arguments",
|
|
|
|
getName());
|
2021-04-15 21:15:54 +00:00
|
|
|
|
|
|
|
auto args = function->arguments->children;
|
|
|
|
|
2021-08-28 19:47:59 +00:00
|
|
|
if (args.size() < 3)
|
2021-08-25 19:30:22 +00:00
|
|
|
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
|
|
|
|
"Table function '{}' requires minimum 3 arguments: script_name, format, structure, [input_query...]",
|
|
|
|
getName());
|
2021-04-15 21:15:54 +00:00
|
|
|
|
|
|
|
for (size_t i = 0; i <= 2; ++i)
|
|
|
|
args[i] = evaluateConstantExpressionOrIdentifierAsLiteral(args[i], context);
|
|
|
|
|
2021-08-29 20:19:05 +00:00
|
|
|
auto scipt_name_with_arguments_value = args[0]->as<ASTLiteral &>().value.safeGet<String>();
|
|
|
|
|
|
|
|
std::vector<String> script_name_with_arguments;
|
|
|
|
boost::split(script_name_with_arguments, scipt_name_with_arguments_value, [](char c){ return c == ' '; });
|
|
|
|
|
|
|
|
script_name = script_name_with_arguments[0];
|
|
|
|
script_name_with_arguments.erase(script_name_with_arguments.begin());
|
|
|
|
arguments = std::move(script_name_with_arguments);
|
2021-04-15 21:15:54 +00:00
|
|
|
format = args[1]->as<ASTLiteral &>().value.safeGet<String>();
|
2021-08-28 19:47:59 +00:00
|
|
|
structure = args[2]->as<ASTLiteral &>().value.safeGet<String>();
|
2021-08-24 19:38:42 +00:00
|
|
|
|
2021-08-25 19:30:22 +00:00
|
|
|
for (size_t i = 3; i < args.size(); ++i)
|
|
|
|
{
|
2021-08-29 20:19:05 +00:00
|
|
|
ASTPtr query = args[i]->children.at(0);
|
|
|
|
if (!query->as<ASTSelectWithUnionQuery>())
|
2021-08-25 19:30:22 +00:00
|
|
|
throw Exception(ErrorCodes::UNSUPPORTED_METHOD,
|
|
|
|
"Table function '{}' argument is invalid input query {}",
|
|
|
|
getName(),
|
2021-08-29 20:19:05 +00:00
|
|
|
query->formatForErrorMessage());
|
2021-08-25 19:30:22 +00:00
|
|
|
|
2021-08-29 20:19:05 +00:00
|
|
|
input_queries.emplace_back(std::move(query));
|
2021-04-15 21:15:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-24 19:38:42 +00:00
|
|
|
ColumnsDescription TableFunctionExecutable::getActualTableStructure(ContextPtr context) const
|
2021-04-15 21:15:54 +00:00
|
|
|
{
|
|
|
|
return parseColumnsListFromString(structure, context);
|
|
|
|
}
|
|
|
|
|
2021-08-24 19:38:42 +00:00
|
|
|
StoragePtr TableFunctionExecutable::executeImpl(const ASTPtr & /*ast_function*/, ContextPtr context, const std::string & table_name, ColumnsDescription /*cached_columns*/) const
|
2021-04-15 21:15:54 +00:00
|
|
|
{
|
2021-08-24 19:38:42 +00:00
|
|
|
auto storage_id = StorageID(getDatabaseName(), table_name);
|
2021-11-01 11:22:21 +00:00
|
|
|
auto global_context = context->getGlobalContext();
|
|
|
|
ExecutableSettings settings;
|
|
|
|
settings.script_name = script_name;
|
|
|
|
settings.script_arguments = std::move(arguments);
|
|
|
|
|
|
|
|
auto storage = StorageExecutable::create(storage_id, format, settings, input_queries, getActualTableStructure(context), ConstraintsDescription{});
|
2021-04-15 21:15:54 +00:00
|
|
|
storage->startup();
|
|
|
|
return storage;
|
2021-04-14 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void registerTableFunctionExecutable(TableFunctionFactory & factory)
|
|
|
|
{
|
|
|
|
factory.registerFunction<TableFunctionExecutable>();
|
|
|
|
}
|
2021-04-15 21:15:54 +00:00
|
|
|
|
2021-04-14 17:51:55 +00:00
|
|
|
}
|