|
1 | | -#include "NamedCollections.h" |
| 1 | +#include <Common/NamedCollections/NamedCollections.h> |
2 | 2 |
|
3 | 3 | #include <Interpreters/Context.h> |
4 | 4 | #include <IO/WriteBufferFromString.h> |
5 | 5 | #include <IO/Operators.h> |
6 | 6 | #include <Common/NamedCollections/NamedCollectionConfiguration.h> |
7 | 7 | #include <Poco/Util/AbstractConfiguration.h> |
| 8 | +#include <Common/FieldVisitorToString.h> |
| 9 | + |
| 10 | +#include <fmt/ranges.h> |
8 | 11 |
|
9 | 12 |
|
10 | 13 | namespace DB |
11 | 14 | { |
12 | 15 |
|
13 | 16 | namespace ErrorCodes |
14 | 17 | { |
15 | | - extern const int NAMED_COLLECTION_DOESNT_EXIST; |
16 | | - extern const int NAMED_COLLECTION_ALREADY_EXISTS; |
17 | 18 | extern const int NAMED_COLLECTION_IS_IMMUTABLE; |
| 19 | + extern const int BAD_ARGUMENTS; |
| 20 | + extern const int NOT_IMPLEMENTED; |
18 | 21 | } |
19 | 22 |
|
20 | 23 | namespace Configuration = NamedCollectionConfiguration; |
@@ -175,27 +178,14 @@ class NamedCollection::Impl |
175 | 178 | NamedCollection::NamedCollection( |
176 | 179 | ImplPtr pimpl_, |
177 | 180 | const std::string & collection_name_, |
178 | | - SourceId source_id_, |
179 | | - bool is_mutable_) |
| 181 | + const bool is_mutable_) |
180 | 182 | : pimpl(std::move(pimpl_)) |
181 | 183 | , collection_name(collection_name_) |
182 | | - , source_id(source_id_) |
183 | 184 | , is_mutable(is_mutable_) |
184 | 185 | { |
185 | 186 | } |
186 | 187 |
|
187 | | -MutableNamedCollectionPtr NamedCollection::create( |
188 | | - const Poco::Util::AbstractConfiguration & config, |
189 | | - const std::string & collection_name, |
190 | | - const std::string & collection_path, |
191 | | - const Keys & keys, |
192 | | - SourceId source_id, |
193 | | - bool is_mutable) |
194 | | -{ |
195 | | - auto impl = Impl::create(config, collection_name, collection_path, keys); |
196 | | - return std::unique_ptr<NamedCollection>( |
197 | | - new NamedCollection(std::move(impl), collection_name, source_id, is_mutable)); |
198 | | -} |
| 188 | +NamedCollection::~NamedCollection() = default; |
199 | 189 |
|
200 | 190 | bool NamedCollection::has(const Key & key) const |
201 | 191 | { |
@@ -296,8 +286,7 @@ MutableNamedCollectionPtr NamedCollection::duplicate() const |
296 | 286 | std::lock_guard lock(mutex); |
297 | 287 | auto impl = pimpl->createCopy(collection_name); |
298 | 288 | return std::unique_ptr<NamedCollection>( |
299 | | - new NamedCollection( |
300 | | - std::move(impl), collection_name, SourceId::NONE, true)); |
| 289 | + new NamedCollection(std::move(impl), collection_name, true)); |
301 | 290 | } |
302 | 291 |
|
303 | 292 | NamedCollection::Keys NamedCollection::getKeys(ssize_t depth, const std::string & prefix) const |
@@ -333,6 +322,133 @@ std::unique_lock<std::mutex> NamedCollection::lock() |
333 | 322 | return std::unique_lock(mutex); |
334 | 323 | } |
335 | 324 |
|
| 325 | + |
| 326 | +void NamedCollection::update(const ASTAlterNamedCollectionQuery & /*query*/) |
| 327 | +{ |
| 328 | + throw Exception( |
| 329 | + ErrorCodes::NOT_IMPLEMENTED, |
| 330 | + "update() not implemented for NamedCollection base class."); |
| 331 | +} |
| 332 | + |
| 333 | +NamedCollectionFromConfig::NamedCollectionFromConfig( |
| 334 | + const Poco::Util::AbstractConfiguration & config_, |
| 335 | + const std::string & collection_name_, |
| 336 | + const std::string & collection_path_, |
| 337 | + const Keys & keys_) |
| 338 | + : NamedCollection(Impl::create(config_, collection_name_, collection_path_, keys_), collection_name_, /* is_mutable */ false) |
| 339 | +{ |
| 340 | +} |
| 341 | + |
| 342 | +MutableNamedCollectionPtr NamedCollectionFromConfig::create( |
| 343 | + const Poco::Util::AbstractConfiguration & config_, |
| 344 | + const std::string & collection_name_, |
| 345 | + const std::string & collection_path_, |
| 346 | + const Keys & keys_) |
| 347 | +{ |
| 348 | + return std::unique_ptr<NamedCollection>( |
| 349 | + new NamedCollectionFromConfig(config_, collection_name_, collection_path_, keys_)); |
| 350 | +} |
| 351 | + |
| 352 | + |
| 353 | +MutableNamedCollectionPtr NamedCollectionFromSQL::create(const ASTCreateNamedCollectionQuery & query) |
| 354 | +{ |
| 355 | + return std::unique_ptr<NamedCollection>(new NamedCollectionFromSQL(query)); |
| 356 | +} |
| 357 | + |
| 358 | +NamedCollectionFromSQL::NamedCollectionFromSQL(const ASTCreateNamedCollectionQuery & query_) |
| 359 | + : NamedCollection(nullptr, query_.collection_name, true) |
| 360 | + , create_query_ptr(query_.clone()->as<ASTCreateNamedCollectionQuery &>()) |
| 361 | +{ |
| 362 | + const auto config = NamedCollectionConfiguration::createConfiguration(collection_name, create_query_ptr.changes, create_query_ptr.overridability); |
| 363 | + |
| 364 | + std::set<std::string, std::less<>> keys; |
| 365 | + for (const auto & [name, _] : create_query_ptr.changes) |
| 366 | + keys.insert(name); |
| 367 | + |
| 368 | + pimpl = Impl::create(*config, collection_name, "", keys); |
| 369 | +} |
| 370 | + |
| 371 | +String NamedCollectionFromSQL::getCreateStatement(bool show_secrects) |
| 372 | +{ |
| 373 | + auto & changes = create_query_ptr.changes; |
| 374 | + std::sort( |
| 375 | + changes.begin(), changes.end(), |
| 376 | + [](const SettingChange & lhs, const SettingChange & rhs) { return lhs.name < rhs.name; }); |
| 377 | + |
| 378 | + return create_query_ptr.formatWithPossiblyHidingSensitiveData( |
| 379 | + /*max_length=*/0, |
| 380 | + /*one_line=*/true, |
| 381 | + /*show_secrets=*/show_secrects); |
| 382 | +} |
| 383 | + |
| 384 | +void NamedCollectionFromSQL::update(const ASTAlterNamedCollectionQuery & alter_query) |
| 385 | +{ |
| 386 | + std::lock_guard lock(mutex); |
| 387 | + |
| 388 | + std::unordered_map<std::string, Field> result_changes_map; |
| 389 | + for (const auto & [name, value] : alter_query.changes) |
| 390 | + { |
| 391 | + auto [it, inserted] = result_changes_map.emplace(name, value); |
| 392 | + if (!inserted) |
| 393 | + { |
| 394 | + throw Exception( |
| 395 | + ErrorCodes::BAD_ARGUMENTS, |
| 396 | + "Value with key `{}` is used twice in the SET query (collection name: {})", |
| 397 | + name, alter_query.collection_name); |
| 398 | + } |
| 399 | + } |
| 400 | + |
| 401 | + for (const auto & [name, value] : create_query_ptr.changes) |
| 402 | + result_changes_map.emplace(name, value); |
| 403 | + |
| 404 | + std::unordered_map<std::string, bool> result_overridability_map; |
| 405 | + for (const auto & [name, value] : alter_query.overridability) |
| 406 | + result_overridability_map.emplace(name, value); |
| 407 | + for (const auto & [name, value] : create_query_ptr.overridability) |
| 408 | + result_overridability_map.emplace(name, value); |
| 409 | + |
| 410 | + for (const auto & delete_key : alter_query.delete_keys) |
| 411 | + { |
| 412 | + auto it = result_changes_map.find(delete_key); |
| 413 | + if (it == result_changes_map.end()) |
| 414 | + { |
| 415 | + throw Exception( |
| 416 | + ErrorCodes::BAD_ARGUMENTS, |
| 417 | + "Cannot delete key `{}` because it does not exist in collection", |
| 418 | + delete_key); |
| 419 | + } |
| 420 | + |
| 421 | + result_changes_map.erase(it); |
| 422 | + auto it_override = result_overridability_map.find(delete_key); |
| 423 | + if (it_override != result_overridability_map.end()) |
| 424 | + result_overridability_map.erase(it_override); |
| 425 | + } |
| 426 | + |
| 427 | + create_query_ptr.changes.clear(); |
| 428 | + for (const auto & [name, value] : result_changes_map) |
| 429 | + create_query_ptr.changes.emplace_back(name, value); |
| 430 | + create_query_ptr.overridability = std::move(result_overridability_map); |
| 431 | + |
| 432 | + if (create_query_ptr.changes.empty()) |
| 433 | + throw Exception( |
| 434 | + ErrorCodes::BAD_ARGUMENTS, |
| 435 | + "Named collection cannot be empty (collection name: {})", |
| 436 | + collection_name); |
| 437 | + |
| 438 | + chassert(create_query_ptr.collection_name == alter_query.collection_name); |
| 439 | + for (const auto & [name, value] : alter_query.changes) |
| 440 | + { |
| 441 | + auto it_override = alter_query.overridability.find(name); |
| 442 | + if (it_override != alter_query.overridability.end()) |
| 443 | + setOrUpdate<String, true>(name, convertFieldToString(value), it_override->second); |
| 444 | + else |
| 445 | + setOrUpdate<String, true>(name, convertFieldToString(value), {}); |
| 446 | + } |
| 447 | + |
| 448 | + for (const auto & key : alter_query.delete_keys) |
| 449 | + remove<true>(key); |
| 450 | +} |
| 451 | + |
336 | 452 | template String NamedCollection::get<String>(const NamedCollection::Key & key) const; |
337 | 453 | template UInt64 NamedCollection::get<UInt64>(const NamedCollection::Key & key) const; |
338 | 454 | template Int64 NamedCollection::get<Int64>(const NamedCollection::Key & key) const; |
|
0 commit comments