ClickHouse/src/Interpreters/InterpreterOptimizeQuery.cpp

80 lines
3.0 KiB
C++
Raw Normal View History

#include <Storages/IStorage.h>
#include <Parsers/ASTOptimizeQuery.h>
2017-05-23 18:24:43 +00:00
#include <Interpreters/Context.h>
#include <Interpreters/DDLWorker.h>
#include <Interpreters/InterpreterOptimizeQuery.h>
#include <Access/AccessRightsElement.h>
2017-07-13 20:58:19 +00:00
#include <Common/typeid_cast.h>
#include <Parsers/ASTExpressionList.h>
2016-12-12 07:24:56 +00:00
#include <Interpreters/processColumnTransformers.h>
#include <memory>
2016-12-12 07:24:56 +00:00
namespace DB
{
2017-04-08 01:32:05 +00:00
namespace ErrorCodes
{
extern const int THERE_IS_NO_COLUMN;
2017-04-08 01:32:05 +00:00
}
2016-12-12 07:24:56 +00:00
BlockIO InterpreterOptimizeQuery::execute()
{
const auto & ast = query_ptr->as<ASTOptimizeQuery &>();
2016-12-12 07:24:56 +00:00
if (!ast.cluster.empty())
2020-01-24 16:20:36 +00:00
return executeDDLQueryOnCluster(query_ptr, context, getRequiredAccess());
context.checkAccess(getRequiredAccess());
2020-03-13 10:30:55 +00:00
auto table_id = context.resolveStorageID(ast, Context::ResolveOrdinary);
2020-05-28 23:01:18 +00:00
StoragePtr table = DatabaseCatalog::instance().getTable(table_id, context);
2020-06-17 13:39:26 +00:00
auto metadata_snapshot = table->getInMemoryMetadataPtr();
// Empty list of names means we deduplicate by all columns, but user can explicitly state which columns to use.
Names column_names;
if (ast.deduplicate_by_columns)
{
// User requested custom set of columns for deduplication, possibly with Column Transformer expression.
{
// Expand asterisk, column transformers, etc into list of column names.
const auto cols = processColumnTransformers(context.getCurrentDatabase(), table, metadata_snapshot, ast.deduplicate_by_columns);
for (const auto & col : cols->children)
column_names.emplace_back(col->getColumnName());
}
metadata_snapshot->check(column_names, NamesAndTypesList{}, table_id);
const auto & sorting_keys = metadata_snapshot->getColumnsRequiredForSortingKey();
for (const auto & sorting_key : sorting_keys)
{
// Deduplication is performed only for adjacent rows in a block,
// and all rows in block are in the sorting key order,
// hence deduplication always implicitly takes sorting keys in account.
// So we just explicitly state that limitation in order to avoid confusion.
if (std::find(column_names.begin(), column_names.end(), sorting_key) == column_names.end())
throw Exception(ErrorCodes::THERE_IS_NO_COLUMN,
"DEDUPLICATE BY expression must include all columns used in table's ORDER BY or PRIMARY KEY,"
" but '{}' is missing."
" Expanded deduplicate columns expression: ['{}']",
sorting_key, fmt::join(column_names, "', '"));
}
}
table->optimize(query_ptr, metadata_snapshot, ast.partition, ast.final, ast.deduplicate, column_names, context);
return {};
2016-12-12 07:24:56 +00:00
}
2020-01-24 16:20:36 +00:00
AccessRightsElements InterpreterOptimizeQuery::getRequiredAccess() const
{
const auto & optimize = query_ptr->as<const ASTOptimizeQuery &>();
AccessRightsElements required_access;
required_access.emplace_back(AccessType::OPTIMIZE, optimize.database, optimize.table);
return required_access;
}
2016-12-12 07:24:56 +00:00
}