Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
3a668313
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3a668313
编写于
6月 07, 2016
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added implicit conversion to covering type for functions dictGetT [#METR-21527].
上级
7c8c2df5
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
365 addition
and
193 deletion
+365
-193
dbms/include/DB/Dictionaries/CacheDictionary.h
dbms/include/DB/Dictionaries/CacheDictionary.h
+61
-37
dbms/include/DB/Dictionaries/ComplexKeyCacheDictionary.h
dbms/include/DB/Dictionaries/ComplexKeyCacheDictionary.h
+54
-35
dbms/include/DB/Dictionaries/ComplexKeyHashedDictionary.h
dbms/include/DB/Dictionaries/ComplexKeyHashedDictionary.h
+55
-34
dbms/include/DB/Dictionaries/DictionaryStructure.h
dbms/include/DB/Dictionaries/DictionaryStructure.h
+41
-0
dbms/include/DB/Dictionaries/FlatDictionary.h
dbms/include/DB/Dictionaries/FlatDictionary.h
+58
-38
dbms/include/DB/Dictionaries/HashedDictionary.h
dbms/include/DB/Dictionaries/HashedDictionary.h
+56
-35
dbms/include/DB/Dictionaries/RangeHashedDictionary.h
dbms/include/DB/Dictionaries/RangeHashedDictionary.h
+40
-14
未找到文件。
dbms/include/DB/Dictionaries/CacheDictionary.h
浏览文件 @
3a668313
...
...
@@ -46,8 +46,7 @@ public:
if
(
!
this
->
source_ptr
->
supportsSelectiveLoad
())
throw
Exception
{
name
+
": source cannot be used with CacheDictionary"
,
ErrorCodes
::
UNSUPPORTED_METHOD
};
ErrorCodes
::
UNSUPPORTED_METHOD
};
createAttributes
();
}
...
...
@@ -105,22 +104,21 @@ public:
{
const
auto
null_value
=
std
::
get
<
UInt64
>
(
hierarchical_attribute
->
null_values
);
getItems
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
getItems
Number
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
#define DECLARE(TYPE)\
void get##TYPE(const std::string & attribute_name, const PaddedPODArray<id_t> & ids, PaddedPODArray<TYPE> & out) const\
{\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
const auto null_value = std::get<TYPE>(attribute.null_values);\
\
getItems<TYPE>(attribute, ids, out, [&] (const std::size_t) { return null_value; });\
getItems
Number
<TYPE>(attribute, ids, out, [&] (const std::size_t) { return null_value; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -136,15 +134,14 @@ public:
void
getString
(
const
std
::
string
&
attribute_name
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ColumnString
*
out
)
const
{
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
null_value
=
StringRef
{
std
::
get
<
String
>
(
attribute
.
null_values
)};
getItems
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
getItems
String
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
#define DECLARE(TYPE)\
...
...
@@ -153,13 +150,12 @@ public:
PaddedPODArray<TYPE> & out) const\
{\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids, out, [&] (const std::size_t row) { return def[row]; });\
getItems
Number
<TYPE>(attribute, ids, out, [&] (const std::size_t row) { return def[row]; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -177,13 +173,12 @@ public:
ColumnString
*
const
out
)
const
{
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
getItems
String
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
}
#define DECLARE(TYPE)\
...
...
@@ -191,13 +186,12 @@ public:
const std::string & attribute_name, const PaddedPODArray<id_t> & ids, const TYPE def, PaddedPODArray<TYPE> & out) const\
{\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids, out, [&] (const std::size_t) { return def; });\
getItems
Number
<TYPE>(attribute, ids, out, [&] (const std::size_t) { return def; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -215,13 +209,12 @@ public:
ColumnString
*
const
out
)
const
{
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
getItems
String
(
attribute
,
ids
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
}
void
has
(
const
PaddedPODArray
<
id_t
>
&
ids
,
PaddedPODArray
<
UInt8
>
&
out
)
const
override
...
...
@@ -333,8 +326,7 @@ private:
if
(
hierarchical_attribute
->
type
!=
AttributeUnderlyingType
::
UInt64
)
throw
Exception
{
name
+
": hierarchical attribute must be UInt64."
,
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
}
}
}
...
...
@@ -407,13 +399,43 @@ private:
return
attr
;
}
template
<
typename
T
,
typename
DefaultGetter
>
void
getItems
(
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
PaddedPODArray
<
T
>
&
out
,
DefaultGetter
&&
get_default
)
const
template
<
typename
OutputType
,
typename
DefaultGetter
>
void
getItemsNumber
(
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
PaddedPODArray
<
OutputType
>
&
out
,
DefaultGetter
&&
get_default
)
const
{
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsNumberImpl<TYPE, OutputType>(attribute, ids, out, std::forward<DefaultGetter>(get_default));
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
,
typename
DefaultGetter
>
void
getItemsNumberImpl
(
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
PaddedPODArray
<
OutputType
>
&
out
,
DefaultGetter
&&
get_default
)
const
{
/// Mapping: <id> -> { all indices `i` of `ids` such that `ids[i]` = <id> }
MapType
<
std
::
vector
<
std
::
size_t
>>
outdated_ids
;
auto
&
attribute_array
=
std
::
get
<
ContainerPtrType
<
T
>>
(
attribute
.
arrays
);
auto
&
attribute_array
=
std
::
get
<
ContainerPtrType
<
OutputType
>>
(
attribute
.
arrays
);
const
auto
rows
=
ext
::
size
(
ids
);
{
...
...
@@ -461,8 +483,11 @@ private:
}
template
<
typename
DefaultGetter
>
void
getItems
(
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ColumnString
*
out
,
DefaultGetter
&&
get_default
)
const
void
getItemsString
(
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ColumnString
*
out
,
DefaultGetter
&&
get_default
)
const
{
const
auto
rows
=
ext
::
size
(
ids
);
...
...
@@ -598,8 +623,7 @@ private:
if
(
!
id_column
)
throw
Exception
{
name
+
": id column has type different from UInt64."
,
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
&
ids
=
id_column
->
getData
();
...
...
dbms/include/DB/Dictionaries/ComplexKeyCacheDictionary.h
浏览文件 @
3a668313
...
...
@@ -46,8 +46,7 @@ public:
if
(
!
this
->
source_ptr
->
supportsSelectiveLoad
())
throw
Exception
{
name
+
": source cannot be used with ComplexKeyCacheDictionary"
,
ErrorCodes
::
UNSUPPORTED_METHOD
};
ErrorCodes
::
UNSUPPORTED_METHOD
};
createAttributes
();
}
...
...
@@ -115,15 +114,14 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
const auto null_value = std::get<TYPE>(attribute.null_values);\
\
getItems<TYPE>(attribute, key_columns, out, [&] (const std::size_t) { return null_value; });\
getItems
Number
<TYPE>(attribute, key_columns, out, [&] (const std::size_t) { return null_value; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -143,15 +141,14 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
null_value
=
StringRef
{
std
::
get
<
String
>
(
attribute
.
null_values
)};
getItems
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
getItems
String
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
#define DECLARE(TYPE)\
...
...
@@ -162,13 +159,12 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, key_columns, out, [&] (const std::size_t row) { return def[row]; });\
getItems
Number
<TYPE>(attribute, key_columns, out, [&] (const std::size_t row) { return def[row]; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -188,13 +184,12 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
getItems
String
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
}
#define DECLARE(TYPE)\
...
...
@@ -205,13 +200,12 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, key_columns, out, [&] (const std::size_t) { return def; });\
getItems
Number
<TYPE>(attribute, key_columns, out, [&] (const std::size_t) { return def; });\
}
DECLARE
(
UInt8
)
DECLARE
(
UInt16
)
...
...
@@ -231,13 +225,12 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
getItems
String
(
attribute
,
key_columns
,
out
,
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
}
void
has
(
const
ConstColumnPlainPtrs
&
key_columns
,
const
DataTypes
&
key_types
,
PaddedPODArray
<
UInt8
>
&
out
)
const
...
...
@@ -355,8 +348,7 @@ private:
if
(
attribute
.
hierarchical
)
throw
Exception
{
name
+
": hierarchical attributes not supported for dictionary of type "
+
getTypeName
(),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
}
}
...
...
@@ -428,14 +420,42 @@ private:
return
attr
;
}
template
<
typename
T
,
typename
DefaultGetter
>
void
getItems
(
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
PaddedPODArray
<
T
>
&
out
,
template
<
typename
OutputType
,
typename
DefaultGetter
>
void
getItemsNumber
(
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
PaddedPODArray
<
OutputType
>
&
out
,
DefaultGetter
&&
get_default
)
const
{
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsNumberImpl<TYPE, OutputType>(attribute, key_columns, out, std::forward<DefaultGetter>(get_default));
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
,
typename
DefaultGetter
>
void
getItemsNumberImpl
(
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
PaddedPODArray
<
OutputType
>
&
out
,
DefaultGetter
&&
get_default
)
const
{
/// Mapping: <key> -> { all indices `i` of `key_columns` such that `key_columns[i]` = <key> }
MapType
<
std
::
vector
<
std
::
size_t
>>
outdated_keys
;
auto
&
attribute_array
=
std
::
get
<
ContainerPtrType
<
T
>>
(
attribute
.
arrays
);
auto
&
attribute_array
=
std
::
get
<
ContainerPtrType
<
AttributeType
>>
(
attribute
.
arrays
);
const
auto
rows
=
key_columns
.
front
()
->
size
();
const
auto
keys_size
=
dict_struct
.
key
.
value
().
size
();
...
...
@@ -488,7 +508,7 @@ private:
}
template
<
typename
DefaultGetter
>
void
getItems
(
void
getItems
String
(
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
ColumnString
*
out
,
DefaultGetter
&&
get_default
)
const
{
...
...
@@ -827,8 +847,7 @@ private:
if
(
it
==
std
::
end
(
attribute_index_by_name
))
throw
Exception
{
name
+
": no such attribute '"
+
attribute_name
+
"'"
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
return
attributes
[
it
->
second
];
}
...
...
dbms/include/DB/Dictionaries/ComplexKeyHashedDictionary.h
浏览文件 @
3a668313
...
...
@@ -98,15 +98,14 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
const auto null_value = std::get<TYPE>(attribute.null_values);\
\
getItems<TYPE>(attribute, key_columns,\
getItems
Number
<TYPE>(attribute, key_columns,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return null_value; });\
}
...
...
@@ -128,15 +127,14 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
&
null_value
=
StringRef
{
std
::
get
<
String
>
(
attribute
.
null_values
)};
getItems
<
StringRef
>
(
attribute
,
key_columns
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
key_columns
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
...
...
@@ -149,13 +147,12 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, key_columns,\
getItems
Number
<TYPE>(attribute, key_columns,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t row) { return def[row]; });\
}
...
...
@@ -177,13 +174,12 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
key_columns
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
key_columns
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
}
...
...
@@ -196,13 +192,12 @@ public:
dict_struct.validateKeyTypes(key_types);\
\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, key_columns,\
getItems
Number
<TYPE>(attribute, key_columns,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return def; });\
}
...
...
@@ -224,13 +219,12 @@ public:
dict_struct
.
validateKeyTypes
(
key_types
);
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
key_columns
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
key_columns
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
}
...
...
@@ -290,8 +284,7 @@ private:
if
(
attribute
.
hierarchical
)
throw
Exception
{
name
+
": hierarchical attributes not supported for dictionary of type "
+
getTypeName
(),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
}
}
...
...
@@ -349,8 +342,7 @@ private:
if
(
require_nonempty
&&
0
==
element_count
)
throw
Exception
{
name
+
": dictionary source is empty and 'require_nonempty' property is set."
,
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
}
template
<
typename
T
>
...
...
@@ -427,12 +419,41 @@ private:
return
attr
;
}
template
<
typename
T
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItems
(
const
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
ValueSetter
&&
set_value
,
template
<
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsNumber
(
const
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
const
auto
&
attr
=
*
std
::
get
<
ContainerPtrType
<
T
>>
(
attribute
.
maps
);
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsImpl<TYPE, OutputType>(attribute, key_columns, std::forward<ValueSetter>(set_value), std::forward<DefaultGetter>(get_default));
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsImpl
(
const
attribute_t
&
attribute
,
const
ConstColumnPlainPtrs
&
key_columns
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
const
auto
&
attr
=
*
std
::
get
<
ContainerPtrType
<
AttributeType
>>
(
attribute
.
maps
);
const
auto
keys_size
=
key_columns
.
size
();
StringRefs
keys
(
keys_size
);
...
...
@@ -454,6 +475,7 @@ private:
query_count
.
fetch_add
(
rows
,
std
::
memory_order_relaxed
);
}
template
<
typename
T
>
bool
setAttributeValueImpl
(
attribute_t
&
attribute
,
const
StringRef
key
,
const
T
value
)
{
...
...
@@ -495,8 +517,7 @@ private:
if
(
it
==
std
::
end
(
attribute_index_by_name
))
throw
Exception
{
name
+
": no such attribute '"
+
attribute_name
+
"'"
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
return
attributes
[
it
->
second
];
}
...
...
dbms/include/DB/Dictionaries/DictionaryStructure.h
浏览文件 @
3a668313
...
...
@@ -39,6 +39,47 @@ enum class AttributeUnderlyingType
String
};
/** Для неявных преобразований в функциях dictGet.
*/
inline
bool
isAttributeTypeConvertibleTo
(
AttributeUnderlyingType
from
,
AttributeUnderlyingType
to
)
{
if
(
from
==
to
)
return
true
;
/** Это перечисление может быть несколько неполным и смысл может не совпадать с NumberTraits.h.
* (например тем, что целые числа нельзя преобразовать во float-ы)
* Это нормально для ограниченной области применения.
*/
if
(
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
UInt16
)
||
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
UInt32
)
||
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
UInt64
)
||
(
from
==
AttributeUnderlyingType
::
UInt16
&&
to
==
AttributeUnderlyingType
::
UInt32
)
||
(
from
==
AttributeUnderlyingType
::
UInt16
&&
to
==
AttributeUnderlyingType
::
UInt64
)
||
(
from
==
AttributeUnderlyingType
::
UInt32
&&
to
==
AttributeUnderlyingType
::
UInt64
)
||
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
Int16
)
||
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
Int32
)
||
(
from
==
AttributeUnderlyingType
::
UInt8
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
UInt16
&&
to
==
AttributeUnderlyingType
::
Int32
)
||
(
from
==
AttributeUnderlyingType
::
UInt16
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
UInt32
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
Int8
&&
to
==
AttributeUnderlyingType
::
Int16
)
||
(
from
==
AttributeUnderlyingType
::
Int8
&&
to
==
AttributeUnderlyingType
::
Int32
)
||
(
from
==
AttributeUnderlyingType
::
Int8
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
Int16
&&
to
==
AttributeUnderlyingType
::
Int32
)
||
(
from
==
AttributeUnderlyingType
::
Int16
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
Int32
&&
to
==
AttributeUnderlyingType
::
Int64
)
||
(
from
==
AttributeUnderlyingType
::
Float32
&&
to
==
AttributeUnderlyingType
::
Float64
))
{
return
true
;
}
return
false
;
}
inline
AttributeUnderlyingType
getAttributeUnderlyingType
(
const
std
::
string
&
type
)
{
static
const
std
::
unordered_map
<
std
::
string
,
AttributeUnderlyingType
>
dictionary
{
...
...
dbms/include/DB/Dictionaries/FlatDictionary.h
浏览文件 @
3a668313
...
...
@@ -97,7 +97,7 @@ public:
{
const
auto
null_value
=
std
::
get
<
UInt64
>
(
hierarchical_attribute
->
null_values
);
getItems
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
getItems
Number
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
UInt64
value
)
{
out
[
row
]
=
value
;
},
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
...
...
@@ -106,15 +106,14 @@ public:
void get##TYPE(const std::string & attribute_name, const PaddedPODArray<id_t> & ids, PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
const auto null_value = std::get<TYPE>(attribute.null_values);\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return null_value; });\
}
...
...
@@ -132,15 +131,14 @@ public:
void
getString
(
const
std
::
string
&
attribute_name
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ColumnString
*
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
&
null_value
=
StringRef
{
std
::
get
<
String
>
(
attribute
.
null_values
)};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
...
...
@@ -151,13 +149,12 @@ public:
PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t row) { return def[row]; });\
}
...
...
@@ -177,13 +174,12 @@ public:
ColumnString
*
const
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
}
...
...
@@ -194,13 +190,12 @@ public:
PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return def; });\
}
...
...
@@ -220,13 +215,12 @@ public:
ColumnString
*
const
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
}
...
...
@@ -288,8 +282,7 @@ private:
if
(
hierarchical_attribute
->
type
!=
AttributeUnderlyingType
::
UInt64
)
throw
Exception
{
name
+
": hierarchical attribute must be UInt64."
,
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
}
}
}
...
...
@@ -320,8 +313,7 @@ private:
if
(
require_nonempty
&&
0
==
element_count
)
throw
Exception
{
name
+
": dictionary source is empty and 'require_nonempty' property is set."
,
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
}
template
<
typename
T
>
...
...
@@ -399,14 +391,43 @@ private:
return
attr
;
}
template
<
typename
T
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItems
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
template
<
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsNumber
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsImpl<TYPE, OutputType>(attribute, ids, std::forward<ValueSetter>(set_value), std::forward<DefaultGetter>(get_default));
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsImpl
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
const
auto
&
attr
=
*
std
::
get
<
ContainerPtrType
<
T
>>
(
attribute
.
arrays
);
const
auto
&
attr
=
*
std
::
get
<
ContainerPtrType
<
AttributeType
>>
(
attribute
.
arrays
);
const
auto
rows
=
ext
::
size
(
ids
);
using
null_value_type
=
std
::
conditional_t
<
std
::
is_same
<
T
,
StringRef
>::
value
,
String
,
T
>
;
using
null_value_type
=
std
::
conditional_t
<
std
::
is_same
<
AttributeType
,
StringRef
>::
value
,
String
,
AttributeType
>
;
const
auto
null_value
=
std
::
get
<
null_value_type
>
(
attribute
.
null_values
);
for
(
const
auto
row
:
ext
::
range
(
0
,
rows
))
...
...
@@ -418,6 +439,7 @@ private:
query_count
.
fetch_add
(
rows
,
std
::
memory_order_relaxed
);
}
template
<
typename
T
>
void
setAttributeValueImpl
(
attribute_t
&
attribute
,
const
id_t
id
,
const
T
value
)
{
...
...
@@ -432,8 +454,7 @@ private:
if
(
id
>=
max_array_size
)
throw
Exception
{
name
+
": identifier should be less than "
+
toString
(
max_array_size
),
ErrorCodes
::
ARGUMENT_OUT_OF_BOUND
};
ErrorCodes
::
ARGUMENT_OUT_OF_BOUND
};
switch
(
attribute
.
type
)
{
...
...
@@ -466,8 +487,7 @@ private:
if
(
it
==
std
::
end
(
attribute_index_by_name
))
throw
Exception
{
name
+
": no such attribute '"
+
attribute_name
+
"'"
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
return
attributes
[
it
->
second
];
}
...
...
dbms/include/DB/Dictionaries/HashedDictionary.h
浏览文件 @
3a668313
...
...
@@ -92,7 +92,7 @@ public:
{
const
auto
null_value
=
std
::
get
<
UInt64
>
(
hierarchical_attribute
->
null_values
);
getItems
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
getItems
Number
<
UInt64
>
(
*
hierarchical_attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
UInt64
value
)
{
out
[
row
]
=
value
;
},
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
...
...
@@ -101,15 +101,14 @@ public:
void get##TYPE(const std::string & attribute_name, const PaddedPODArray<id_t> & ids, PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
const auto null_value = std::get<TYPE>(attribute.null_values);\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return null_value; });\
}
...
...
@@ -127,15 +126,14 @@ public:
void
getString
(
const
std
::
string
&
attribute_name
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ColumnString
*
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
const
auto
&
null_value
=
StringRef
{
std
::
get
<
String
>
(
attribute
.
null_values
)};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
null_value
;
});
}
...
...
@@ -146,13 +144,12 @@ public:
PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t row) { return def[row]; });\
}
...
...
@@ -172,13 +169,12 @@ public:
ColumnString
*
const
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
row
)
{
return
def
->
getDataAt
(
row
);
});
}
...
...
@@ -188,13 +184,12 @@ public:
const std::string & attribute_name, const PaddedPODArray<id_t> & ids, const TYPE & def, PaddedPODArray<TYPE> & out) const\
{\
const auto & attribute = getAttribute(attribute_name);\
if (
attribute.type != AttributeUnderlyingType::TYPE
)\
if (
!isAttributeTypeConvertibleTo(attribute.type, AttributeUnderlyingType::TYPE)
)\
throw Exception{\
name + ": type mismatch: attribute " + attribute_name + " has type " + toString(attribute.type),\
ErrorCodes::TYPE_MISMATCH\
};\
ErrorCodes::TYPE_MISMATCH};\
\
getItems<TYPE>(attribute, ids,\
getItems
Number
<TYPE>(attribute, ids,\
[&] (const std::size_t row, const auto value) { out[row] = value; },\
[&] (const std::size_t) { return def; });\
}
...
...
@@ -214,13 +209,12 @@ public:
ColumnString
*
const
out
)
const
{
const
auto
&
attribute
=
getAttribute
(
attribute_name
);
if
(
attribute
.
type
!=
AttributeUnderlyingType
::
String
)
if
(
!
isAttributeTypeConvertibleTo
(
attribute
.
type
,
AttributeUnderlyingType
::
String
)
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
attribute_name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
getItems
<
StringRef
>
(
attribute
,
ids
,
getItems
Impl
<
StringRef
,
StringRef
>
(
attribute
,
ids
,
[
&
]
(
const
std
::
size_t
row
,
const
StringRef
value
)
{
out
->
insertData
(
value
.
data
,
value
.
size
);
},
[
&
]
(
const
std
::
size_t
)
{
return
StringRef
{
def
};
});
}
...
...
@@ -282,8 +276,7 @@ private:
if
(
hierarchical_attribute
->
type
!=
AttributeUnderlyingType
::
UInt64
)
throw
Exception
{
name
+
": hierarchical attribute must be UInt64."
,
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
}
}
}
...
...
@@ -314,8 +307,7 @@ private:
if
(
require_nonempty
&&
0
==
element_count
)
throw
Exception
{
name
+
": dictionary source is empty and 'require_nonempty' property is set."
,
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
}
template
<
typename
T
>
...
...
@@ -390,12 +382,41 @@ private:
return
attr
;
}
template
<
typename
T
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItems
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
template
<
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsNumber
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
const
auto
&
attr
=
*
std
::
get
<
CollectionPtrType
<
T
>>
(
attribute
.
maps
);
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsImpl<TYPE, OutputType>(attribute, ids, std::forward<ValueSetter>(set_value), std::forward<DefaultGetter>(get_default));
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
,
typename
ValueSetter
,
typename
DefaultGetter
>
void
getItemsImpl
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
ValueSetter
&&
set_value
,
DefaultGetter
&&
get_default
)
const
{
const
auto
&
attr
=
*
std
::
get
<
CollectionPtrType
<
AttributeType
>>
(
attribute
.
maps
);
const
auto
rows
=
ext
::
size
(
ids
);
for
(
const
auto
i
:
ext
::
range
(
0
,
rows
))
...
...
@@ -407,6 +428,7 @@ private:
query_count
.
fetch_add
(
rows
,
std
::
memory_order_relaxed
);
}
template
<
typename
T
>
void
setAttributeValueImpl
(
attribute_t
&
attribute
,
const
id_t
id
,
const
T
value
)
{
...
...
@@ -445,8 +467,7 @@ private:
if
(
it
==
std
::
end
(
attribute_index_by_name
))
throw
Exception
{
name
+
": no such attribute '"
+
attribute_name
+
"'"
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
return
attributes
[
it
->
second
];
}
...
...
dbms/include/DB/Dictionaries/RangeHashedDictionary.h
浏览文件 @
3a668313
...
...
@@ -188,8 +188,7 @@ private:
if
(
attribute
.
hierarchical
)
throw
Exception
{
name
+
": hierarchical attributes not supported by "
+
getName
()
+
" dictionary."
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
}
}
...
...
@@ -223,8 +222,7 @@ private:
if
(
require_nonempty
&&
0
==
element_count
)
throw
Exception
{
name
+
": dictionary source is empty and 'require_nonempty' property is set."
,
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
ErrorCodes
::
DICTIONARY_IS_EMPTY
};
}
template
<
typename
T
>
...
...
@@ -299,13 +297,42 @@ private:
return
attr
;
}
template
<
typename
T
>
template
<
typename
OutputType
>
void
getItems
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
const
PaddedPODArray
<
UInt16
>
&
dates
,
PaddedPODArray
<
T
>
&
out
)
const
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
const
PaddedPODArray
<
UInt16
>
&
dates
,
PaddedPODArray
<
OutputType
>
&
out
)
const
{
const
auto
&
attr
=
*
std
::
get
<
ptr_t
<
T
>>
(
attribute
.
maps
);
const
auto
null_value
=
std
::
get
<
T
>
(
attribute
.
null_values
);
if
(
false
)
{}
#define DISPATCH(TYPE) \
else if (attribute.type == AttributeUnderlyingType::TYPE) \
getItemsImpl<TYPE, OutputType>(attribute, ids, dates, out);
DISPATCH
(
UInt8
)
DISPATCH
(
UInt16
)
DISPATCH
(
UInt32
)
DISPATCH
(
UInt64
)
DISPATCH
(
Int8
)
DISPATCH
(
Int16
)
DISPATCH
(
Int32
)
DISPATCH
(
Int64
)
DISPATCH
(
Float32
)
DISPATCH
(
Float64
)
#undef DISPATCH
else
throw
Exception
(
"Unexpected type of attribute: "
+
toString
(
attribute
.
type
),
ErrorCodes
::
LOGICAL_ERROR
);
}
template
<
typename
AttributeType
,
typename
OutputType
>
void
getItemsImpl
(
const
attribute_t
&
attribute
,
const
PaddedPODArray
<
id_t
>
&
ids
,
const
PaddedPODArray
<
UInt16
>
&
dates
,
PaddedPODArray
<
OutputType
>
&
out
)
const
{
const
auto
&
attr
=
*
std
::
get
<
ptr_t
<
AttributeType
>>
(
attribute
.
maps
);
const
auto
null_value
=
std
::
get
<
AttributeType
>
(
attribute
.
null_values
);
for
(
const
auto
i
:
ext
::
range
(
0
,
ids
.
size
()))
{
...
...
@@ -315,7 +342,7 @@ private:
const
auto
date
=
dates
[
i
];
const
auto
&
ranges_and_values
=
it
->
second
;
const
auto
val_it
=
std
::
find_if
(
std
::
begin
(
ranges_and_values
),
std
::
end
(
ranges_and_values
),
[
date
]
(
const
value_t
<
T
>
&
v
)
{
return
v
.
range
.
contains
(
date
);
});
[
date
]
(
const
value_t
<
AttributeType
>
&
v
)
{
return
v
.
range
.
contains
(
date
);
});
out
[
i
]
=
val_it
!=
std
::
end
(
ranges_and_values
)
?
val_it
->
value
:
null_value
;
}
...
...
@@ -326,6 +353,7 @@ private:
query_count
.
fetch_add
(
ids
.
size
(),
std
::
memory_order_relaxed
);
}
template
<
typename
T
>
void
setAttributeValueImpl
(
attribute_t
&
attribute
,
const
id_t
id
,
const
range_t
&
range
,
const
T
value
)
{
...
...
@@ -395,8 +423,7 @@ private:
if
(
it
==
std
::
end
(
attribute_index_by_name
))
throw
Exception
{
name
+
": no such attribute '"
+
attribute_name
+
"'"
,
ErrorCodes
::
BAD_ARGUMENTS
};
ErrorCodes
::
BAD_ARGUMENTS
};
return
attributes
[
it
->
second
];
}
...
...
@@ -407,8 +434,7 @@ private:
if
(
attribute
.
type
!=
type
)
throw
Exception
{
name
+
": type mismatch: attribute "
+
name
+
" has type "
+
toString
(
attribute
.
type
),
ErrorCodes
::
TYPE_MISMATCH
};
ErrorCodes
::
TYPE_MISMATCH
};
return
attribute
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录