55#include < IO/Operators.h>
66#include < Common/NamedCollections/NamedCollectionConfiguration.h>
77#include < Poco/Util/AbstractConfiguration.h>
8+ #include < Common/FieldVisitorToString.h>
89
910#include < fmt/ranges.h>
1011
@@ -16,6 +17,7 @@ namespace ErrorCodes
1617{
1718 extern const int NAMED_COLLECTION_IS_IMMUTABLE;
1819 extern const int BAD_ARGUMENTS;
20+ extern const int NOT_IMPLEMENTED;
1921}
2022
2123namespace Configuration = NamedCollectionConfiguration;
@@ -173,30 +175,27 @@ class NamedCollection::Impl
173175 }
174176};
175177
178+ String NamedCollection::sourceIdToString (NamedCollection::SourceId id)
179+ {
180+ switch (id)
181+ {
182+ case NamedCollection::SourceId::NONE: return " NONE" ;
183+ case NamedCollection::SourceId::CONFIG: return " CONFIG" ;
184+ case NamedCollection::SourceId::SQL: return " SQL" ;
185+ }
186+ }
187+
176188NamedCollection::NamedCollection (
177189 ImplPtr pimpl_,
178190 const std::string & collection_name_,
179- SourceId source_id_,
180- bool is_mutable_)
191+ const bool is_mutable_)
181192 : pimpl(std::move(pimpl_))
182193 , collection_name(collection_name_)
183- , source_id(source_id_)
184194 , is_mutable(is_mutable_)
185195{
186196}
187197
188- MutableNamedCollectionPtr NamedCollection::create (
189- const Poco::Util::AbstractConfiguration & config,
190- const std::string & collection_name,
191- const std::string & collection_path,
192- const Keys & keys,
193- SourceId source_id,
194- bool is_mutable)
195- {
196- auto impl = Impl::create (config, collection_name, collection_path, keys);
197- return std::unique_ptr<NamedCollection>(
198- new NamedCollection (std::move (impl), collection_name, source_id, is_mutable));
199- }
198+ NamedCollection::~NamedCollection () = default ;
200199
201200bool NamedCollection::has (const Key & key) const
202201{
@@ -297,8 +296,7 @@ MutableNamedCollectionPtr NamedCollection::duplicate() const
297296 std::lock_guard lock (mutex);
298297 auto impl = pimpl->createCopy (collection_name);
299298 return std::unique_ptr<NamedCollection>(
300- new NamedCollection (
301- std::move (impl), collection_name, SourceId::NONE, true ));
299+ new NamedCollection (std::move (impl), collection_name, true ));
302300}
303301
304302NamedCollection::Keys NamedCollection::getKeys (ssize_t depth, const std::string & prefix) const
@@ -334,6 +332,136 @@ std::unique_lock<std::mutex> NamedCollection::lock()
334332 return std::unique_lock (mutex);
335333}
336334
335+
336+ void NamedCollection::update (const ASTAlterNamedCollectionQuery & /* query*/ )
337+ {
338+ throw Exception (
339+ ErrorCodes::NOT_IMPLEMENTED,
340+ " update() not implemented for NamedCollection base class." );
341+ }
342+
343+ NamedCollectionFromConfig::NamedCollectionFromConfig (
344+ const Poco::Util::AbstractConfiguration & config_,
345+ const std::string & collection_name_,
346+ const std::string & collection_path_,
347+ const Keys & keys_)
348+ : NamedCollection(Impl::create(config_, collection_name_, collection_path_, keys_), collection_name_, false )
349+ {
350+ }
351+
352+ MutableNamedCollectionPtr NamedCollectionFromConfig::create (
353+ const Poco::Util::AbstractConfiguration & config_,
354+ const std::string & collection_name_,
355+ const std::string & collection_path_,
356+ const Keys & keys_)
357+ {
358+ return std::unique_ptr<NamedCollection>(
359+ new NamedCollectionFromConfig (config_, collection_name_, collection_path_, keys_));
360+ }
361+
362+
363+ MutableNamedCollectionPtr NamedCollectionFromSQL::create (const ASTCreateNamedCollectionQuery & query)
364+ {
365+ return std::unique_ptr<NamedCollection>(new NamedCollectionFromSQL (query));
366+ }
367+
368+ NamedCollectionFromSQL::NamedCollectionFromSQL (const ASTCreateNamedCollectionQuery & query_)
369+ : NamedCollection(nullptr , query_.collection_name, true )
370+ , create_query_ptr(query_.clone()->as<ASTCreateNamedCollectionQuery &>())
371+ {
372+ const auto config = NamedCollectionConfiguration::createConfiguration (collection_name, create_query_ptr.changes , create_query_ptr.overridability );
373+
374+ std::set<std::string, std::less<>> keys;
375+ for (const auto & [name, _] : create_query_ptr.changes )
376+ keys.insert (name);
377+
378+ pimpl = Impl::create (*config, collection_name, " " , keys);
379+ }
380+
381+ String NamedCollectionFromSQL::getCreateStatement (bool show_secrects)
382+ {
383+ auto & changes = create_query_ptr.changes ;
384+ std::sort (
385+ changes.begin (), changes.end (),
386+ [](const SettingChange & lhs, const SettingChange & rhs) { return lhs.name < rhs.name ; });
387+
388+ return create_query_ptr.formatWithPossiblyHidingSensitiveData (
389+ /* max_length=*/ 0 ,
390+ /* one_line=*/ true ,
391+ /* show_secrets=*/ show_secrects,
392+ /* print_pretty_type_names=*/ false ,
393+ /* identifier_quoting_rule=*/ IdentifierQuotingRule::WhenNecessary,
394+ /* identifier_quoting_style=*/ IdentifierQuotingStyle::Backticks);
395+ }
396+
397+ void NamedCollectionFromSQL::update (const ASTAlterNamedCollectionQuery & alter_query)
398+ {
399+ std::lock_guard lock (mutex);
400+
401+ std::unordered_map<std::string, Field> result_changes_map;
402+ for (const auto & [name, value] : alter_query.changes )
403+ {
404+ auto [it, inserted] = result_changes_map.emplace (name, value);
405+ if (!inserted)
406+ {
407+ throw Exception (
408+ ErrorCodes::BAD_ARGUMENTS,
409+ " Value with key `{}` is used twice in the SET query (collection name: {})" ,
410+ name, alter_query.collection_name );
411+ }
412+ }
413+
414+ for (const auto & [name, value] : create_query_ptr.changes )
415+ result_changes_map.emplace (name, value);
416+
417+ std::unordered_map<std::string, bool > result_overridability_map;
418+ for (const auto & [name, value] : alter_query.overridability )
419+ result_overridability_map.emplace (name, value);
420+ for (const auto & [name, value] : create_query_ptr.overridability )
421+ result_overridability_map.emplace (name, value);
422+
423+ for (const auto & delete_key : alter_query.delete_keys )
424+ {
425+ auto it = result_changes_map.find (delete_key);
426+ if (it == result_changes_map.end ())
427+ {
428+ throw Exception (
429+ ErrorCodes::BAD_ARGUMENTS,
430+ " Cannot delete key `{}` because it does not exist in collection" ,
431+ delete_key);
432+ }
433+
434+ result_changes_map.erase (it);
435+ auto it_override = result_overridability_map.find (delete_key);
436+ if (it_override != result_overridability_map.end ())
437+ result_overridability_map.erase (it_override);
438+ }
439+
440+ create_query_ptr.changes .clear ();
441+ for (const auto & [name, value] : result_changes_map)
442+ create_query_ptr.changes .emplace_back (name, value);
443+ create_query_ptr.overridability = std::move (result_overridability_map);
444+
445+ if (create_query_ptr.changes .empty ())
446+ throw Exception (
447+ ErrorCodes::BAD_ARGUMENTS,
448+ " Named collection cannot be empty (collection name: {})" ,
449+ collection_name);
450+
451+ chassert (create_query_ptr.collection_name == alter_query.collection_name );
452+ for (const auto & [name, value] : alter_query.changes )
453+ {
454+ auto it_override = alter_query.overridability .find (name);
455+ if (it_override != alter_query.overridability .end ())
456+ setOrUpdate<String, true >(name, convertFieldToString (value), it_override->second );
457+ else
458+ setOrUpdate<String, true >(name, convertFieldToString (value), {});
459+ }
460+
461+ for (const auto & key : alter_query.delete_keys )
462+ remove<true >(key);
463+ }
464+
337465template String NamedCollection::get<String>(const NamedCollection::Key & key) const ;
338466template UInt64 NamedCollection::get<UInt64>(const NamedCollection::Key & key) const ;
339467template Int64 NamedCollection::get<Int64>(const NamedCollection::Key & key) const ;
0 commit comments