aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Formats/IndexForNativeFormat.cpp
blob: bb410125378f4ff244fe2f13cbdd6168b93ae663 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <Formats/IndexForNativeFormat.h>
#include <IO/ReadHelpers.h>


namespace DB
{

namespace ErrorCodes
{
    extern const int INCORRECT_INDEX;
}

void IndexOfBlockForNativeFormat::read(ReadBuffer & istr)
{
    readVarUInt(num_columns, istr);
    readVarUInt(num_rows, istr);
    columns.clear();
    for (size_t i = 0; i < num_columns; ++i)
    {
        auto & column = columns.emplace_back();
        readBinary(column.name, istr);
        readBinary(column.type, istr);
        readBinaryLittleEndian(column.location.offset_in_compressed_file, istr);
        readBinaryLittleEndian(column.location.offset_in_decompressed_block, istr);
    }
}

void IndexOfBlockForNativeFormat::write(WriteBuffer & ostr) const
{
    writeVarUInt(num_columns, ostr);
    writeVarUInt(num_rows, ostr);
    for (size_t i = 0; i < num_columns; ++i)
    {
        const auto & column = columns[i];
        writeBinary(column.name, ostr);
        writeBinary(column.type, ostr);
        writeBinaryLittleEndian(column.location.offset_in_compressed_file, ostr);
        writeBinaryLittleEndian(column.location.offset_in_decompressed_block, ostr);
    }
}

IndexOfBlockForNativeFormat IndexOfBlockForNativeFormat::extractIndexForColumns(const NameSet & required_columns) const
{
    if (num_columns < required_columns.size())
        throw Exception(ErrorCodes::INCORRECT_INDEX, "Index contain less than required columns");

    IndexOfBlockForNativeFormat res;
    for (size_t i = 0; i < num_columns; ++i)
    {
        const auto & column = columns[i];
        if (required_columns.contains(column.name))
            res.columns.push_back(column);
    }

    if (res.columns.size() < required_columns.size())
        throw Exception(ErrorCodes::INCORRECT_INDEX, "Index contain less than required columns");
    if (res.columns.size() > required_columns.size())
        throw Exception(ErrorCodes::INCORRECT_INDEX, "Index contain duplicate columns");

    res.num_columns = res.columns.size();
    res.num_rows = num_rows;
    return res;
}


void IndexForNativeFormat::read(ReadBuffer & istr)
{
    blocks.clear();
    while (!istr.eof())
    {
        auto & block = blocks.emplace_back();
        block.read(istr);
    }
}

void IndexForNativeFormat::write(WriteBuffer & ostr) const
{
    for (const auto & block : blocks)
        block.write(ostr);
}

IndexForNativeFormat IndexForNativeFormat::extractIndexForColumns(const NameSet & required_columns) const
{
    IndexForNativeFormat res;
    res.blocks.reserve(blocks.size());
    for (const auto & block : blocks)
        res.blocks.emplace_back(block.extractIndexForColumns(required_columns));
    return res;
}

}