std::unique_ptr<IMergeTreeIndex> minmaxIndexCreator( const NamesAndTypesList & new_columns, std::shared_ptr<ASTIndexDeclaration> node, const Context & context) { if (node->name.empty()) throw Exception("Index must have unique name", ErrorCodes::INCORRECT_QUERY); if (node->type->arguments) throw Exception("Minmax index have not any arguments", ErrorCodes::INCORRECT_QUERY); ASTPtr expr_list = MergeTreeData::extractKeyExpressionList(node->expr->clone()); auto syntax = SyntaxAnalyzer(context, {}).analyze( expr_list, new_columns); auto minmax_expr = ExpressionAnalyzer(expr_list, syntax, context).getActions(false); auto sample = ExpressionAnalyzer(expr_list, syntax, context) .getActions(true)->getSampleBlock(); Names columns; DataTypes data_types; for (size_t i = 0; i < expr_list->children.size(); ++i) { const auto & column = sample.getByPosition(i); columns.emplace_back(column.name); data_types.emplace_back(column.type); } return std::make_unique<MergeTreeMinMaxIndex>( node->name, std::move(minmax_expr), columns, data_types, sample, node->granularity); }
NameSet MergeTreeReadPool::injectRequiredColumns(const MergeTreeData::DataPartPtr & part, Names & columns) const { NameSet required_columns{std::begin(columns), std::end(columns)}; NameSet injected_columns; auto all_column_files_missing = true; for (size_t i = 0; i < columns.size(); ++i) { const auto & column_name = columns[i]; /// column has files and hence does not require evaluation if (part->hasColumnFiles(column_name)) { all_column_files_missing = false; continue; } const auto default_it = data.column_defaults.find(column_name); /// columns has no explicit default expression if (default_it == std::end(data.column_defaults)) continue; /// collect identifiers required for evaluation IdentifierNameSet identifiers; default_it->second.expression->collectIdentifierNames(identifiers); for (const auto & identifier : identifiers) { if (data.hasColumn(identifier)) { /// ensure each column is added only once if (required_columns.count(identifier) == 0) { columns.emplace_back(identifier); required_columns.emplace(identifier); injected_columns.emplace(identifier); } } } } /** Добавить столбец минимального размера. * Используется в случае, когда ни один столбец не нужен или файлы отсутствуют, но нужно хотя бы знать количество строк. * Добавляет в columns. */ if (all_column_files_missing) { const auto minimum_size_column_name = part->getColumnNameWithMinumumCompressedSize(); columns.push_back(minimum_size_column_name); /// correctly report added column injected_columns.insert(columns.back()); } return injected_columns; }