2018-11-28 11:37:12 +00:00
|
|
|
#include "DictionarySourceFactory.h"
|
2017-04-01 09:19:00 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
#include <Columns/ColumnsNumber.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Core/Block.h>
|
2018-11-28 11:37:12 +00:00
|
|
|
#include <Core/ColumnWithTypeAndName.h>
|
2018-09-13 13:33:44 +00:00
|
|
|
#include <DataTypes/DataTypeNullable.h>
|
2018-11-28 11:37:12 +00:00
|
|
|
#include <DataTypes/DataTypesNumber.h>
|
2017-11-27 17:34:43 +00:00
|
|
|
#include <Poco/Logger.h>
|
|
|
|
#include <common/logger_useful.h>
|
2018-11-28 11:37:12 +00:00
|
|
|
#include "DictionaryStructure.h"
|
2016-12-08 02:49:04 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
extern const int UNKNOWN_ELEMENT_IN_CONFIG;
|
|
|
|
extern const int EXCESSIVE_ELEMENT_IN_CONFIG;
|
|
|
|
extern const int LOGICAL_ERROR;
|
2016-12-08 02:49:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2018-11-28 11:37:12 +00:00
|
|
|
Block createSampleBlock(const DictionaryStructure & dict_struct)
|
|
|
|
{
|
|
|
|
Block block;
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
if (dict_struct.id)
|
2018-12-10 15:25:45 +00:00
|
|
|
block.insert(ColumnWithTypeAndName{ColumnUInt64::create(1, 0), std::make_shared<DataTypeUInt64>(), dict_struct.id->name});
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
if (dict_struct.key)
|
2017-04-01 07:20:54 +00:00
|
|
|
{
|
2018-11-28 11:37:12 +00:00
|
|
|
for (const auto & attribute : *dict_struct.key)
|
|
|
|
{
|
|
|
|
auto column = attribute.type->createColumn();
|
|
|
|
column->insertDefault();
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-12-10 15:25:45 +00:00
|
|
|
block.insert(ColumnWithTypeAndName{std::move(column), attribute.type, attribute.name});
|
2018-11-28 11:37:12 +00:00
|
|
|
}
|
2017-04-01 07:20:54 +00:00
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
if (dict_struct.range_min)
|
2018-09-13 13:33:44 +00:00
|
|
|
{
|
2018-11-28 11:37:12 +00:00
|
|
|
for (const auto & attribute : {dict_struct.range_min, dict_struct.range_max})
|
|
|
|
{
|
|
|
|
const auto & type = std::make_shared<DataTypeNullable>(attribute->type);
|
|
|
|
auto column = type->createColumn();
|
|
|
|
column->insertDefault();
|
|
|
|
|
2018-12-10 15:25:45 +00:00
|
|
|
block.insert(ColumnWithTypeAndName{std::move(column), type, attribute->name});
|
2018-11-28 11:37:12 +00:00
|
|
|
}
|
2018-09-13 13:33:44 +00:00
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
for (const auto & attribute : dict_struct.attributes)
|
|
|
|
{
|
|
|
|
auto column = attribute.type->createColumn();
|
|
|
|
column->insert(attribute.null_value);
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-12-10 15:25:45 +00:00
|
|
|
block.insert(ColumnWithTypeAndName{std::move(column), attribute.type, attribute.name});
|
2018-11-28 11:37:12 +00:00
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
return block;
|
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-28 11:37:12 +00:00
|
|
|
DictionarySourceFactory::DictionarySourceFactory() : log(&Poco::Logger::get("DictionarySourceFactory"))
|
2016-12-08 02:49:04 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-11-27 19:05:45 +00:00
|
|
|
void DictionarySourceFactory::registerSource(const std::string & source_type, Creator create_source)
|
2017-11-27 17:34:43 +00:00
|
|
|
{
|
2017-11-27 19:05:45 +00:00
|
|
|
if (!registered_sources.emplace(source_type, std::move(create_source)).second)
|
2018-11-28 11:37:12 +00:00
|
|
|
throw Exception("DictionarySourceFactory: the source name '" + source_type + "' is not unique", ErrorCodes::LOGICAL_ERROR);
|
2017-11-27 17:34:43 +00:00
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
|
|
|
DictionarySourcePtr DictionarySourceFactory::create(
|
2018-11-28 11:37:12 +00:00
|
|
|
const std::string & name,
|
|
|
|
const Poco::Util::AbstractConfiguration & config,
|
|
|
|
const std::string & config_prefix,
|
|
|
|
const DictionaryStructure & dict_struct,
|
2019-12-10 17:27:29 +00:00
|
|
|
const Context & context,
|
2020-08-15 03:10:57 +00:00
|
|
|
const std::string & default_database,
|
2019-12-10 17:27:29 +00:00
|
|
|
bool check_config) const
|
2016-12-08 02:49:04 +00:00
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
Poco::Util::AbstractConfiguration::Keys keys;
|
|
|
|
config.keys(config_prefix, keys);
|
2020-04-09 20:52:53 +00:00
|
|
|
|
2020-04-02 22:35:22 +00:00
|
|
|
if (keys.empty() || keys.size() > 2)
|
|
|
|
throw Exception{name + ": element dictionary.source should have one or two child elements",
|
2018-12-10 15:25:45 +00:00
|
|
|
ErrorCodes::EXCESSIVE_ELEMENT_IN_CONFIG};
|
2020-04-09 20:52:53 +00:00
|
|
|
|
2020-04-17 19:54:53 +00:00
|
|
|
const std::string & source_type = keys.front() == "settings" ? keys.back() : keys.front();
|
2017-04-01 07:20:54 +00:00
|
|
|
|
2019-06-02 12:11:01 +00:00
|
|
|
const auto found = registered_sources.find(source_type);
|
|
|
|
if (found != registered_sources.end())
|
2017-11-27 17:34:43 +00:00
|
|
|
{
|
2019-06-02 12:11:01 +00:00
|
|
|
const auto & create_source = found->second;
|
|
|
|
auto sample_block = createSampleBlock(dict_struct);
|
2020-08-15 03:10:57 +00:00
|
|
|
return create_source(dict_struct, config, config_prefix, sample_block, context, default_database, check_config);
|
2017-11-27 17:34:43 +00:00
|
|
|
}
|
2016-12-08 02:49:04 +00:00
|
|
|
|
2018-12-10 15:25:45 +00:00
|
|
|
throw Exception{name + ": unknown dictionary source type: " + source_type, ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG};
|
2016-12-08 02:49:04 +00:00
|
|
|
}
|
|
|
|
|
2019-08-22 03:24:05 +00:00
|
|
|
DictionarySourceFactory & DictionarySourceFactory::instance()
|
|
|
|
{
|
|
|
|
static DictionarySourceFactory instance;
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2016-12-08 02:49:04 +00:00
|
|
|
}
|