提交 ab1b7257 编写于 作者: A Alexey Milovidov

dbms: less dependencies [#METR-2944].

上级 df780e94
#pragma once
#include <DB/Core/NamesAndTypes.h>
#include <DB/Columns/IColumnDummy.h>
#include <DB/Interpreters/ExpressionActions.h>
namespace DB
{
class ExpressionActions;
/** Столбец, содержащий лямбда-выражение.
* Ведёт себя как столбец-константа. Содержит выражение, но не входные или выходные данные.
*/
class ColumnExpression final : public IColumnDummy
{
public:
ColumnExpression(size_t s_, ExpressionActionsPtr expression_, const NamesAndTypes & arguments_, DataTypePtr return_type_, std::string return_name_)
: IColumnDummy(s_), expression(expression_), arguments(arguments_), return_type(return_type_), return_name(return_name_) {}
ColumnExpression(size_t s_, ExpressionActionsPtr expression_, const NamesAndTypesList & arguments_, DataTypePtr return_type_, std::string return_name_)
: IColumnDummy(s_), expression(expression_), arguments(arguments_.begin(), arguments_.end()), return_type(return_type_), return_name(return_name_) {}
std::string getName() const override { return "ColumnExpression"; }
ColumnPtr cloneDummy(size_t s_) const override { return new ColumnExpression(s_, expression, arguments, return_type, return_name); }
private:
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
const ExpressionActionsPtr & getExpression() const { return expression; }
const DataTypePtr & getReturnType() const { return return_type; }
const std::string & getReturnName() const { return return_name; }
public:
ColumnExpression(size_t s_, ExpressionActionsPtr expression_, const NamesAndTypes & arguments_, DataTypePtr return_type_, String return_name_);
ColumnExpression(size_t s_, ExpressionActionsPtr expression_, const NamesAndTypesList & arguments_, DataTypePtr return_type_, String return_name_);
const NamesAndTypes & getArguments() const { return arguments; }
std::string getName() const override;
ColumnPtr cloneDummy(size_t s_) const override;
Names getArgumentNames() const
{
Names res(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i)
res[i] = arguments[i].name;
return res;
}
const ExpressionActionsPtr & getExpression() const;
const DataTypePtr & getReturnType() const;
const std::string & getReturnName() const;
const NamesAndTypes & getArguments() const;
Names getArgumentNames() const;
private:
ExpressionActionsPtr expression;
......
......@@ -7,6 +7,13 @@
namespace DB
{
namespace ErrorCodes
{
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
extern const int NOT_IMPLEMENTED;
}
/** Базовый класс для столбцов-констант, содержащих значение, не входящее в Field.
* Не является полноценым столбцом и используется особым образом.
*/
......
#pragma once
#include <Poco/SharedPtr.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/DataStreams/IProfilingBlockInputStream.h>
namespace DB
{
using Poco::SharedPtr;
class ExpressionActions;
/** Выполняет над блоком вычисление некоторого выражения.
* Выражение состоит из идентификаторов столбцов из блока, констант, обычных функций.
......@@ -19,44 +15,18 @@ using Poco::SharedPtr;
*/
class ExpressionBlockInputStream : public IProfilingBlockInputStream
{
public:
ExpressionBlockInputStream(BlockInputStreamPtr input_, ExpressionActionsPtr expression_)
: expression(expression_)
{
children.push_back(input_);
}
String getName() const override { return "Expression"; }
String getID() const override
{
std::stringstream res;
res << "Expression(" << children.back()->getID() << ", " << expression->getID() << ")";
return res.str();
}
private:
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
const Block & getTotals() override
{
if (IProfilingBlockInputStream * child = dynamic_cast<IProfilingBlockInputStream *>(&*children.back()))
{
totals = child->getTotals();
expression->executeOnTotals(totals);
}
public:
ExpressionBlockInputStream(BlockInputStreamPtr input_, ExpressionActionsPtr expression_);
return totals;
}
String getName() const override;
String getID() const override;
const Block & getTotals() override;
protected:
Block readImpl() override
{
Block res = children.back()->read();
if (!res)
return res;
expression->execute(res);
return res;
}
Block readImpl() override;
private:
ExpressionActionsPtr expression;
......
#pragma once
#include <DB/Interpreters/Aggregator.h>
#include <DB/DataStreams/IProfilingBlockInputStream.h>
#include <DB/Interpreters/ExpressionActions.h>
namespace DB
{
using Poco::SharedPtr;
class ExpressionActions;
/** Принимает блоки после группировки, с нефиализированными агрегатными функциями.
......@@ -17,26 +15,18 @@ using Poco::SharedPtr;
*/
class TotalsHavingBlockInputStream : public IProfilingBlockInputStream
{
private:
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
public:
TotalsHavingBlockInputStream(BlockInputStreamPtr input_, const Names & keys_names_,
const AggregateDescriptions & aggregates_, bool overflow_row_, ExpressionActionsPtr expression_,
const std::string & filter_column_, TotalsMode totals_mode_, double auto_include_threshold_)
: overflow_row(overflow_row_),
expression(expression_), filter_column_name(filter_column_), totals_mode(totals_mode_),
auto_include_threshold(auto_include_threshold_)
{
children.push_back(input_);
}
TotalsHavingBlockInputStream(
BlockInputStreamPtr input_,
bool overflow_row_, ExpressionActionsPtr expression_,
const std::string & filter_column_, TotalsMode totals_mode_, double auto_include_threshold_);
String getName() const override { return "TotalsHaving"; }
String getID() const override
{
std::stringstream res;
res << "TotalsHavingBlockInputStream(" << children.back()->getID()
<< "," << filter_column_name << ")";
return res.str();
}
String getID() const override;
const Block & getTotals() override;
......
#pragma once
#include <ext/enumerate.hpp>
#include <ext/collection_cast.hpp>
#include <ext/range.hpp>
#include <type_traits>
#include <DB/IO/WriteBufferFromVector.h>
#include <DB/IO/ReadBufferFromString.h>
#include <DB/DataTypes/DataTypeFactory.h>
......@@ -9,19 +14,15 @@
#include <DB/DataTypes/DataTypeDate.h>
#include <DB/DataTypes/DataTypeDateTime.h>
#include <DB/DataTypes/DataTypeEnum.h>
#include <DB/DataTypes/DataTypeArray.h>
#include <DB/DataTypes/DataTypeTuple.h>
#include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnFixedString.h>
#include <DB/Columns/ColumnConst.h>
#include <DB/Functions/IFunction.h>
#include <DB/Columns/ColumnArray.h>
#include <DB/Core/FieldVisitors.h>
#include <ext/range.hpp>
#include <type_traits>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/DataTypes/DataTypeArray.h>
#include <DB/Columns/ColumnArray.h>
#include <DB/DataTypes/DataTypeTuple.h>
#include <ext/enumerate.hpp>
#include <ext/collection_cast.hpp>
#include <DB/Functions/IFunction.h>
#include <DB/Functions/FunctionsMiscellaneous.h>
......@@ -49,7 +50,8 @@ struct ConvertImpl
static void execute(Block & block, const ColumnNumbers & arguments, size_t result)
{
if (const ColumnVector<FromFieldType> * col_from = typeid_cast<const ColumnVector<FromFieldType> *>(&*block.getByPosition(arguments[0]).column))
if (const ColumnVector<FromFieldType> * col_from
= typeid_cast<const ColumnVector<FromFieldType> *>(&*block.getByPosition(arguments[0]).column))
{
ColumnVector<ToFieldType> * col_to = new ColumnVector<ToFieldType>;
block.getByPosition(result).column = col_to;
......
......@@ -267,7 +267,7 @@ private:
void optimizeArrayJoin();
};
typedef SharedPtr<ExpressionActions> ExpressionActionsPtr;
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
/** Последовательность преобразований над блоком.
......
......@@ -7,7 +7,6 @@
#include <DB/Interpreters/Context.h>
#include <DB/Interpreters/AggregateDescription.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Interpreters/Set.h>
#include <DB/Interpreters/Join.h>
......@@ -16,6 +15,10 @@ namespace DB
{
class ExpressionActions;
struct ExpressionActionsChain;
/** Информация о том, что делать при выполнении подзапроса в секции [GLOBAL] IN/JOIN.
*/
struct SubqueryForSet
......@@ -36,7 +39,7 @@ struct SubqueryForSet
};
/// ID подзапроса -> что с ним делать.
typedef std::unordered_map<String, SubqueryForSet> SubqueriesForSets;
using SubqueriesForSets = std::unordered_map<String, SubqueryForSet>;
/** Превращает выражение из синтаксического дерева в последовательность действий для его выполнения.
......@@ -45,6 +48,9 @@ typedef std::unordered_map<String, SubqueryForSet> SubqueriesForSets;
*/
class ExpressionAnalyzer : private boost::noncopyable
{
private:
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
public:
ExpressionAnalyzer(
const ASTPtr & ast_,
......
#pragma once
#include <DB/Core/Block.h>
#include <DB/Storages/ColumnDefault.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <utility>
#include <unordered_map>
namespace DB
{
inline void evaluateMissingDefaults(Block & block,
const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context)
namespace DB
{
if (column_defaults.empty())
return;
ASTPtr default_expr_list{std::make_unique<ASTExpressionList>().release()};
for (const auto & column : required_columns)
{
if (block.has(column.name))
continue;
const auto it = column_defaults.find(column.name);
class Block;
class Context;
class NamesAndTypesList;
struct ColumnDefault;
/// 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));
}
/// 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{block};
/// 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, materializing them at the same time
for (auto & column_name_type : copy_block.getColumns())
{
if (auto converted = column_name_type.column->convertToFullColumnIfConst())
column_name_type.column = converted;
block.insert(std::move(column_name_type));
}
}
void evaluateMissingDefaults(Block & block,
const NamesAndTypesList & required_columns,
const std::unordered_map<String, ColumnDefault> & column_defaults,
const Context & context);
}
#pragma once
#include <DB/Interpreters/Context.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/DataTypes/DataTypeString.h>
#include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTLiteral.h>
#include <Poco/SharedPtr.h>
namespace DB
{
namespace
{
ASTPtr reinterpretAsIdentifierImpl(const ASTPtr & expr, const Context & context)
{
/// for string literal return its value
if (const auto literal = typeid_cast<const ASTLiteral *>(expr.get()))
return new ASTIdentifier{{}, safeGet<const String &>(literal->value)};
/// otherwise evaluate the expression
Block block{};
/** pass a dummy column name because ExpressionAnalyzer
* does not work with no columns so far. */
ExpressionAnalyzer{
expr, context, {},
{ { "", new DataTypeString } }
}.getActions(false)->execute(block);
class IAST;
class ASTIdentifier;
class Context;
const auto & column_name_type = block.getByName(expr->getColumnName());
/** \brief if `expr` is not already ASTIdentifier evaluates it
* and replaces by a new ASTIdentifier with the result of evaluation as its name.
* `expr` must evaluate to a String type */
ASTIdentifier & reinterpretAsIdentifier(Poco::SharedPtr<IAST> & expr, const Context & context);
/// ensure the result of evaluation has String type
if (!typeid_cast<const DataTypeString *>(column_name_type.type.get()))
throw Exception{"Expression must evaluate to a String"};
return new ASTIdentifier{{}, column_name_type.column->getDataAt(0).toString()};
}
}
/** \brief if `expr` is not already ASTIdentifier evaluates it
* and replaces by a new ASTIdentifier with the result of evaluation as its name.
* `expr` must evaluate to a String type */
inline ASTIdentifier & reinterpretAsIdentifier(ASTPtr & expr, const Context & context)
{
/// for identifier just return its name
if (!typeid_cast<const ASTIdentifier *>(expr.get()))
expr = reinterpretAsIdentifierImpl(expr, context);
return static_cast<ASTIdentifier &>(*expr);
}
}
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Columns/ColumnExpression.h>
namespace DB
{
ColumnExpression::ColumnExpression(
size_t s_, ExpressionActionsPtr expression_, const NamesAndTypes & arguments_, DataTypePtr return_type_, std::string return_name_)
: IColumnDummy(s_), expression(expression_), arguments(arguments_), return_type(return_type_), return_name(return_name_)
{
}
ColumnExpression::ColumnExpression(
size_t s_, ExpressionActionsPtr expression_, const NamesAndTypesList & arguments_, DataTypePtr return_type_, std::string return_name_)
: IColumnDummy(s_), expression(expression_), arguments(arguments_.begin(), arguments_.end()), return_type(return_type_), return_name(return_name_)
{
}
std::string ColumnExpression::getName() const
{
return "ColumnExpression";
}
ColumnPtr ColumnExpression::cloneDummy(size_t s_) const
{
return new ColumnExpression(s_, expression, arguments, return_type, return_name);
}
const ExpressionActionsPtr & ColumnExpression::getExpression() const { return expression; }
const DataTypePtr & ColumnExpression::getReturnType() const { return return_type; }
const std::string & ColumnExpression::getReturnName() const { return return_name; }
const NamesAndTypes & ColumnExpression::getArguments() const { return arguments; }
Names ColumnExpression::getArgumentNames() const
{
Names res(arguments.size());
for (size_t i = 0; i < arguments.size(); ++i)
res[i] = arguments[i].name;
return res;
}
}
#include <DB/Interpreters/Context.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTExpressionList.h>
#include <DB/Parsers/ASTLiteral.h>
......
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/DataStreams/ExpressionBlockInputStream.h>
namespace DB
{
ExpressionBlockInputStream::ExpressionBlockInputStream(BlockInputStreamPtr input_, ExpressionActionsPtr expression_)
: expression(expression_)
{
children.push_back(input_);
}
String ExpressionBlockInputStream::getName() const { return "Expression"; }
String ExpressionBlockInputStream::getID() const
{
std::stringstream res;
res << "Expression(" << children.back()->getID() << ", " << expression->getID() << ")";
return res.str();
}
const Block & ExpressionBlockInputStream::getTotals()
{
if (IProfilingBlockInputStream * child = dynamic_cast<IProfilingBlockInputStream *>(&*children.back()))
{
totals = child->getTotals();
expression->executeOnTotals(totals);
}
return totals;
}
Block ExpressionBlockInputStream::readImpl()
{
Block res = children.back()->read();
if (!res)
return res;
expression->execute(res);
return res;
}
}
#include <sys/ioctl.h>
#include <unistd.h>
#include <DB/Functions/FunctionsMiscellaneous.h>
#include <DB/DataStreams/PrettyCompactBlockOutputStream.h>
......
#include <sys/ioctl.h>
#include <unistd.h>
#include <DB/Functions/FunctionsMiscellaneous.h>
#include <DB/DataStreams/PrettyCompactMonoBlockOutputStream.h>
......@@ -13,7 +11,7 @@ void PrettyCompactMonoBlockOutputStream::write(const Block & block)
{
if (total_rows < max_rows)
blocks.push_back(block);
total_rows += block.rows();
}
......@@ -21,22 +19,22 @@ void PrettyCompactMonoBlockOutputStream::writeSuffix()
{
if (blocks.empty())
return;
Widths_t max_widths;
Widths_t name_widths;
for (size_t i = 0; i < blocks.size(); ++i)
calculateWidths(blocks[i], max_widths, name_widths);
writeHeader(blocks.front(), max_widths, name_widths);
size_t row_count = 0;
for (size_t block_id = 0; block_id < blocks.size() && row_count < max_rows; ++block_id)
{
const Block & block = blocks[block_id];
size_t rows = block.rows();
for (size_t i = 0; i < rows && row_count < max_rows; ++i)
{
writeRow(i, block, max_widths, name_widths);
......
#include <sys/ioctl.h>
#include <unistd.h>
#include <DB/Functions/FunctionsMiscellaneous.h>
#include <DB/DataStreams/PrettySpaceBlockOutputStream.h>
......
#include <DB/DataStreams/TotalsHavingBlockInputStream.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Interpreters/AggregateDescription.h>
#include <DB/Columns/ColumnAggregateFunction.h>
#include <DB/Columns/ColumnsNumber.h>
......@@ -12,6 +14,27 @@ namespace ErrorCodes
}
TotalsHavingBlockInputStream::TotalsHavingBlockInputStream(
BlockInputStreamPtr input_,
bool overflow_row_, ExpressionActionsPtr expression_,
const std::string & filter_column_, TotalsMode totals_mode_, double auto_include_threshold_)
: overflow_row(overflow_row_),
expression(expression_), filter_column_name(filter_column_), totals_mode(totals_mode_),
auto_include_threshold(auto_include_threshold_)
{
children.push_back(input_);
}
String TotalsHavingBlockInputStream::getID() const
{
std::stringstream res;
res << "TotalsHavingBlockInputStream(" << children.back()->getID()
<< "," << filter_column_name << ")";
return res.str();
}
static void finalize(Block & block)
{
for (size_t i = 0; i < block.columns(); ++i)
......
......@@ -1013,7 +1013,7 @@ void ExpressionActionsChain::addStep()
throw Exception("Cannot add action to empty ExpressionActionsChain", ErrorCodes::LOGICAL_ERROR);
ColumnsWithTypeAndName columns = steps.back().actions->getSampleBlock().getColumns();
steps.push_back(Step(new ExpressionActions(columns, settings)));
steps.push_back(Step(std::make_shared<ExpressionActions>(columns, settings)));
}
void ExpressionActionsChain::finalize()
......
......@@ -22,6 +22,7 @@
#include <DB/Interpreters/InterpreterSelectQuery.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Interpreters/InJoinSubqueriesPreprocessor.h>
#include <DB/Interpreters/LogicalExpressionsOptimizer.h>
#include <DB/Interpreters/ExternalDictionaries.h>
......@@ -186,7 +187,7 @@ void ExpressionAnalyzer::analyzeAggregation()
if (select_query && (select_query->group_expression_list || select_query->having_expression))
has_aggregation = true;
ExpressionActionsPtr temp_actions = new ExpressionActions(columns, settings);
ExpressionActionsPtr temp_actions = std::make_shared<ExpressionActions>(columns, settings);
if (select_query && select_query->array_join_expression_list)
{
......@@ -1364,7 +1365,7 @@ struct ExpressionAnalyzer::ScopeStack
all_columns.push_back(col);
}
stack.back().actions = new ExpressionActions(all_columns, settings);
stack.back().actions = std::make_shared<ExpressionActions>(all_columns, settings);
}
size_t getColumnLevel(const std::string & name)
......@@ -1855,7 +1856,7 @@ void ExpressionAnalyzer::initChain(ExpressionActionsChain & chain, const NamesAn
if (chain.steps.empty())
{
chain.settings = settings;
chain.steps.emplace_back(new ExpressionActions(columns, settings));
chain.steps.emplace_back(std::make_shared<ExpressionActions>(columns, settings));
}
}
......@@ -2115,7 +2116,7 @@ Block ExpressionAnalyzer::getSelectSampleBlock()
{
assertSelect();
ExpressionActionsPtr temp_actions = new ExpressionActions(aggregated_columns, settings);
ExpressionActionsPtr temp_actions = std::make_shared<ExpressionActions>(aggregated_columns, settings);
NamesWithAliases result_columns;
ASTs asts = select_query->select_expression_list->children;
......@@ -2145,7 +2146,7 @@ void ExpressionAnalyzer::getActionsBeforeAggregation(ASTPtr ast, ExpressionActio
ExpressionActionsPtr ExpressionAnalyzer::getActions(bool project_result)
{
ExpressionActionsPtr actions = new ExpressionActions(columns, settings);
ExpressionActionsPtr actions = std::make_shared<ExpressionActions>(columns, settings);
NamesWithAliases result_columns;
Names result_names;
......@@ -2188,7 +2189,7 @@ ExpressionActionsPtr ExpressionAnalyzer::getActions(bool project_result)
ExpressionActionsPtr ExpressionAnalyzer::getConstActions()
{
ExpressionActionsPtr actions = new ExpressionActions(NamesAndTypesList(), settings);
ExpressionActionsPtr actions = std::make_shared<ExpressionActions>(NamesAndTypesList(), settings);
getRootActions(ast, true, true, actions);
......
......@@ -972,11 +972,8 @@ void InterpreterSelectQuery::executeTotalsAndHaving(bool has_having, ExpressionA
{
executeUnion();
Names key_names;
AggregateDescriptions aggregates;
query_analyzer->getAggregateInfo(key_names, aggregates);
streams[0] = new TotalsHavingBlockInputStream(
streams[0], key_names, aggregates, overflow_row, expression,
streams[0], overflow_row, expression,
has_having ? query.having_expression->getColumnName() : "", settings.totals_mode, settings.totals_auto_threshold);
}
......
#include <DB/Core/Block.h>
#include <DB/Storages/ColumnDefault.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Interpreters/evaluateMissingDefaults.h>
#include <utility>
namespace DB
{
void evaluateMissingDefaults(Block & block,
const NamesAndTypesList & required_columns,
const ColumnDefaults & column_defaults,
const Context & context)
{
if (column_defaults.empty())
return;
ASTPtr default_expr_list{std::make_unique<ASTExpressionList>().release()};
for (const auto & column : required_columns)
{
if (block.has(column.name))
continue;
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(
setAlias(it->second.expression->clone(), it->first));
}
/// 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{block};
/// 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, materializing them at the same time
for (auto & column_name_type : copy_block.getColumns())
{
if (auto converted = column_name_type.column->convertToFullColumnIfConst())
column_name_type.column = converted;
block.insert(std::move(column_name_type));
}
}
}
#include <DB/Interpreters/Context.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Interpreters/reinterpretAsIdentifier.h>
#include <DB/DataTypes/DataTypeString.h>
#include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTLiteral.h>
namespace DB
{
namespace
{
ASTPtr reinterpretAsIdentifierImpl(const ASTPtr & expr, const Context & context)
{
/// for string literal return its value
if (const auto literal = typeid_cast<const ASTLiteral *>(expr.get()))
return new ASTIdentifier{{}, safeGet<const String &>(literal->value)};
/// otherwise evaluate the expression
Block block{};
/** pass a dummy column name because ExpressionAnalyzer
* does not work with no columns so far. */
ExpressionAnalyzer{
expr, context, {},
{ { "", new DataTypeString } }
}.getActions(false)->execute(block);
const auto & column_name_type = block.getByName(expr->getColumnName());
/// ensure the result of evaluation has String type
if (!typeid_cast<const DataTypeString *>(column_name_type.type.get()))
throw Exception{"Expression must evaluate to a String"};
return new ASTIdentifier{{}, column_name_type.column->getDataAt(0).toString()};
}
}
ASTIdentifier & reinterpretAsIdentifier(ASTPtr & expr, const Context & context)
{
/// for identifier just return its name
if (!typeid_cast<const ASTIdentifier *>(expr.get()))
expr = reinterpretAsIdentifierImpl(expr, context);
return static_cast<ASTIdentifier &>(*expr);
}
}
......@@ -4,6 +4,7 @@
#include <DB/DataTypes/DataTypeNested.h>
#include <DB/Interpreters/Context.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Parsers/ASTIdentifier.h>
......
......@@ -508,7 +508,7 @@ void MergeTreeData::createConvertExpression(const DataPartPtr & part, const Name
/// Нужно изменить тип столбца.
if (!out_expression)
out_expression = new ExpressionActions(NamesAndTypesList(), context.getSettingsRef());
out_expression = std::make_shared<ExpressionActions>(NamesAndTypesList(), context.getSettingsRef());
out_expression->addInput(ColumnWithTypeAndName(nullptr, column.type, column.name));
......
#include <DB/Storages/MergeTree/PKCondition.h>
#include <DB/DataTypes/DataTypesNumberFixed.h>
#include <DB/Interpreters/ExpressionAnalyzer.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/Columns/ColumnSet.h>
#include <DB/Columns/ColumnTuple.h>
#include <DB/Parsers/ASTSet.h>
......
......@@ -3,11 +3,14 @@
#include <DB/Storages/StorageChunkRef.h>
#include <DB/Interpreters/executeQuery.h>
#include <DB/Interpreters/InterpreterDropQuery.h>
#include <DB/Interpreters/ExpressionActions.h>
#include <DB/DataStreams/ConcatBlockInputStream.h>
#include <DB/DataStreams/AddingDefaultBlockInputStream.h>
#include <DB/DataStreams/AddingConstColumnBlockInputStream.h>
#include <DB/DataStreams/narrowBlockInputStreams.h>
#include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/ASTSelectQuery.h>
#include <DB/Parsers/ASTExpressionList.h>
#include <DB/Parsers/formatAST.h>
#include <DB/Common/VirtualColumnUtils.h>
#include <DB/DataTypes/DataTypeString.h>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册