2020-02-17 15:44:13 +00:00
|
|
|
#include "inplaceBlockConversions.h"
|
2019-05-25 11:03:12 +00:00
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/Block.h>
|
2020-01-15 13:00:08 +00:00
|
|
|
#include <Parsers/queryToString.h>
|
2020-07-22 17:13:05 +00:00
|
|
|
#include <Interpreters/TreeRewriter.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Interpreters/ExpressionAnalyzer.h>
|
|
|
|
#include <Interpreters/ExpressionActions.h>
|
|
|
|
#include <Parsers/ASTExpressionList.h>
|
|
|
|
#include <Parsers/ASTWithAlias.h>
|
2020-01-15 13:00:08 +00:00
|
|
|
#include <Parsers/ASTIdentifier.h>
|
2020-02-19 14:58:06 +00:00
|
|
|
#include <Parsers/ASTLiteral.h>
|
|
|
|
#include <Parsers/ASTFunction.h>
|
2016-01-13 00:32:59 +00:00
|
|
|
#include <utility>
|
2019-05-25 11:03:12 +00:00
|
|
|
#include <DataTypes/DataTypesNumber.h>
|
2020-03-03 14:25:28 +00:00
|
|
|
#include <Interpreters/RequiredSourceColumnsVisitor.h>
|
2020-10-02 12:38:50 +00:00
|
|
|
#include <Common/checkStackSize.h>
|
|
|
|
#include <Storages/ColumnsDescription.h>
|
2016-01-13 00:32:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2020-02-17 12:47:34 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
2020-10-02 12:54:51 +00:00
|
|
|
/// Add all required expressions for missing columns calculation
|
2021-02-04 20:36:50 +00:00
|
|
|
void addDefaultRequiredExpressionsRecursively(const Block & block, const String & required_column, const ColumnsDescription & columns, ASTPtr default_expr_list_accum, NameSet & added_columns)
|
2016-01-13 00:32:59 +00:00
|
|
|
{
|
2020-10-02 12:38:50 +00:00
|
|
|
checkStackSize();
|
|
|
|
if (block.has(required_column) || added_columns.count(required_column))
|
|
|
|
return;
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2020-10-02 12:38:50 +00:00
|
|
|
auto column_default = columns.getDefault(required_column);
|
|
|
|
|
|
|
|
if (column_default)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2020-10-02 12:38:50 +00:00
|
|
|
/// expressions must be cloned to prevent modification by the ExpressionAnalyzer
|
|
|
|
auto column_default_expr = column_default->expression->clone();
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2020-10-02 12:54:51 +00:00
|
|
|
/// Our default may depend on columns with default expr which not present in block
|
|
|
|
/// we have to add them to block too
|
2020-10-02 12:38:50 +00:00
|
|
|
RequiredSourceColumnsVisitor::Data columns_context;
|
|
|
|
RequiredSourceColumnsVisitor(columns_context).visit(column_default_expr);
|
|
|
|
NameSet required_columns_names = columns_context.requiredColumns();
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2021-02-14 11:09:36 +00:00
|
|
|
auto cast_func = makeASTFunction("CAST", column_default_expr, std::make_shared<ASTLiteral>(columns.get(required_column).type->getName()));
|
2020-10-02 12:38:50 +00:00
|
|
|
default_expr_list_accum->children.emplace_back(setAlias(cast_func, required_column));
|
|
|
|
added_columns.emplace(required_column);
|
|
|
|
|
|
|
|
for (const auto & required_column_name : required_columns_names)
|
|
|
|
addDefaultRequiredExpressionsRecursively(block, required_column_name, columns, default_expr_list_accum, added_columns);
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2020-10-02 12:38:50 +00:00
|
|
|
}
|
|
|
|
|
2021-02-04 20:36:50 +00:00
|
|
|
ASTPtr defaultRequiredExpressions(const Block & block, const NamesAndTypesList & required_columns, const ColumnsDescription & columns)
|
2020-10-02 12:38:50 +00:00
|
|
|
{
|
|
|
|
ASTPtr default_expr_list = std::make_shared<ASTExpressionList>();
|
|
|
|
|
|
|
|
NameSet added_columns;
|
|
|
|
for (const auto & column : required_columns)
|
|
|
|
addDefaultRequiredExpressionsRecursively(block, column.name, columns, default_expr_list, added_columns);
|
|
|
|
|
2018-11-15 16:57:20 +00:00
|
|
|
if (default_expr_list->children.empty())
|
|
|
|
return nullptr;
|
2020-10-02 12:38:50 +00:00
|
|
|
|
2018-07-04 17:02:47 +00:00
|
|
|
return default_expr_list;
|
|
|
|
}
|
|
|
|
|
2020-01-15 13:00:08 +00:00
|
|
|
ASTPtr convertRequiredExpressions(Block & block, const NamesAndTypesList & required_columns)
|
2018-07-04 17:02:47 +00:00
|
|
|
{
|
2020-01-15 13:00:08 +00:00
|
|
|
ASTPtr conversion_expr_list = std::make_shared<ASTExpressionList>();
|
|
|
|
for (const auto & required_column : required_columns)
|
|
|
|
{
|
|
|
|
if (!block.has(required_column.name))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto column_in_block = block.getByName(required_column.name);
|
|
|
|
if (column_in_block.type->equals(*required_column.type))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto cast_func = makeASTFunction(
|
2021-02-14 12:53:50 +00:00
|
|
|
"CAST", std::make_shared<ASTIdentifier>(required_column.name), std::make_shared<ASTLiteral>(required_column.type->getName()));
|
2020-01-15 13:00:08 +00:00
|
|
|
|
|
|
|
conversion_expr_list->children.emplace_back(setAlias(cast_func, required_column.name));
|
2018-07-04 17:02:47 +00:00
|
|
|
|
2020-01-15 13:00:08 +00:00
|
|
|
}
|
|
|
|
return conversion_expr_list;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:26 +00:00
|
|
|
ActionsDAGPtr createExpressions(
|
2021-02-04 20:36:50 +00:00
|
|
|
const Block & header,
|
2020-01-15 13:00:08 +00:00
|
|
|
ASTPtr expr_list,
|
|
|
|
bool save_unneeded_columns,
|
|
|
|
const NamesAndTypesList & required_columns,
|
|
|
|
const Context & context)
|
|
|
|
{
|
|
|
|
if (!expr_list)
|
2021-02-04 20:36:50 +00:00
|
|
|
return nullptr;
|
2016-08-15 19:41:44 +00:00
|
|
|
|
2021-02-04 20:36:50 +00:00
|
|
|
auto syntax_result = TreeRewriter(context).analyze(expr_list, header.getNamesAndTypesList());
|
2020-01-15 13:00:08 +00:00
|
|
|
auto expression_analyzer = ExpressionAnalyzer{expr_list, syntax_result, context};
|
2021-02-05 14:42:41 +00:00
|
|
|
auto dag = std::make_shared<ActionsDAG>(header.getNamesAndTypesList());
|
|
|
|
auto actions = expression_analyzer.getActionsDAG(true, !save_unneeded_columns);
|
|
|
|
dag = ActionsDAG::merge(std::move(*dag), std::move(*actions));
|
2019-05-25 11:03:12 +00:00
|
|
|
|
2021-02-04 20:36:50 +00:00
|
|
|
if (save_unneeded_columns)
|
2019-05-25 11:03:12 +00:00
|
|
|
{
|
2021-02-09 19:48:34 +00:00
|
|
|
dag->removeUnusedActions(required_columns.getNames());
|
2021-02-04 20:36:50 +00:00
|
|
|
dag->addMaterializingOutputActions();
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2021-02-04 20:36:50 +00:00
|
|
|
|
|
|
|
return dag;
|
2016-01-13 00:32:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-01-15 13:00:08 +00:00
|
|
|
|
|
|
|
void performRequiredConversions(Block & block, const NamesAndTypesList & required_columns, const Context & context)
|
|
|
|
{
|
|
|
|
ASTPtr conversion_expr_list = convertRequiredExpressions(block, required_columns);
|
|
|
|
if (conversion_expr_list->children.empty())
|
|
|
|
return;
|
2021-02-04 20:36:50 +00:00
|
|
|
|
2021-02-05 15:11:26 +00:00
|
|
|
if (auto dag = createExpressions(block, conversion_expr_list, true, required_columns, context))
|
2021-02-04 20:36:50 +00:00
|
|
|
{
|
2021-03-04 17:38:12 +00:00
|
|
|
auto expression = std::make_shared<ExpressionActions>(std::move(dag), ExpressionActionsSettings::fromContext(context));
|
2021-02-04 20:36:50 +00:00
|
|
|
expression->execute(block);
|
|
|
|
}
|
2020-01-15 13:00:08 +00:00
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:26 +00:00
|
|
|
ActionsDAGPtr evaluateMissingDefaults(
|
2021-02-04 20:36:50 +00:00
|
|
|
const Block & header,
|
2020-01-15 13:00:08 +00:00
|
|
|
const NamesAndTypesList & required_columns,
|
2020-10-02 12:38:50 +00:00
|
|
|
const ColumnsDescription & columns,
|
2020-01-15 13:00:08 +00:00
|
|
|
const Context & context, bool save_unneeded_columns)
|
|
|
|
{
|
2020-10-02 12:38:50 +00:00
|
|
|
if (!columns.hasDefaults())
|
2021-02-04 20:36:50 +00:00
|
|
|
return nullptr;
|
2020-01-15 13:00:08 +00:00
|
|
|
|
2021-02-04 20:36:50 +00:00
|
|
|
ASTPtr expr_list = defaultRequiredExpressions(header, required_columns, columns);
|
2021-02-05 15:11:26 +00:00
|
|
|
return createExpressions(header, expr_list, save_unneeded_columns, required_columns, context);
|
2020-01-15 13:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|