dbms: chaining support for defaulted columns when corresponding columns files are absent. [#METR-12739]

This commit is contained in:
Andrey Mironov 2014-10-17 16:26:53 +04:00
parent 1dfcaefc64
commit 8a8e5963c5
4 changed files with 44 additions and 10 deletions

View File

@ -68,8 +68,10 @@ public:
void addDefaults(const NamesAndTypesList & required_columns);
void addDefaults(const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context,
bool only_explicitly_defaulted = false);
const Context & context);
void addAllDefaults(const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context);
ColumnWithNameAndType & getByPosition(size_t position);
const ColumnWithNameAndType & getByPosition(size_t position) const;

View File

@ -161,6 +161,7 @@ public:
size_t pos = 0; /// Позиция, куда надо вставить недостающий столбец.
for (NamesAndTypesList::const_iterator it = columns.begin(); it != columns.end(); ++it, ++pos)
{
/// insert default values only for columns without default expressions
if (!res.has(it->name) && storage.column_defaults.count(it->name) == 0)
{
ColumnWithNameAndType column;
@ -193,8 +194,8 @@ public:
}
}
/// evaluate defaulted values
res.addDefaults(columns, storage.column_defaults, storage.context, true);
/// evaluate defaulted columns
res.addAllDefaults(columns, storage.column_defaults, storage.context);
}
catch (const Exception & e)
{

View File

@ -34,8 +34,7 @@ void Block::addDefaults(const NamesAndTypesList & required_columns)
void Block::addDefaults(const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context,
const bool only_explicitly_defaulted)
const Context & context)
{
ASTPtr default_expr_list{stdext::make_unique<ASTExpressionList>().release()};
@ -47,10 +46,10 @@ void Block::addDefaults(const NamesAndTypesList & required_columns,
const auto it = column_defaults.find(column.name);
/// expressions must be cloned to prevent modification by the ExpressionAnalyzer
if (it != column_defaults.end())
default_expr_list->children.emplace_back(it->second.expression->clone());
else if (only_explicitly_defaulted)
if (it == column_defaults.end())
insertDefault(column.name, column.type);
else
default_expr_list->children.emplace_back(it->second.expression->clone());
}
/// nothing to evaluate
@ -68,6 +67,38 @@ void Block::addDefaults(const NamesAndTypesList & required_columns,
insert(std::move(column_name_type));
}
void Block::addAllDefaults(const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context)
{
ASTPtr default_expr_list{stdext::make_unique<ASTExpressionList>().release()};
for (const auto & column_default : column_defaults)
{
if (has(column_default.first))
continue;
/// expressions must be cloned to prevent modification by the ExpressionAnalyzer
default_expr_list->children.emplace_back(column_default.second.expression->clone());
}
/// nothing to evaluate
if (default_expr_list->children.empty())
return;
/** 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{*this};
/// evaluate default values for defaulted columns
ExpressionAnalyzer{default_expr_list, context, required_columns}.getActions(true)->execute(copy_block);
/// move evaluated columns to the original block only if required
for (auto & column_name_type : required_columns) {
if (copy_block.has(column_name_type.name))
insert(std::move(copy_block.getByName(column_name_type.name)));
}
}
Block & Block::operator= (const Block & other)
{
data = other.data;

View File

@ -123,7 +123,7 @@ namespace DB
column_defaults.erase(column_name);
else if (default_expression && !had_default_expr)
column_defaults.emplace(column_name, ColumnDefault{default_type, default_expression});
else
else if (had_default_expr)
column_defaults[column_name].expression = default_expression;
}
else