mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-05 14:02:21 +00:00
495c6e03aa
* Replace all Context references with std::weak_ptr * Fix shared context captured by value * Fix build * Fix Context with named sessions * Fix copy context * Fix gcc build * Merge with master and fix build * Fix gcc-9 build
132 lines
4.2 KiB
C++
132 lines
4.2 KiB
C++
#include <Storages/KeyDescription.h>
|
|
|
|
#include <Functions/IFunction.h>
|
|
#include <Parsers/ASTIdentifier.h>
|
|
#include <Interpreters/ExpressionActions.h>
|
|
#include <Interpreters/ExpressionAnalyzer.h>
|
|
#include <Interpreters/TreeRewriter.h>
|
|
#include <Storages/extractKeyExpressionList.h>
|
|
#include <Common/quoteString.h>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
{
|
|
extern const int LOGICAL_ERROR;
|
|
extern const int DATA_TYPE_CANNOT_BE_USED_IN_KEY;
|
|
}
|
|
|
|
KeyDescription::KeyDescription(const KeyDescription & other)
|
|
: definition_ast(other.definition_ast ? other.definition_ast->clone() : nullptr)
|
|
, expression_list_ast(other.expression_list_ast ? other.expression_list_ast->clone() : nullptr)
|
|
, sample_block(other.sample_block)
|
|
, column_names(other.column_names)
|
|
, data_types(other.data_types)
|
|
, additional_column(other.additional_column)
|
|
{
|
|
if (other.expression)
|
|
expression = other.expression->clone();
|
|
}
|
|
|
|
KeyDescription & KeyDescription::operator=(const KeyDescription & other)
|
|
{
|
|
if (&other == this)
|
|
return *this;
|
|
|
|
if (other.definition_ast)
|
|
definition_ast = other.definition_ast->clone();
|
|
else
|
|
definition_ast.reset();
|
|
|
|
if (other.expression_list_ast)
|
|
expression_list_ast = other.expression_list_ast->clone();
|
|
else
|
|
expression_list_ast.reset();
|
|
|
|
|
|
if (other.expression)
|
|
expression = other.expression->clone();
|
|
else
|
|
expression.reset();
|
|
|
|
sample_block = other.sample_block;
|
|
column_names = other.column_names;
|
|
data_types = other.data_types;
|
|
|
|
/// additional_column is constant property It should never be lost.
|
|
if (additional_column.has_value() && !other.additional_column.has_value())
|
|
throw Exception("Wrong key assignment, losing additional_column", ErrorCodes::LOGICAL_ERROR);
|
|
additional_column = other.additional_column;
|
|
return *this;
|
|
}
|
|
|
|
|
|
void KeyDescription::recalculateWithNewAST(
|
|
const ASTPtr & new_ast,
|
|
const ColumnsDescription & columns,
|
|
ContextPtr context)
|
|
{
|
|
*this = getSortingKeyFromAST(new_ast, columns, context, additional_column);
|
|
}
|
|
|
|
void KeyDescription::recalculateWithNewColumns(
|
|
const ColumnsDescription & new_columns,
|
|
ContextPtr context)
|
|
{
|
|
*this = getSortingKeyFromAST(definition_ast, new_columns, context, additional_column);
|
|
}
|
|
|
|
KeyDescription KeyDescription::getKeyFromAST(
|
|
const ASTPtr & definition_ast,
|
|
const ColumnsDescription & columns,
|
|
ContextPtr context)
|
|
{
|
|
return getSortingKeyFromAST(definition_ast, columns, context, {});
|
|
}
|
|
|
|
KeyDescription KeyDescription::getSortingKeyFromAST(
|
|
const ASTPtr & definition_ast,
|
|
const ColumnsDescription & columns,
|
|
ContextPtr context,
|
|
const std::optional<String> & additional_column)
|
|
{
|
|
KeyDescription result;
|
|
result.definition_ast = definition_ast;
|
|
result.expression_list_ast = extractKeyExpressionList(definition_ast);
|
|
|
|
if (additional_column)
|
|
{
|
|
result.additional_column = additional_column;
|
|
ASTPtr column_identifier = std::make_shared<ASTIdentifier>(*additional_column);
|
|
result.expression_list_ast->children.push_back(column_identifier);
|
|
}
|
|
|
|
const auto & children = result.expression_list_ast->children;
|
|
for (const auto & child : children)
|
|
result.column_names.emplace_back(child->getColumnName());
|
|
|
|
{
|
|
auto expr = result.expression_list_ast->clone();
|
|
auto syntax_result = TreeRewriter(context).analyze(expr, columns.getAllPhysical());
|
|
/// In expression we also need to store source columns
|
|
result.expression = ExpressionAnalyzer(expr, syntax_result, context).getActions(false);
|
|
/// In sample block we use just key columns
|
|
result.sample_block = ExpressionAnalyzer(expr, syntax_result, context).getActions(true)->getSampleBlock();
|
|
}
|
|
|
|
for (size_t i = 0; i < result.sample_block.columns(); ++i)
|
|
{
|
|
result.data_types.emplace_back(result.sample_block.getByPosition(i).type);
|
|
if (!result.data_types.back()->isComparable())
|
|
throw Exception(ErrorCodes::DATA_TYPE_CANNOT_BE_USED_IN_KEY,
|
|
"Column {} with type {} is not allowed in key expression, it's not comparable",
|
|
backQuote(result.sample_block.getByPosition(i).name), result.data_types.back()->getName());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|