Repository: ClickHouse/ClickHouse
File: src/Interpreters/SystemLog.cpp (C++)

Code before:

    ASTPtr storage_with_comment_ast = parseQuery(
        storage_parser, storage_def.data(), storage_def.data() + storage_def.size(),
        "Storage to create table for " + LogElement::name(), 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS);

    StorageWithComment & storage_with_comment = storage_with_comment_ast->as<StorageWithComment &>();

    create->set(create->storage, storage_with_comment.storage);
    create->set(create->comment, storage_with_comment.comment);

    /// Write additional (default) settings for MergeTree engine to make it make it possible to compare ASTs
    /// and recreate tables on settings changes.
    const auto & engine = create->storage->engine->as<ASTFunction &>();
    if (endsWith(engine.name, "MergeTree"))
    {
        auto storage_settings = std::make_unique<MergeTreeSettings>(getContext()->getMergeTreeSettings());
        storage_settings->loadFromQuery(*create->storage, getContext(), false);
    }

    return create;
}

#define INSTANTIATE_SYSTEM_LOG(ELEMENT) template class SystemLog<ELEMENT>;
SYSTEM_LOG_ELEMENTS(INSTANTIATE_SYSTEM_LOG)
#if CLICKHOUSE_CLOUD
SYSTEM_LOG_ELEMENTS_CLOUD(INSTANTIATE_SYSTEM_LOG)
#endif

}


Review comment (suggestion):
Not critical, but maybe we should choose more cryptic names (like `__automatic_index_<column>`) to minimise the risk of name collisions if someone has already declared such an index. 

Code after:
    ASTPtr storage_with_comment_ast = parseQuery(
        storage_parser, storage_def.data(), storage_def.data() + storage_def.size(),
        "Storage to create table for " + LogElement::name(), 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS);

    StorageWithComment & storage_with_comment = storage_with_comment_ast->as<StorageWithComment &>();

    create->set(create->storage, storage_with_comment.storage);
    create->set(create->comment, storage_with_comment.comment);

    const auto & engine = create->storage->engine->as<ASTFunction &>();

    /// Add secondary indexes (minmax on time columns) for MergeTree engines only,
    /// since other engines (e.g. Null) do not support skipping indices.
    if (endsWith(engine.name, "MergeTree"))
    {
        auto indices = make_intrusive<ASTExpressionList>();

        auto add_index = [&](const char * definition)
        {
            ParserIndexDeclaration parser;
            ASTPtr ast = parseQuery(parser, definition, definition + strlen(definition),
                "index declaration for " + LogElement::name(), 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS);
            indices->children.push_back(ast);
        };

        if (ordinary_columns.has("event_time"))
            add_index("event_time_index event_time TYPE minmax GRANULARITY 1");
        if (ordinary_columns.has("event_time_microseconds"))
            add_index("event_time_microseconds_index event_time_microseconds TYPE minmax GRANULARITY 1");

        if (ordinary_columns.has("query_id"))
            add_index("query_id_index query_id TYPE bloom_filter(0.001) GRANULARITY 1");
        if (ordinary_columns.has("initial_query_id"))
            add_index("initial_query_id_index initial_query_id TYPE bloom_filter(0.001) GRANULARITY 1");

        if (!indices->children.empty())
            new_columns_list->set(new_columns_list->indices, indices);
    }

    create->set(create->columns_list, new_columns_list);

    /// Write additional (default) settings for MergeTree engine to make it make it possible to compare ASTs
    /// and recreate tables on settings changes.
    if (endsWith(engine.name, "MergeTree"))
    {
        auto storage_settings = std::make_unique<MergeTreeSettings>(getContext()->getMergeTreeSettings());
        storage_settings->loadFromQuery(*create->storage, getContext(), false);
    }

    return create;
}