aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Formats/ColumnMapping.cpp
blob: e33dfc878f441544ad611e07955a1dd5745a157d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <Formats/ColumnMapping.h>

namespace DB
{

namespace ErrorCodes
{
    extern const int INCORRECT_DATA;
}

void ColumnMapping::setupByHeader(const Block & header)
{
    column_indexes_for_input_fields.resize(header.columns());
    names_of_columns = header.getNames();

    for (size_t i = 0; i < column_indexes_for_input_fields.size(); ++i)
        column_indexes_for_input_fields[i] = i;
}

void ColumnMapping::addColumns(
    const Names & column_names, const Block::NameMap & column_indexes_by_names, const FormatSettings & settings)
{
    std::vector<bool> read_columns(column_indexes_by_names.size(), false);

    for (const auto & name : column_names)
    {
        names_of_columns.push_back(name);

        const auto column_it = column_indexes_by_names.find(name);
        if (column_it == column_indexes_by_names.end())
        {
            if (settings.skip_unknown_fields)
            {
                column_indexes_for_input_fields.push_back(std::nullopt);
                continue;
            }

            throw Exception(
                            ErrorCodes::INCORRECT_DATA,
                            "Unknown field found in format header: "
                            "'{}' at position {}\nSet the 'input_format_skip_unknown_fields' parameter explicitly "
                            "to ignore and proceed",
                            name, column_indexes_for_input_fields.size());
        }

        const auto column_index = column_it->second;

        if (read_columns[column_index])
            throw Exception(ErrorCodes::INCORRECT_DATA, "Duplicate field found while parsing format header: {}", name);

        read_columns[column_index] = true;
        column_indexes_for_input_fields.emplace_back(column_index);
    }

    for (size_t i = 0; i != read_columns.size(); ++i)
    {
        if (!read_columns[i])
            not_presented_columns.push_back(i);
    }
}

void ColumnMapping::insertDefaultsForNotSeenColumns(MutableColumns & columns, std::vector<UInt8> & read_columns)
{
    for (auto index : not_presented_columns)
    {
        columns[index]->insertDefault();
        read_columns[index] = false;
    }
}

}