aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Storages/StorageSnapshot.h
blob: a69f9b959551d873ecb3478c7bd4b1f879eab3be (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
#pragma once
#include <Storages/StorageInMemoryMetadata.h>

namespace DB
{

class IStorage;

/// Snapshot of storage that fixes set columns that can be read in query.
/// There are 3 sources of columns: regular columns from metadata,
/// dynamic columns from object Types, virtual columns.
struct StorageSnapshot
{
    const IStorage & storage;
    const StorageMetadataPtr metadata;
    const ColumnsDescription object_columns;

    /// Additional data, on which set of columns may depend.
    /// E.g. data parts in MergeTree, list of blocks in Memory, etc.
    struct Data
    {
        virtual ~Data() = default;
    };

    using DataPtr = std::unique_ptr<Data>;
    DataPtr data;

    /// Projection that is used in query.
    mutable const ProjectionDescription * projection = nullptr;

    StorageSnapshot(
        const IStorage & storage_,
        StorageMetadataPtr metadata_)
        : storage(storage_), metadata(std::move(metadata_))
    {
        init();
    }

    StorageSnapshot(
        const IStorage & storage_,
        StorageMetadataPtr metadata_,
        ColumnsDescription object_columns_)
        : storage(storage_)
        , metadata(std::move(metadata_))
        , object_columns(std::move(object_columns_))
    {
        init();
    }

    StorageSnapshot(
        const IStorage & storage_,
        StorageMetadataPtr metadata_,
        ColumnsDescription object_columns_,
        DataPtr data_)
        : storage(storage_)
        , metadata(std::move(metadata_))
        , object_columns(std::move(object_columns_))
        , data(std::move(data_))
    {
        init();
    }

    /// Get all available columns with types according to options.
    NamesAndTypesList getColumns(const GetColumnsOptions & options) const;

    /// Get columns with types according to options only for requested names.
    NamesAndTypesList getColumnsByNames(const GetColumnsOptions & options, const Names & names) const;

    /// Get column with type according to options for requested name.
    std::optional<NameAndTypePair> tryGetColumn(const GetColumnsOptions & options, const String & column_name) const;
    NameAndTypePair getColumn(const GetColumnsOptions & options, const String & column_name) const;

    /// Block with ordinary + materialized + aliases + virtuals + subcolumns.
    Block getSampleBlockForColumns(const Names & column_names) const;

    ColumnsDescription getDescriptionForColumns(const Names & column_names) const;

    /// Verify that all the requested names are in the table and are set correctly:
    /// list of names is not empty and the names do not repeat.
    void check(const Names & column_names) const;

    DataTypePtr getConcreteType(const String & column_name) const;

    void addProjection(const ProjectionDescription * projection_) const { projection = projection_; }

    /// If we have a projection then we should use its metadata.
    StorageMetadataPtr getMetadataForQuery() const { return projection ? projection->metadata : metadata; }

private:
    void init();

    std::unordered_map<String, DataTypePtr> virtual_columns;

    /// System columns are not visible in the schema but might be persisted in the data.
    /// One example of such column is lightweight delete mask '_row_exists'.
    std::unordered_map<String, DataTypePtr> system_columns;
};

using StorageSnapshotPtr = std::shared_ptr<StorageSnapshot>;

}