dbms: external tables: fixed error [#METR-10071].

This commit is contained in:
Alexey Milovidov 2014-04-22 22:35:40 +04:00
parent 4befbd1f20
commit 6bec60bb39
2 changed files with 31 additions and 57 deletions

View File

@ -1,6 +1,7 @@
#pragma once
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <DB/DataStreams/AsynchronousBlockInputStream.h>
#include <DB/Interpreters/Context.h>
#include <DB/IO/copyData.h>
@ -27,7 +28,7 @@ public:
/// Описание структуры таблицы: (имя столбца, имя типа данных)
std::vector<std::pair<std::string, std::string> > structure;
ReadBuffer *read_buffer;
std::unique_ptr<ReadBuffer> read_buffer;
Block sample_block;
virtual ~BaseExternalTable() {};
@ -36,7 +37,7 @@ public:
virtual void initReadBuffer() {};
/// Инициализировать sample_block по структуре таблицы сохраненной в structure
virtual void initSampleBlock(const Context &context)
virtual void initSampleBlock(const Context & context)
{
for (size_t i = 0; i < structure.size(); ++i)
{
@ -49,7 +50,7 @@ public:
}
/// Получить данные таблицы - пару (поток с содержимым таблицы, имя таблицы)
virtual ExternalTableData getData(const Context &context)
virtual ExternalTableData getData(const Context & context)
{
initReadBuffer();
initSampleBlock(context);
@ -67,7 +68,7 @@ protected:
format = "";
structure.clear();
sample_block = Block();
read_buffer = NULL;
read_buffer.reset();
}
/// Функция для отладочного вывода информации
@ -81,23 +82,10 @@ protected:
std::cerr << "\t" << structure[i].first << " " << structure[i].second << std::endl;
}
static std::vector<std::string> split(const std::string & s, const std::string &d)
static std::vector<std::string> split(const std::string & s, const std::string & d)
{
std::vector<std::string> res;
std::string now;
for (size_t i = 0; i < s.size(); ++i)
{
if (d.find(s[i]) != std::string::npos)
{
if (!now.empty())
res.push_back(now);
now = "";
continue;
}
now += s[i];
}
if (!now.empty())
res.push_back(now);
boost::split(res, s, boost::algorithm::is_any_of(d), boost::algorithm::token_compress_on);
return res;
}
@ -110,7 +98,7 @@ protected:
throw Exception("Odd number of attributes in section structure", ErrorCodes::BAD_ARGUMENTS);
for (size_t i = 0; i < vals.size(); i += 2)
structure.push_back(std::make_pair(vals[i], vals[i+1]));
structure.emplace_back(vals[i], vals[i + 1]);
}
/// Построить вектор structure по текстовому полю types
@ -119,7 +107,7 @@ protected:
std::vector<std::string> vals = split(argument, " ,");
for (size_t i = 0; i < vals.size(); ++i)
structure.push_back(std::make_pair("_" + toString(i + 1), vals[i]));
structure.emplace_back("_" + toString(i + 1), vals[i]);
}
};
@ -131,9 +119,9 @@ public:
void initReadBuffer()
{
if (file == "-")
read_buffer = new ReadBufferFromIStream(std::cin);
read_buffer.reset(new ReadBufferFromFileDescriptor(STDIN_FILENO));
else
read_buffer = new ReadBufferFromFile(file);
read_buffer.reset(new ReadBufferFromFile(file));
}
/// Извлечение параметров из variables_map, которая строится по командной строке клиента
@ -155,24 +143,9 @@ public:
throw Exception("--format field have not been provided for external table", ErrorCodes::BAD_ARGUMENTS);
if (external_options.count("structure"))
{
std::vector<std::string> temp = external_options["structure"].as<std::vector<std::string>>();
std::string argument;
for (size_t i = 0; i < temp.size(); ++i)
argument = argument + temp[i] + " ";
parseStructureFromStructureField(argument);
}
parseStructureFromStructureField(external_options["structure"].as<std::string>());
else if (external_options.count("types"))
{
std::vector<std::string> temp = external_options["types"].as<std::vector<std::string>>();
std::string argument;
for (size_t i = 0; i < temp.size(); ++i)
argument = argument + temp[i] + " ";
parseStructureFromTypesField(argument);
}
parseStructureFromTypesField(external_options["types"].as<std::string>());
else
throw Exception("Neither --structure nor --types have not been provided for external table", ErrorCodes::BAD_ARGUMENTS);
}
@ -191,7 +164,7 @@ public:
void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream)
{
/// Буфер инициализируется здесь, а не в виртуальной функции initReadBuffer
read_buffer = new ReadBufferFromIStream(stream);
read_buffer.reset(new ReadBufferFromIStream(stream));
/// Извлекаем коллекцию параметров из MessageHeader
Poco::Net::NameValueCollection content;

View File

@ -116,7 +116,7 @@ private:
bool written_first_block;
/// Информация о внешних таблицах
std::vector<ExternalTable> external_tables;
std::list<ExternalTable> external_tables;
void initialize(Poco::Util::Application & self)
@ -521,8 +521,9 @@ private:
throw Exception("External tables could be sent only with select query", ErrorCodes::BAD_ARGUMENTS);
std::vector<ExternalTableData> data;
for (size_t i = 0; i < external_tables.size(); ++i)
data.push_back(external_tables[i].getData(context));
for (auto & table : external_tables)
data.emplace_back(table.getData(context));
connection->sendExternalTablesData(data);
}
@ -898,13 +899,13 @@ public:
boost::program_options::options_description main_description("Main options");
main_description.add_options()
("help", "produce help message")
("config-file,c", boost::program_options::value<std::string> (), "config-file path")
("host,h", boost::program_options::value<std::string> ()->implicit_value("")->default_value("localhost"), "server host")
("port", boost::program_options::value<int> ()->default_value(9000), "server port")
("user,u", boost::program_options::value<std::string> (), "user")
("password", boost::program_options::value<std::string> (), "password")
("query,q", boost::program_options::value<std::string> (), "query")
("database,d", boost::program_options::value<std::string> (), "database")
("config-file,c", boost::program_options::value<std::string>(), "config-file path")
("host,h", boost::program_options::value<std::string>()->implicit_value("")->default_value("localhost"), "server host")
("port", boost::program_options::value<int>()->default_value(9000), "server port")
("user,u", boost::program_options::value<std::string>(), "user")
("password", boost::program_options::value<std::string>(), "password")
("query,q", boost::program_options::value<std::string>(), "query")
("database,d", boost::program_options::value<std::string>(), "database")
("multiline,m", "multiline")
("multiquery,n", "multiquery")
APPLY_FOR_SETTINGS(DECLARE_SETTING)
@ -916,11 +917,11 @@ public:
/// Перечисляем опции командной строки относящиеся к внешним таблицам
boost::program_options::options_description external_description("External tables options");
external_description.add_options()
("file", boost::program_options::value<std::string> (), "data file or - for stdin")
("name", boost::program_options::value<std::string> ()->default_value("_data"), "name of the table")
("format", boost::program_options::value<std::string> ()->default_value("TabSeparated"), "data format")
("structure", boost::program_options::value<std::vector<std::string>> ()->multitoken(), "structure")
("types", boost::program_options::value<std::vector<std::string>> ()->multitoken(), "types")
("file", boost::program_options::value<std::string>(), "data file or - for stdin")
("name", boost::program_options::value<std::string>()->default_value("_data"), "name of the table")
("format", boost::program_options::value<std::string>()->default_value("TabSeparated"), "data format")
("structure", boost::program_options::value<std::string>(), "structure")
("types", boost::program_options::value<std::string>(), "types")
;
/// Парсим основные опции командной строки
@ -966,7 +967,7 @@ public:
try
{
external_tables.push_back(ExternalTable(external_options));
external_tables.emplace_back(external_options);
if (external_tables.back().file == "-")
++stdin_count;
if (stdin_count > 1)