Repository: ClickHouse/ClickHouse
File: src/Storages/ObjectStorage/StorageObjectStorage.cpp (C++)

Code before:

    setInMemoryMetadata(metadata);

    /// This will update metadata for table function which contains specific information about table
    /// state (e.g. for Iceberg). It is done because select queries for table functions are executed
    /// in a different way and clickhouse can execute without calling updateExternalDynamicMetadataIfExists.
    if (!do_lazy_init && is_table_function && configuration->needsUpdateForSchemaConsistency())
    {
        auto metadata_snapshot = configuration->getStorageSnapshotMetadata(context);
        setInMemoryMetadata(metadata_snapshot);
    }

    /// We don't need to process data lakes because tables may have "schema evolution" feature.
    if (!configuration->isDataLakeConfiguration() &&
        !columns_in_table_or_function_definition.empty() &&
        !is_table_function &&
        configuration_->format != "CSV" &&
        configuration_->format != "TSV" &&
        mode == LoadingStrictnessLevel::CREATE &&
        !do_lazy_init)
    {
        String sample_path_schema;
        std::optional<ColumnsDescription> schema_file;
        try
        {
            schema_file = resolveSchemaFromData(object_storage_, configuration_, {}, sample_path_schema, context);
        }
        catch (...)
        {
            tryLogCurrentException(log, "", LogsLevel::debug);
        }
        if (schema_file)
        {
            std::unordered_set<String> hive_parititioning_columns;
            for (const auto & column_name : hive_partition_columns_to_read_from_file_path.getNames())
                hive_parititioning_columns.insert(column_name);
            for (const auto & column : columns_in_table_or_function_definition)
                if (!schema_file->tryGet(column.name) && !hive_parititioning_columns.contains(column.name))
                {
                    String hive_columns;
                    for (const auto & hive_column : hive_parititioning_columns)
                        hive_columns += hive_column + ";";
                    throw Exception(ErrorCodes::BAD_ARGUMENTS, "Cannot find column {} in schema {}, hive columns {}", column.name, schema_file->toString(false), hive_columns);
                }
        }
    }
}

String StorageObjectStorage::getName() const
{
    return configuration->getEngineName();

Review comment (suggestion):
```suggestion
            schema_file = resolveSchemaFromData(object_storage_, configuration_, format_settings, sample_path_schema, context);
```
`format_settings` are available in constructor

Code after:
    StorageInMemoryMetadata metadata;
    metadata.setColumns(columns);
    metadata.setConstraints(constraints_);
    metadata.setComment(comment);

    /// I am not sure this is actually required, but just in case
    if (configuration->partition_strategy)
    {
        metadata.partition_key = configuration->partition_strategy->getPartitionKeyDescription();
    }

    setVirtuals(VirtualColumnUtils::getVirtualsForFileLikeStorage(
        metadata.columns,
        context,
        format_settings,
        configuration->partition_strategy_type,
        sample_path));

    setInMemoryMetadata(metadata);

    /// This will update metadata for table function which contains specific information about table
    /// state (e.g. for Iceberg). It is done because select queries for table functions are executed
    /// in a different way and clickhouse can execute without calling updateExternalDynamicMetadataIfExists.
    if (!do_lazy_init && is_table_function && configuration->needsUpdateForSchemaConsistency())
    {
        auto metadata_snapshot = configuration->getStorageSnapshotMetadata(context);
        setInMemoryMetadata(metadata_snapshot);
    }

}

String StorageObjectStorage::getName() const
{
    return configuration->getEngineName();
}

bool StorageObjectStorage::prefersLargeBlocks() const
{
    return FormatFactory::instance().checkIfOutputFormatPrefersLargeBlocks(configuration->format);
}

bool StorageObjectStorage::parallelizeOutputAfterReading(ContextPtr context) const
{
    return FormatFactory::instance().checkParallelizeOutputAfterReading(configuration->format, context);
}

bool StorageObjectStorage::supportsSubsetOfColumns(const ContextPtr & context) const
{
    return FormatFactory::instance().checkIfFormatSupportsSubsetOfColumns(configuration->format, context, format_settings);
}