Repository: ClickHouse/ClickHouse
File: src/Databases/IDatabase.h (C/C++)

Code before:
    /// Get the table for work. Return nullptr if there is no table.
    virtual StoragePtr tryGetTable(const String & name, ContextPtr context) const = 0;

    virtual StoragePtr getTable(const String & name, ContextPtr context) const;

    virtual UUID tryGetTableUUID(const String & /*table_name*/) const { return UUIDHelpers::Nil; }

    using FilterByNameFunction = std::function<bool(const String &)>;

    /// Get an iterator that allows you to pass through all the tables.
    /// It is possible to have "hidden" tables that are not visible when passing through, but are visible if you get them by name using the functions above.
    /// Wait for all tables to be loaded and started up. If `skip_not_loaded` is true, then not yet loaded or not yet started up (at the moment of iterator creation) tables are excluded.
    virtual DatabaseTablesIteratorPtr getTablesIterator(ContextPtr context, const FilterByNameFunction & filter_by_table_name = {}, bool skip_not_loaded = false) const = 0; /// NOLINT

    /// Same as above, but may return non-fully initialized StoragePtr objects which are not suitable for reading.
    /// Useful for queries like "SHOW TABLES"
    virtual std::vector<LightWeightTableDetails> getLightweightTablesIterator(ContextPtr context, const FilterByNameFunction & filter_by_table_name = {}, bool skip_not_loaded = false) const /// NOLINT
    {
        std::vector<LightWeightTableDetails> result;

        for (auto iterator = getTablesIterator(context, filter_by_table_name, skip_not_loaded); iterator->isValid(); iterator->next())
        {
            if (const auto & table = iterator->table())
            {
                result.emplace_back(iterator->name());
            }
        }

        return result;
    }

    virtual DatabaseDetachedTablesSnapshotIteratorPtr getDetachedTablesIterator(
        ContextPtr /*context*/, const FilterByNameFunction & /*filter_by_table_name = {}*/, bool /*skip_not_loaded = false*/) const;

    /// Returns list of table names.
    virtual Strings getAllTableNames(ContextPtr context) const
    {
        // NOTE: This default implementation wait for all tables to be loaded and started up. It should be reimplemented for databases that support async loading.
        Strings result;
        for (auto table_it = getTablesIterator(context); table_it->isValid(); table_it->next())
            result.emplace_back(table_it->name());
        return result;
    }

    /// Is the database empty.
    virtual bool empty() const = 0;

    virtual bool isReadOnly() const { return false; }

    /// Add the table to the database. Record its presence in the metadata.
    virtual void createTable(

Review comment (bug):
The default implementation of `getLightweightTablesIterator()` skips tables where `iterator->table()` returns null, but this differs from the previous behavior where all tables were included. This could cause tables that fail to load to be silently omitted from results. Consider whether null tables should be included with just their names, or document this filtering behavior.
```suggestion
            result.emplace_back(iterator->name());
```

Code after:
    /// Check if the table name exceeds the max allowed length
    virtual void checkTableNameLength(const String & /*table_name*/) const {}

    /// Get the table for work. Return nullptr if there is no table.
    virtual StoragePtr tryGetTable(const String & name, ContextPtr context) const = 0;

    virtual StoragePtr getTable(const String & name, ContextPtr context) const;

    virtual UUID tryGetTableUUID(const String & /*table_name*/) const { return UUIDHelpers::Nil; }

    using FilterByNameFunction = std::function<bool(const String &)>;

    /// Get an iterator that allows you to pass through all the tables.
    /// It is possible to have "hidden" tables that are not visible when passing through, but are visible if you get them by name using the functions above.
    /// Wait for all tables to be loaded and started up. If `skip_not_loaded` is true, then not yet loaded or not yet started up (at the moment of iterator creation) tables are excluded.
    virtual DatabaseTablesIteratorPtr getTablesIterator(ContextPtr context, const FilterByNameFunction & filter_by_table_name = {}, bool skip_not_loaded = false) const = 0; /// NOLINT

    /// Same as above, but may return non-fully initialized StoragePtr objects which are not suitable for reading.
    /// Useful for queries like "SHOW TABLES"
    virtual std::vector<LightWeightTableDetails> getLightweightTablesIterator(ContextPtr context, const FilterByNameFunction & filter_by_table_name = {}, bool skip_not_loaded = false) const /// NOLINT
    {
        std::vector<LightWeightTableDetails> result;

        for (auto iterator = getTablesIterator(context, filter_by_table_name, skip_not_loaded); iterator->isValid(); iterator->next())
        {
            if (const auto & table = iterator->table())
                result.emplace_back(iterator->name());
        }

        return result;
    }

    virtual DatabaseDetachedTablesSnapshotIteratorPtr getDetachedTablesIterator(
        ContextPtr /*context*/, const FilterByNameFunction & /*filter_by_table_name = {}*/, bool /*skip_not_loaded = false*/) const;

    /// Returns list of table names.
    virtual Strings getAllTableNames(ContextPtr context) const
    {
        // NOTE: This default implementation wait for all tables to be loaded and started up. It should be reimplemented for databases that support async loading.
        Strings result;
        for (auto table_it = getTablesIterator(context); table_it->isValid(); table_it->next())
            result.emplace_back(table_it->name());
        return result;
    }

    /// Is the database empty.
    virtual bool empty() const = 0;

    virtual bool isReadOnly() const { return false; }

    /// Add the table to the database. Record its presence in the metadata.