2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/Block.h>
|
|
|
|
#include <Storages/ColumnDefault.h>
|
2018-11-08 15:43:14 +00:00
|
|
|
#include <Interpreters/SyntaxAnalyzer.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Interpreters/ExpressionAnalyzer.h>
|
|
|
|
#include <Interpreters/ExpressionActions.h>
|
|
|
|
#include <Interpreters/evaluateMissingDefaults.h>
|
|
|
|
#include <Parsers/ASTExpressionList.h>
|
|
|
|
#include <Parsers/ASTWithAlias.h>
|
2016-01-13 00:32:59 +00:00
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-07-04 17:02:47 +00:00
|
|
|
static ASTPtr requiredExpressions(Block & block, const NamesAndTypesList & required_columns, const ColumnDefaults & column_defaults)
|
2016-01-13 00:32:59 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
ASTPtr default_expr_list = std::make_shared<ASTExpressionList>();
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
for (const auto & column : required_columns)
|
|
|
|
{
|
|
|
|
if (block.has(column.name))
|
|
|
|
continue;
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
const auto it = column_defaults.find(column.name);
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// expressions must be cloned to prevent modification by the ExpressionAnalyzer
|
|
|
|
if (it != column_defaults.end())
|
|
|
|
default_expr_list->children.emplace_back(
|
|
|
|
setAlias(it->second.expression->clone(), it->first));
|
|
|
|
}
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2018-11-15 16:57:20 +00:00
|
|
|
if (default_expr_list->children.empty())
|
|
|
|
return nullptr;
|
2018-07-04 17:02:47 +00:00
|
|
|
return default_expr_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void evaluateMissingDefaults(Block & block,
|
|
|
|
const NamesAndTypesList & required_columns,
|
|
|
|
const ColumnDefaults & column_defaults,
|
2018-12-04 20:03:04 +00:00
|
|
|
const Context & context, bool save_unneeded_columns)
|
2018-07-04 17:02:47 +00:00
|
|
|
{
|
|
|
|
if (column_defaults.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
ASTPtr default_expr_list = requiredExpressions(block, required_columns, column_defaults);
|
2018-11-15 16:57:20 +00:00
|
|
|
if (!default_expr_list)
|
2017-04-01 07:20:54 +00:00
|
|
|
return;
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2018-12-04 20:03:04 +00:00
|
|
|
if (!save_unneeded_columns)
|
2018-11-15 16:57:20 +00:00
|
|
|
{
|
|
|
|
auto syntax_result = SyntaxAnalyzer(context, {}).analyze(default_expr_list, block.getNamesAndTypesList());
|
|
|
|
ExpressionAnalyzer{default_expr_list, syntax_result, context}.getActions(true)->execute(block);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/** ExpressionAnalyzer eliminates "unused" columns, in order to ensure their safety
|
|
|
|
* we are going to operate on a copy instead of the original block */
|
|
|
|
Block copy_block{block};
|
2016-08-15 19:41:44 +00:00
|
|
|
|
2018-11-15 16:57:20 +00:00
|
|
|
auto syntax_result = SyntaxAnalyzer(context, {}).analyze(default_expr_list, block.getNamesAndTypesList());
|
2018-11-08 17:28:52 +00:00
|
|
|
ExpressionAnalyzer{default_expr_list, syntax_result, context}.getActions(true)->execute(copy_block);
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// move evaluated columns to the original block, materializing them at the same time
|
2018-09-20 11:16:15 +00:00
|
|
|
size_t pos = 0;
|
|
|
|
for (auto col = required_columns.begin(); col != required_columns.end(); ++col, ++pos)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2018-09-20 11:16:15 +00:00
|
|
|
if (copy_block.has(col->name))
|
|
|
|
{
|
|
|
|
auto evaluated_col = copy_block.getByName(col->name);
|
2018-12-21 16:00:07 +00:00
|
|
|
evaluated_col.column = evaluated_col.column->convertToFullColumnIfConst();
|
2016-01-13 00:32:59 +00:00
|
|
|
|
2018-09-20 11:16:15 +00:00
|
|
|
block.insert(pos, std::move(evaluated_col));
|
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2016-01-13 00:32:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|