1#pragma once
2
3#include <Core/Field.h>
4#include <DataTypes/IDataType.h>
5#include <IO/ReadBufferFromString.h>
6#include <Interpreters/IExternalLoadable.h>
7#include <Poco/Util/AbstractConfiguration.h>
8
9#include <map>
10#include <optional>
11#include <string>
12#include <vector>
13
14
15namespace DB
16{
17
18namespace ErrorCodes
19{
20 extern const int TYPE_MISMATCH;
21}
22
23enum class AttributeUnderlyingType
24{
25 utUInt8,
26 utUInt16,
27 utUInt32,
28 utUInt64,
29 utUInt128,
30 utInt8,
31 utInt16,
32 utInt32,
33 utInt64,
34 utFloat32,
35 utFloat64,
36 utDecimal32,
37 utDecimal64,
38 utDecimal128,
39 utString
40};
41
42
43AttributeUnderlyingType getAttributeUnderlyingType(const std::string & type);
44
45std::string toString(const AttributeUnderlyingType type);
46
47/// Implicit conversions in dictGet functions is disabled.
48inline void checkAttributeType(const std::string & dict_name, const std::string & attribute_name,
49 AttributeUnderlyingType attribute_type, AttributeUnderlyingType to)
50{
51 if (attribute_type != to)
52 throw Exception{dict_name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute_type)
53 + ", expected " + toString(to), ErrorCodes::TYPE_MISMATCH};
54}
55
56/// Min and max lifetimes for a dictionary or it's entry
57using DictionaryLifetime = ExternalLoadableLifetime;
58
59
60/** Holds the description of a single dictionary attribute:
61* - name, used for lookup into dictionary and source;
62* - type, used in conjunction with DataTypeFactory and getAttributeUnderlyingTypeByname;
63* - null_value, used as a default value for non-existent entries in the dictionary,
64* decimal representation for numeric attributes;
65* - hierarchical, whether this attribute defines a hierarchy;
66* - injective, whether the mapping to parent is injective (can be used for optimization of GROUP BY?)
67* - is_object_id, used in mongo dictionary, converts string key to objectid
68*/
69struct DictionaryAttribute final
70{
71 const std::string name;
72 const AttributeUnderlyingType underlying_type;
73 const DataTypePtr type;
74 const std::string expression;
75 const Field null_value;
76 const bool hierarchical;
77 const bool injective;
78 const bool is_object_id;
79};
80
81
82struct DictionarySpecialAttribute final
83{
84 const std::string name;
85 const std::string expression;
86
87 DictionarySpecialAttribute(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix);
88};
89
90struct DictionaryTypedSpecialAttribute final
91{
92 const std::string name;
93 const std::string expression;
94 const DataTypePtr type;
95};
96
97
98/// Name of identifier plus list of attributes
99struct DictionaryStructure final
100{
101 std::optional<DictionarySpecialAttribute> id;
102 std::optional<std::vector<DictionaryAttribute>> key;
103 std::vector<DictionaryAttribute> attributes;
104 std::optional<DictionaryTypedSpecialAttribute> range_min;
105 std::optional<DictionaryTypedSpecialAttribute> range_max;
106 bool has_expressions = false;
107
108 DictionaryStructure(const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix);
109
110 void validateKeyTypes(const DataTypes & key_types) const;
111 std::string getKeyDescription() const;
112 bool isKeySizeFixed() const;
113 size_t getKeySize() const;
114
115private:
116 std::vector<DictionaryAttribute> getAttributes(
117 const Poco::Util::AbstractConfiguration & config,
118 const std::string & config_prefix,
119 const bool hierarchy_allowed = true,
120 const bool allow_null_values = true);
121};
122
123}
124