aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/clickhouse/client/block.cpp
blob: d39f1967c70e5f85f840e14dc6ffd3fb6e9c27ac (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "block.h"

#include <util/generic/yexception.h>

namespace NClickHouse {
    TBlock::TIterator::TIterator(const TBlock& block)
        : Block_(block)
        , Idx_(0)
    {
    }

    const TString& TBlock::TIterator::Name() const {
        return Block_.Columns_[Idx_].Name;
    }

    TTypeRef TBlock::TIterator::Type() const {
        return Block_.Columns_[Idx_].Column->Type();
    }

    TColumnRef TBlock::TIterator::Column() const {
        return Block_.Columns_[Idx_].Column;
    }

    void TBlock::TIterator::Next() {
        ++Idx_;
    }

    bool TBlock::TIterator::IsValid() const {
        return Idx_ < Block_.Columns_.size();
    }

    TBlock::TBlock()
        : Rows_(0)
    {
    }

    TBlock::TBlock(size_t cols, size_t rows)
        : Rows_(rows)
    {
        Columns_.reserve(cols);
    }

    TBlock::~TBlock() = default;

    void TBlock::AppendColumn(const TString& name, const TColumnRef& col) {
        if (Columns_.empty()) {
            Rows_ = col->Size();
        } else if (col->Size() != Rows_) {
            ythrow yexception()
                << "all clumns in block must have same count of rows";
        }

        Columns_.push_back(TColumnItem{name, col});
    }

    /// Count of columns in the block.
    size_t TBlock::GetColumnCount() const {
        return Columns_.size();
    }

    const TBlockInfo& TBlock::Info() const {
        return Info_;
    }

    /// Count of rows in the block.
    size_t TBlock::GetRowCount() const {
        return Rows_;
    }

    void TBlock::AppendBlock(const TBlock& block) {
        if (block.GetRowCount() == 0) {
            return;
        }
        size_t columnCount = GetColumnCount();
        if (columnCount == 0) {
            Rows_ = block.GetRowCount();
            Columns_ = block.Columns_;
            return;
        }

        if (columnCount != block.GetColumnCount()) {
            ythrow yexception() << "Can't concatenate two blocks. Different number of columns (current_block: "
                << columnCount << ", added: " << block.GetColumnCount() << ")";
        }

        for (size_t i = 0; i < columnCount; ++i) {
            if (Columns_[i].Name != block.Columns_[i].Name) {
                ythrow yexception() << "Can't concatenate two blocks. Different names of columns (current_block: "
                    << Columns_[i].Name << ", added: " << block.Columns_[i].Name << ")";
            }
        }

        for (size_t i = 0; i < columnCount; ++i) {
            Columns_[i].Column->Append(block.Columns_[i].Column);
        }
        Rows_ += block.GetRowCount();
    }

    TColumnRef TBlock::operator[](size_t idx) const {
        if (idx < Columns_.size()) {
            return Columns_[idx].Column;
        }

        ythrow yexception() << "column index is out of range";
    }

}