| 60 | /// Creates a system log with MergeTree engine using parameters from config |
| 61 | template <typename TSystemLog> |
| 62 | std::shared_ptr<TSystemLog> createSystemLog( |
| 63 | ContextPtr context, |
| 64 | const String & default_database_name, |
| 65 | const String & default_table_name, |
| 66 | const Poco::Util::AbstractConfiguration & config, |
| 67 | const String & config_prefix, |
| 68 | bool enable_by_default) |
| 69 | { |
| 70 | if (!config.has(config_prefix) && !enable_by_default) |
| 71 | return {}; |
| 72 | |
| 73 | if (config.has(config_prefix) && !config.getBool(config_prefix + ".enable", true)) |
| 74 | return {}; |
| 75 | |
| 76 | String database = config.getString(config_prefix + ".database", default_database_name); |
| 77 | String table = config.getString(config_prefix + ".table", default_table_name); |
| 78 | |
| 79 | if (database != default_database_name) |
| 80 | { |
| 81 | /// System tables must be loaded before other tables, but loading order is undefined for all databases except `system` |
| 82 | LOG_ERROR(&Poco::Logger::get("SystemLog"), "Custom database name for a system table specified in config." |
| 83 | " Table `{}` will be created in `system` database instead of `{}`", table, database); |
| 84 | database = default_database_name; |
| 85 | } |
| 86 | |
| 87 | String engine; |
| 88 | if (config.has(config_prefix + ".engine")) |
| 89 | { |
| 90 | if (config.has(config_prefix + ".partition_by")) |
| 91 | throw Exception("If 'engine' is specified for system table, " |
| 92 | "PARTITION BY parameters should be specified directly inside 'engine' and 'partition_by' setting doesn't make sense", |
| 93 | ErrorCodes::BAD_ARGUMENTS); |
| 94 | if (config.has(config_prefix + ".ttl")) |
| 95 | throw Exception("If 'engine' is specified for system table, " |
| 96 | "TTL parameters should be specified directly inside 'engine' and 'ttl' setting doesn't make sense", |
| 97 | ErrorCodes::BAD_ARGUMENTS); |
| 98 | engine = config.getString(config_prefix + ".engine"); |
| 99 | } |
| 100 | else |
| 101 | { |
| 102 | String partition_by = config.getString(config_prefix + ".partition_by", "toYYYYMM(event_date)"); |
| 103 | engine = "ENGINE = MergeTree"; |
| 104 | if (!partition_by.empty()) |
| 105 | engine += " PARTITION BY (" + partition_by + ")"; |
| 106 | String ttl = config.getString(config_prefix + ".ttl", ""); |
| 107 | if (!ttl.empty()) |
| 108 | engine += " TTL " + ttl; |
| 109 | engine += " ORDER BY (event_date, event_time)"; |
| 110 | } |
| 111 | // Validate engine definition grammatically to prevent some configuration errors |
| 112 | ParserStorage storage_parser(ParserSettings::valueOf(context->getSettingsRef())); |
| 113 | parseQuery(storage_parser, engine.data(), engine.data() + engine.size(), |
| 114 | "Storage to create table for " + config_prefix, 0, DBMS_DEFAULT_MAX_PARSER_DEPTH); |
| 115 | |
| 116 | size_t flush_interval_milliseconds = config.getUInt64(config_prefix + ".flush_interval_milliseconds", |
| 117 | DEFAULT_SYSTEM_LOG_FLUSH_INTERVAL_MILLISECONDS); |
| 118 | |
| 119 | return std::make_shared<TSystemLog>(context, database, table, engine, flush_interval_milliseconds); |