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

Code before:
    bool validate_schema_with_remote,
    ObjectStoragePtr object_storage,
    StorageObjectStorageConfigurationPtr config_ptr,
    const std::optional<FormatSettings> * format_settings,
    const std::string * sample_path,
    ContextPtr context,
    const NamesAndTypesList * hive_partition_columns_to_read_from_file_path,
    const ColumnsDescription * columns_in_table_or_function_definition,
    LoggerPtr log)
{
    if (!columns.hasOnlyOrdinary())
    {
        /// We don't allow special columns.
        throw Exception(ErrorCodes::BAD_ARGUMENTS,
            "Special columns like MATERIALIZED, ALIAS or EPHEMERAL are not supported for {} storage.",
            configuration.getTypeName());
    }

    /// If schema validation parameters are not provided, skip schema consistency check.
    if (!object_storage || !config_ptr || !format_settings || !sample_path || !context
        || !hive_partition_columns_to_read_from_file_path || !columns_in_table_or_function_definition || !log)
        return;

    /// We don't check csv and tsv formats because they change column names.
    if (!validate_schema_with_remote
        || configuration.format == "CSV"
        || configuration.format == "TSV")
        return;

    /// Verify that explicitly specified columns exist in the schema inferred from data.
    String sample_path_schema = *sample_path;
    std::optional<ColumnsDescription> schema_file;
    try
    {
        schema_file = StorageObjectStorage::resolveSchemaFromData(
            object_storage,
            config_ptr,
            *format_settings,
            sample_path_schema,
            context);
    }
    catch (...)
    {
        tryLogCurrentException(log, "while verifying schema consistency", LogsLevel::debug);
    }
    if (schema_file)
    {
        std::unordered_set<String> hive_partitioning_columns;
        for (const auto & column_name : hive_partition_columns_to_read_from_file_path->getNames())
            hive_partitioning_columns.insert(column_name);
        for (const auto & column : *columns_in_table_or_function_definition)

Review comment (suggestion):
To be honest, do not like this part, we should guarantee that if `validate_schema_with_remote == true` then we do validate it properly, otherwise someone can accidentally forget to pass one of the args and not notice that it actually does not work. So, in my opinion, exception is better, or an assert at least.

Code after:
void validateColumns(
    const ColumnsDescription & columns,
    StorageObjectStorageConfigurationPtr configuration,
    bool validate_schema_with_remote,
    ObjectStoragePtr object_storage,
    const std::optional<FormatSettings> * format_settings,
    const std::string * sample_path,
    ContextPtr context,
    const NamesAndTypesList * hive_partition_columns_to_read_from_file_path,
    const ColumnsDescription * columns_in_table_or_function_definition,
    LoggerPtr log)
{
    if (!columns.hasOnlyOrdinary())
    {
        /// We don't allow special columns.
        throw Exception(ErrorCodes::BAD_ARGUMENTS,
            "Special columns like MATERIALIZED, ALIAS or EPHEMERAL are not supported for {} storage.",
            configuration ? configuration->getTypeName() : "object storage");
    }

    /// If schema validation parameters are not provided, skip schema consistency check.
    /// validateColumns is only called with full arguments from StorageObjectStorage when
    /// resolveSchemaAndFormat was not used (validate_schema_with_remote == true).
    if (!object_storage || !configuration || !format_settings || !sample_path || !context
        || !hive_partition_columns_to_read_from_file_path || !columns_in_table_or_function_definition || !log)
        return;

    /// We don't check csv and tsv formats because they change column names.
    if (!validate_schema_with_remote
        || configuration->format == "CSV"
        || configuration->format == "TSV")
        return;

    /// Verify that explicitly specified columns exist in the schema inferred from data.
    String sample_path_schema = *sample_path;
    std::optional<ColumnsDescription> schema_file;
    try
    {
        schema_file = StorageObjectStorage::resolveSchemaFromData(
            object_storage,
            configuration,
            *format_settings,
            sample_path_schema,
            context);
    }
    catch (...)
    {
        tryLogCurrentException(log, "while verifying schema consistency", LogsLevel::debug);
    }
    if (schema_file)
    {