2020-05-21 19:07:18 +00:00
|
|
|
#include <Storages/StorageInMemoryMetadata.h>
|
|
|
|
|
2020-05-20 15:16:39 +00:00
|
|
|
#include <Interpreters/ExpressionActions.h>
|
|
|
|
#include <Interpreters/ExpressionAnalyzer.h>
|
|
|
|
#include <Interpreters/SyntaxAnalyzer.h>
|
|
|
|
#include <Parsers/ASTExpressionList.h>
|
|
|
|
#include <Parsers/ASTFunction.h>
|
|
|
|
#include <Parsers/queryToString.h>
|
2020-05-25 17:07:14 +00:00
|
|
|
#include <Parsers/ASTTTLElement.h>
|
|
|
|
#include <Functions/IFunction.h>
|
|
|
|
|
|
|
|
#include <DataTypes/DataTypeDateTime.h>
|
|
|
|
#include <DataTypes/DataTypeDate.h>
|
2020-02-14 13:17:50 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2020-05-21 19:07:18 +00:00
|
|
|
|
2020-05-25 17:07:14 +00:00
|
|
|
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int BAD_TTL_EXPRESSION;
|
2020-05-25 19:18:01 +00:00
|
|
|
extern const int BAD_ARGUMENTS;
|
2020-05-25 17:07:14 +00:00
|
|
|
};
|
|
|
|
|
2020-02-14 13:17:50 +00:00
|
|
|
StorageInMemoryMetadata::StorageInMemoryMetadata(
|
|
|
|
const ColumnsDescription & columns_,
|
|
|
|
const IndicesDescription & indices_,
|
|
|
|
const ConstraintsDescription & constraints_)
|
|
|
|
: columns(columns_)
|
|
|
|
, indices(indices_)
|
|
|
|
, constraints(constraints_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageInMemoryMetadata::StorageInMemoryMetadata(const StorageInMemoryMetadata & other)
|
|
|
|
: columns(other.columns)
|
|
|
|
, indices(other.indices)
|
|
|
|
, constraints(other.constraints)
|
|
|
|
{
|
|
|
|
if (other.partition_by_ast)
|
|
|
|
partition_by_ast = other.partition_by_ast->clone();
|
|
|
|
if (other.order_by_ast)
|
|
|
|
order_by_ast = other.order_by_ast->clone();
|
|
|
|
if (other.primary_key_ast)
|
|
|
|
primary_key_ast = other.primary_key_ast->clone();
|
|
|
|
if (other.ttl_for_table_ast)
|
|
|
|
ttl_for_table_ast = other.ttl_for_table_ast->clone();
|
|
|
|
if (other.sample_by_ast)
|
|
|
|
sample_by_ast = other.sample_by_ast->clone();
|
|
|
|
if (other.settings_ast)
|
|
|
|
settings_ast = other.settings_ast->clone();
|
|
|
|
if (other.select)
|
|
|
|
select = other.select->clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageInMemoryMetadata & StorageInMemoryMetadata::operator=(const StorageInMemoryMetadata & other)
|
|
|
|
{
|
2020-03-18 02:02:24 +00:00
|
|
|
if (this == &other)
|
|
|
|
return *this;
|
|
|
|
|
2020-02-14 13:17:50 +00:00
|
|
|
columns = other.columns;
|
|
|
|
indices = other.indices;
|
|
|
|
constraints = other.constraints;
|
|
|
|
|
|
|
|
if (other.partition_by_ast)
|
|
|
|
partition_by_ast = other.partition_by_ast->clone();
|
|
|
|
else
|
|
|
|
partition_by_ast.reset();
|
|
|
|
|
|
|
|
if (other.order_by_ast)
|
|
|
|
order_by_ast = other.order_by_ast->clone();
|
|
|
|
else
|
|
|
|
order_by_ast.reset();
|
|
|
|
|
|
|
|
if (other.primary_key_ast)
|
|
|
|
primary_key_ast = other.primary_key_ast->clone();
|
|
|
|
else
|
|
|
|
primary_key_ast.reset();
|
|
|
|
|
|
|
|
if (other.ttl_for_table_ast)
|
|
|
|
ttl_for_table_ast = other.ttl_for_table_ast->clone();
|
|
|
|
else
|
|
|
|
ttl_for_table_ast.reset();
|
|
|
|
|
|
|
|
if (other.sample_by_ast)
|
|
|
|
sample_by_ast = other.sample_by_ast->clone();
|
|
|
|
else
|
|
|
|
sample_by_ast.reset();
|
|
|
|
|
|
|
|
if (other.settings_ast)
|
|
|
|
settings_ast = other.settings_ast->clone();
|
|
|
|
else
|
|
|
|
settings_ast.reset();
|
|
|
|
|
|
|
|
if (other.select)
|
|
|
|
select = other.select->clone();
|
|
|
|
else
|
|
|
|
select.reset();
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
2020-05-20 15:16:39 +00:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
ASTPtr extractKeyExpressionList(const ASTPtr & node)
|
|
|
|
{
|
|
|
|
if (!node)
|
|
|
|
return std::make_shared<ASTExpressionList>();
|
|
|
|
|
|
|
|
const auto * expr_func = node->as<ASTFunction>();
|
|
|
|
|
|
|
|
if (expr_func && expr_func->name == "tuple")
|
|
|
|
{
|
|
|
|
/// Primary key is specified in tuple, extract its arguments.
|
|
|
|
return expr_func->arguments->clone();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/// Primary key consists of one column.
|
|
|
|
auto res = std::make_shared<ASTExpressionList>();
|
|
|
|
res->children.push_back(node);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageMetadataKeyField StorageMetadataKeyField::getKeyFromAST(const ASTPtr & definition_ast, const ColumnsDescription & columns, const Context & context)
|
|
|
|
{
|
|
|
|
StorageMetadataKeyField result;
|
|
|
|
result.definition_ast = definition_ast;
|
2020-05-21 19:46:03 +00:00
|
|
|
result.expression_list_ast = extractKeyExpressionList(definition_ast);
|
2020-05-20 15:16:39 +00:00
|
|
|
|
2020-05-21 19:46:03 +00:00
|
|
|
if (result.expression_list_ast->children.empty())
|
2020-05-20 15:16:39 +00:00
|
|
|
return result;
|
|
|
|
|
2020-05-21 19:46:03 +00:00
|
|
|
const auto & children = result.expression_list_ast->children;
|
2020-05-20 15:16:39 +00:00
|
|
|
for (const auto & child : children)
|
2020-05-21 19:46:03 +00:00
|
|
|
result.column_names.emplace_back(child->getColumnName());
|
2020-05-20 15:16:39 +00:00
|
|
|
|
|
|
|
{
|
2020-05-21 19:46:03 +00:00
|
|
|
auto expr = result.expression_list_ast->clone();
|
|
|
|
auto syntax_result = SyntaxAnalyzer(context).analyze(expr, columns.getAllPhysical());
|
|
|
|
result.expression = ExpressionAnalyzer(expr, syntax_result, context).getActions(true);
|
|
|
|
result.sample_block = result.expression->getSampleBlock();
|
2020-05-20 15:16:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i = 0; i < result.sample_block.columns(); ++i)
|
|
|
|
result.data_types.emplace_back(result.sample_block.getByPosition(i).type);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-05-25 17:07:14 +00:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
void checkTTLExpression(const ExpressionActionsPtr & ttl_expression, const String & result_column_name)
|
|
|
|
{
|
|
|
|
for (const auto & action : ttl_expression->getActions())
|
|
|
|
{
|
|
|
|
if (action.type == ExpressionAction::APPLY_FUNCTION)
|
|
|
|
{
|
|
|
|
IFunctionBase & func = *action.function_base;
|
|
|
|
if (!func.isDeterministic())
|
|
|
|
throw Exception(
|
|
|
|
"TTL expression cannot contain non-deterministic functions, "
|
|
|
|
"but contains function "
|
|
|
|
+ func.getName(),
|
|
|
|
ErrorCodes::BAD_ARGUMENTS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto & result_column = ttl_expression->getSampleBlock().getByName(result_column_name);
|
|
|
|
|
|
|
|
if (!typeid_cast<const DataTypeDateTime *>(result_column.type.get())
|
|
|
|
&& !typeid_cast<const DataTypeDate *>(result_column.type.get()))
|
|
|
|
{
|
|
|
|
throw Exception(
|
|
|
|
"TTL expression result column should have DateTime or Date type, but has " + result_column.type->getName(),
|
|
|
|
ErrorCodes::BAD_TTL_EXPRESSION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageMetadataTTLField StorageMetadataTTLField::getTTLFromAST(const ASTPtr & definition_ast, const ColumnsDescription & columns, const Context & context)
|
|
|
|
{
|
|
|
|
StorageMetadataTTLField result;
|
|
|
|
const auto * ttl_element = definition_ast->as<ASTTTLElement>();
|
|
|
|
|
2020-05-25 17:57:08 +00:00
|
|
|
/// First child is expression: `TTL expr TO DISK`
|
2020-05-25 17:07:14 +00:00
|
|
|
if (ttl_element != nullptr)
|
2020-05-25 17:57:08 +00:00
|
|
|
result.expression_ast = ttl_element->children.front()->clone();
|
|
|
|
else /// It's columns TTL without any additions, just copy it
|
|
|
|
result.expression_ast = definition_ast->clone();
|
2020-05-25 17:07:14 +00:00
|
|
|
|
2020-05-25 17:57:08 +00:00
|
|
|
auto ttl_ast = result.expression_ast->clone();
|
2020-05-25 17:07:14 +00:00
|
|
|
auto syntax_result = SyntaxAnalyzer(context).analyze(ttl_ast, columns.getAllPhysical());
|
|
|
|
result.expression = ExpressionAnalyzer(ttl_ast, syntax_result, context).getActions(false);
|
|
|
|
|
2020-05-25 17:57:08 +00:00
|
|
|
/// Move TTL to disk or volume
|
2020-05-25 17:07:14 +00:00
|
|
|
if (ttl_element != nullptr)
|
|
|
|
{
|
|
|
|
result.destination_type = ttl_element->destination_type;
|
|
|
|
result.destination_name = ttl_element->destination_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
result.result_column = ttl_ast->getColumnName();
|
|
|
|
|
|
|
|
checkTTLExpression(result.expression, result.result_column);
|
|
|
|
return result;
|
|
|
|
}
|
2020-02-14 13:17:50 +00:00
|
|
|
}
|