2012-09-05 19:51:09 +00:00
|
|
|
|
#include <Poco/Util/Application.h>
|
|
|
|
|
#include <Poco/Util/AbstractConfiguration.h>
|
|
|
|
|
|
2012-05-22 19:32:56 +00:00
|
|
|
|
#include <DB/Parsers/ASTCreateQuery.h>
|
|
|
|
|
#include <DB/Parsers/ASTIdentifier.h>
|
2012-05-30 05:53:09 +00:00
|
|
|
|
#include <DB/Parsers/ASTLiteral.h>
|
2012-05-22 19:32:56 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/Interpreters/Context.h>
|
|
|
|
|
|
2011-10-31 17:30:44 +00:00
|
|
|
|
#include <DB/Storages/StorageLog.h>
|
2012-06-25 00:17:19 +00:00
|
|
|
|
#include <DB/Storages/StorageTinyLog.h>
|
2011-10-31 17:55:06 +00:00
|
|
|
|
#include <DB/Storages/StorageMemory.h>
|
2012-05-30 05:53:09 +00:00
|
|
|
|
#include <DB/Storages/StorageMerge.h>
|
2012-07-18 19:30:33 +00:00
|
|
|
|
#include <DB/Storages/StorageMergeTree.h>
|
2012-05-22 19:32:56 +00:00
|
|
|
|
#include <DB/Storages/StorageDistributed.h>
|
2011-10-31 17:30:44 +00:00
|
|
|
|
#include <DB/Storages/StorageSystemNumbers.h>
|
|
|
|
|
#include <DB/Storages/StorageSystemOne.h>
|
|
|
|
|
#include <DB/Storages/StorageFactory.h>
|
2013-10-30 13:52:02 +00:00
|
|
|
|
#include <DB/Storages/StorageView.h>
|
2013-11-08 17:43:03 +00:00
|
|
|
|
#include <DB/Storages/StorageMaterializedView.h>
|
2013-02-07 13:03:19 +00:00
|
|
|
|
#include <DB/Storages/StorageChunks.h>
|
2013-02-07 13:40:59 +00:00
|
|
|
|
#include <DB/Storages/StorageChunkRef.h>
|
2013-02-11 09:19:48 +00:00
|
|
|
|
#include <DB/Storages/StorageChunkMerger.h>
|
2011-10-31 17:30:44 +00:00
|
|
|
|
|
2013-07-16 14:55:01 +00:00
|
|
|
|
#include <DB/DataTypes/DataTypeArray.h>
|
|
|
|
|
#include <DB/DataTypes/DataTypeNested.h>
|
|
|
|
|
|
2011-10-31 17:30:44 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
StoragePtr StorageFactory::get(
|
|
|
|
|
const String & name,
|
|
|
|
|
const String & data_path,
|
|
|
|
|
const String & table_name,
|
2013-02-07 13:03:19 +00:00
|
|
|
|
const String & database_name,
|
2012-05-22 19:32:56 +00:00
|
|
|
|
Context & context,
|
|
|
|
|
ASTPtr & query,
|
2013-01-17 20:21:03 +00:00
|
|
|
|
NamesAndTypesListPtr columns,
|
|
|
|
|
bool attach) const
|
2011-10-31 17:30:44 +00:00
|
|
|
|
{
|
2013-08-14 16:52:40 +00:00
|
|
|
|
columns = DataTypeNested::expandNestedColumns(*columns);
|
2013-07-16 14:55:01 +00:00
|
|
|
|
|
2011-10-31 17:30:44 +00:00
|
|
|
|
if (name == "Log")
|
2012-05-22 19:32:56 +00:00
|
|
|
|
{
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageLog::create(data_path, table_name, columns);
|
2012-06-25 00:17:19 +00:00
|
|
|
|
}
|
2013-02-07 13:03:19 +00:00
|
|
|
|
else if (name == "Chunks")
|
|
|
|
|
{
|
2013-02-08 17:06:29 +00:00
|
|
|
|
return StorageChunks::create(data_path, table_name, database_name, columns, context, attach);
|
2013-02-07 13:03:19 +00:00
|
|
|
|
}
|
2013-02-07 13:40:59 +00:00
|
|
|
|
else if (name == "ChunkRef")
|
|
|
|
|
{
|
2013-06-17 07:01:31 +00:00
|
|
|
|
throw Exception("Table with storage ChunkRef must not be created manually.", ErrorCodes::TABLE_MUST_NOT_BE_CREATED_MANUALLY);
|
2013-11-08 17:43:03 +00:00
|
|
|
|
}
|
|
|
|
|
else if (name == "View")
|
|
|
|
|
{
|
|
|
|
|
return StorageView::create(table_name, database_name, context, query, columns);
|
|
|
|
|
}
|
|
|
|
|
else if (name == "MaterializedView")
|
2013-10-30 13:52:02 +00:00
|
|
|
|
{
|
2013-11-08 17:43:03 +00:00
|
|
|
|
return StorageMaterializedView::create(table_name, database_name, context, query, columns, attach);
|
2013-02-07 13:40:59 +00:00
|
|
|
|
}
|
2013-02-11 09:19:48 +00:00
|
|
|
|
else if (name == "ChunkMerger")
|
|
|
|
|
{
|
|
|
|
|
ASTs & args_func = dynamic_cast<ASTFunction &>(*dynamic_cast<ASTCreateQuery &>(*query).storage).children;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (args_func.size() != 1)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ASTs & args = dynamic_cast<ASTExpressionList &>(*args_func.at(0)).children;
|
|
|
|
|
|
2013-06-17 07:01:31 +00:00
|
|
|
|
if (args.size() < 3 || args.size() > 4)
|
2013-02-11 09:19:48 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
String source_database = dynamic_cast<ASTIdentifier &>(*args[0]).name;
|
|
|
|
|
String source_table_name_regexp = safeGet<const String &>(dynamic_cast<ASTLiteral &>(*args[1]).value);
|
2013-03-14 11:43:43 +00:00
|
|
|
|
size_t chunks_to_merge = safeGet<UInt64>(dynamic_cast<ASTLiteral &>(*args[2]).value);
|
|
|
|
|
|
|
|
|
|
String destination_name_prefix = "group_";
|
|
|
|
|
String destination_database = source_database;
|
|
|
|
|
|
|
|
|
|
if (args.size() > 3)
|
|
|
|
|
destination_name_prefix = dynamic_cast<ASTIdentifier &>(*args[3]).name;
|
2013-02-11 09:19:48 +00:00
|
|
|
|
|
2013-06-17 07:01:31 +00:00
|
|
|
|
return StorageChunkMerger::create(database_name, table_name, columns, source_database, source_table_name_regexp, destination_name_prefix, chunks_to_merge, context);
|
2013-02-11 09:19:48 +00:00
|
|
|
|
} while(false);
|
|
|
|
|
|
2013-06-17 07:01:31 +00:00
|
|
|
|
throw Exception("Storage ChunkMerger requires from 3 to 4 parameters:"
|
|
|
|
|
" source database, regexp for source table names, number of chunks to merge, [destination tables name prefix].",
|
2013-02-11 09:19:48 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
}
|
2012-06-25 00:51:23 +00:00
|
|
|
|
else if (name == "TinyLog")
|
2012-06-25 00:17:19 +00:00
|
|
|
|
{
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageTinyLog::create(data_path, table_name, columns, attach);
|
2012-05-22 19:32:56 +00:00
|
|
|
|
}
|
2011-10-31 17:55:06 +00:00
|
|
|
|
else if (name == "Memory")
|
2012-05-22 19:32:56 +00:00
|
|
|
|
{
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageMemory::create(table_name, columns);
|
2012-05-22 19:32:56 +00:00
|
|
|
|
}
|
2012-05-30 05:53:09 +00:00
|
|
|
|
else if (name == "Merge")
|
|
|
|
|
{
|
|
|
|
|
/** В запросе в качестве аргумента для движка указано имя БД, в которой находятся таблицы-источники,
|
|
|
|
|
* а также регексп для имён таблиц-источников.
|
|
|
|
|
*/
|
|
|
|
|
ASTs & args_func = dynamic_cast<ASTFunction &>(*dynamic_cast<ASTCreateQuery &>(*query).storage).children;
|
|
|
|
|
|
|
|
|
|
if (args_func.size() != 1)
|
|
|
|
|
throw Exception("Storage Merge requires exactly 2 parameters"
|
|
|
|
|
" - name of source database and regexp for table names.",
|
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
ASTs & args = dynamic_cast<ASTExpressionList &>(*args_func.at(0)).children;
|
|
|
|
|
|
|
|
|
|
if (args.size() != 2)
|
|
|
|
|
throw Exception("Storage Merge requires exactly 2 parameters"
|
|
|
|
|
" - name of source database and regexp for table names.",
|
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
String source_database = dynamic_cast<ASTIdentifier &>(*args[0]).name;
|
2013-01-05 20:03:19 +00:00
|
|
|
|
String table_name_regexp = safeGet<const String &>(dynamic_cast<ASTLiteral &>(*args[1]).value);
|
2012-05-30 05:53:09 +00:00
|
|
|
|
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageMerge::create(table_name, columns, source_database, table_name_regexp, context);
|
2012-05-30 05:53:09 +00:00
|
|
|
|
}
|
2012-05-22 19:32:56 +00:00
|
|
|
|
else if (name == "Distributed")
|
|
|
|
|
{
|
|
|
|
|
/** В запросе в качестве аргумента для движка указано имя конфигурационной секции,
|
2012-05-30 05:53:09 +00:00
|
|
|
|
* в которой задан список удалённых серверов, а также имя удалённой БД и имя удалённой таблицы.
|
2012-05-22 19:32:56 +00:00
|
|
|
|
*/
|
2012-05-22 20:18:45 +00:00
|
|
|
|
ASTs & args_func = dynamic_cast<ASTFunction &>(*dynamic_cast<ASTCreateQuery &>(*query).storage).children;
|
|
|
|
|
|
|
|
|
|
if (args_func.size() != 1)
|
2013-05-08 10:30:29 +00:00
|
|
|
|
throw Exception("Storage Distributed requires 3 or 4 parameters"
|
|
|
|
|
" - name of configuration section with list of remote servers, name of remote database, name of remote table[, sign column name].",
|
2012-05-22 20:18:45 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
ASTs & args = dynamic_cast<ASTExpressionList &>(*args_func.at(0)).children;
|
2012-05-22 20:00:25 +00:00
|
|
|
|
|
2013-05-08 10:30:29 +00:00
|
|
|
|
if (args.size() != 3 && args.size() != 4)
|
|
|
|
|
throw Exception("Storage Distributed requires 3 or 4 parameters"
|
|
|
|
|
" - name of configuration section with list of remote servers, name of remote database, name of remote table[, sign column name].",
|
2012-05-22 19:32:56 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
String config_name = dynamic_cast<ASTIdentifier &>(*args[0]).name;
|
|
|
|
|
String remote_database = dynamic_cast<ASTIdentifier &>(*args[1]).name;
|
|
|
|
|
String remote_table = dynamic_cast<ASTIdentifier &>(*args[2]).name;
|
2013-05-08 10:30:29 +00:00
|
|
|
|
String sign_column_name = args.size() == 4 ? dynamic_cast<ASTIdentifier &>(*args[3]).name : "";
|
2012-11-06 17:04:38 +00:00
|
|
|
|
|
2013-12-07 16:51:29 +00:00
|
|
|
|
return StorageDistributed::create(table_name, columns, remote_database, remote_table, context.getCluster(config_name),
|
2013-09-23 12:01:19 +00:00
|
|
|
|
context.getDataTypeFactory(), context.getSettings(), context, sign_column_name);
|
2012-05-22 19:32:56 +00:00
|
|
|
|
}
|
2013-09-30 19:54:25 +00:00
|
|
|
|
else if (name == "MergeTree" || name == "SummingMergeTree")
|
2012-07-18 19:30:33 +00:00
|
|
|
|
{
|
|
|
|
|
/** В качестве аргумента для движка должно быть указано:
|
|
|
|
|
* - имя столбца с датой;
|
2012-12-12 14:25:55 +00:00
|
|
|
|
* - имя столбца для семплирования (запрос с SAMPLE x будет выбирать строки, у которых в этом столбце значение меньше, чем x*UINT32_MAX);
|
2012-07-18 19:30:33 +00:00
|
|
|
|
* - выражение для сортировки в скобках;
|
|
|
|
|
* - index_granularity.
|
2012-12-12 14:25:55 +00:00
|
|
|
|
* Например: ENGINE = MergeTree(EventDate, intHash32(UniqID), (CounterID, EventDate, intHash32(UniqID), EventTime), 8192).
|
|
|
|
|
*
|
2013-09-30 19:54:25 +00:00
|
|
|
|
* SummingMergeTree - вариант, в котором при слиянии делается суммирование всех числовых столбцов кроме PK
|
|
|
|
|
* - для Баннерной Крутилки.
|
2012-07-18 19:30:33 +00:00
|
|
|
|
*/
|
|
|
|
|
ASTs & args_func = dynamic_cast<ASTFunction &>(*dynamic_cast<ASTCreateQuery &>(*query).storage).children;
|
|
|
|
|
|
|
|
|
|
if (args_func.size() != 1)
|
2013-09-30 19:54:25 +00:00
|
|
|
|
throw Exception("Storage " + name + " requires 3 or 4 parameters"
|
2012-12-15 04:42:42 +00:00
|
|
|
|
" - name of column with date, [name of column for sampling], primary key expression, index granularity.",
|
2012-07-18 19:30:33 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
ASTs & args = dynamic_cast<ASTExpressionList &>(*args_func.at(0)).children;
|
|
|
|
|
|
2012-12-12 14:25:55 +00:00
|
|
|
|
if (args.size() != 3 && args.size() != 4)
|
2013-09-30 19:54:25 +00:00
|
|
|
|
throw Exception("Storage " + name + " requires 3 or 4 parameters"
|
2012-12-12 14:25:55 +00:00
|
|
|
|
" - name of column with date, [name of column for sampling], primary key expression, index granularity.",
|
2012-07-18 19:30:33 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
2012-12-12 14:25:55 +00:00
|
|
|
|
size_t arg_offset = args.size() - 3;
|
|
|
|
|
|
2012-07-18 19:30:33 +00:00
|
|
|
|
String date_column_name = dynamic_cast<ASTIdentifier &>(*args[0]).name;
|
2012-12-12 15:45:08 +00:00
|
|
|
|
ASTPtr sampling_expression = arg_offset == 0 ? NULL : args[1];
|
2013-01-05 20:03:19 +00:00
|
|
|
|
UInt64 index_granularity = safeGet<UInt64>(dynamic_cast<ASTLiteral &>(*args[arg_offset + 2]).value);
|
2012-12-12 14:25:55 +00:00
|
|
|
|
ASTFunction & primary_expr_func = dynamic_cast<ASTFunction &>(*args[arg_offset + 1]);
|
2012-07-18 19:30:33 +00:00
|
|
|
|
|
2012-07-18 20:14:41 +00:00
|
|
|
|
if (primary_expr_func.name != "tuple")
|
2013-09-30 19:54:25 +00:00
|
|
|
|
throw Exception("Primary expression for storage " + name + " must be in parentheses.",
|
2012-07-18 19:30:33 +00:00
|
|
|
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
|
|
|
|
|
|
|
|
|
ASTPtr primary_expr = primary_expr_func.children.at(0);
|
|
|
|
|
|
2013-09-30 19:54:25 +00:00
|
|
|
|
return StorageMergeTree::create(
|
|
|
|
|
data_path, table_name, columns, context, primary_expr, date_column_name, sampling_expression, index_granularity,
|
|
|
|
|
name == "SummingMergeTree" ? StorageMergeTree::Summing : StorageMergeTree::Ordinary);
|
2012-07-18 19:30:33 +00:00
|
|
|
|
}
|
2012-08-16 17:27:40 +00:00
|
|
|
|
else if (name == "CollapsingMergeTree")
|
|
|
|
|
{
|
|
|
|
|
/** В качестве аргумента для движка должно быть указано:
|
|
|
|
|
* - имя столбца с датой;
|
2012-12-12 14:25:55 +00:00
|
|
|
|
* - имя столбца для семплирования (запрос с SAMPLE x будет выбирать строки, у которых в этом столбце значение меньше, чем x*UINT32_MAX);
|
2012-08-16 17:27:40 +00:00
|
|
|
|
* - выражение для сортировки в скобках;
|
|
|
|
|
* - index_granularity;
|
|
|
|
|
* - имя столбца, содержащего тип строчки с изменением "визита" (принимающего значения 1 и -1).
|
2012-08-20 05:32:50 +00:00
|
|
|
|
* Например: ENGINE = CollapsingMergeTree(EventDate, (CounterID, EventDate, intHash32(UniqID), VisitID), 8192, Sign).
|
2012-08-16 17:27:40 +00:00
|
|
|
|
*/
|
|
|
|
|
ASTs & args_func = dynamic_cast<ASTFunction &>(*dynamic_cast<ASTCreateQuery &>(*query).storage).children;
|
|
|
|
|
|
|
|
|
|
if (args_func.size() != 1)
|
2012-12-15 04:42:42 +00:00
|
|
|
|
throw Exception("Storage CollapsingMergeTree requires 4 or 5 parameters"
|
|
|
|
|
" - name of column with date, [name of column for sampling], primary key expression, index granularity, sign_column.",
|
2012-08-16 17:27:40 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
|
|
ASTs & args = dynamic_cast<ASTExpressionList &>(*args_func.at(0)).children;
|
|
|
|
|
|
2012-12-12 14:25:55 +00:00
|
|
|
|
if (args.size() != 4 && args.size() != 5)
|
|
|
|
|
throw Exception("Storage CollapsingMergeTree requires 4 or 5 parameters"
|
|
|
|
|
" - name of column with date, [name of column for sampling], primary key expression, index granularity, sign_column.",
|
2012-08-16 17:27:40 +00:00
|
|
|
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
|
|
|
|
|
2012-12-12 14:25:55 +00:00
|
|
|
|
size_t arg_offset = args.size() - 4;
|
|
|
|
|
|
2012-08-16 17:27:40 +00:00
|
|
|
|
String date_column_name = dynamic_cast<ASTIdentifier &>(*args[0]).name;
|
2012-12-12 15:45:08 +00:00
|
|
|
|
ASTPtr sampling_expression = arg_offset == 0 ? NULL : args[1];
|
2013-01-05 20:03:19 +00:00
|
|
|
|
UInt64 index_granularity = safeGet<UInt64>(dynamic_cast<ASTLiteral &>(*args[arg_offset + 2]).value);
|
2012-12-12 14:25:55 +00:00
|
|
|
|
String sign_column_name = dynamic_cast<ASTIdentifier &>(*args[arg_offset + 3]).name;
|
|
|
|
|
ASTFunction & primary_expr_func = dynamic_cast<ASTFunction &>(*args[arg_offset + 1]);
|
2012-08-16 17:27:40 +00:00
|
|
|
|
|
|
|
|
|
if (primary_expr_func.name != "tuple")
|
|
|
|
|
throw Exception("Primary expression for storage CollapsingMergeTree must be in parentheses.",
|
|
|
|
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
|
|
|
|
|
|
|
|
|
ASTPtr primary_expr = primary_expr_func.children.at(0);
|
|
|
|
|
|
2013-09-30 19:54:25 +00:00
|
|
|
|
return StorageMergeTree::create(
|
|
|
|
|
data_path, table_name, columns, context, primary_expr, date_column_name,
|
|
|
|
|
sampling_expression, index_granularity, StorageMergeTree::Collapsing, sign_column_name);
|
2012-08-16 17:27:40 +00:00
|
|
|
|
}
|
2011-10-31 17:30:44 +00:00
|
|
|
|
else if (name == "SystemNumbers")
|
|
|
|
|
{
|
|
|
|
|
if (columns->size() != 1 || columns->begin()->first != "number" || columns->begin()->second->getName() != "UInt64")
|
|
|
|
|
throw Exception("Storage SystemNumbers only allows one column with name 'number' and type 'UInt64'",
|
|
|
|
|
ErrorCodes::ILLEGAL_COLUMN);
|
|
|
|
|
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageSystemNumbers::create(table_name);
|
2011-10-31 17:30:44 +00:00
|
|
|
|
}
|
|
|
|
|
else if (name == "SystemOne")
|
|
|
|
|
{
|
|
|
|
|
if (columns->size() != 1 || columns->begin()->first != "dummy" || columns->begin()->second->getName() != "UInt8")
|
|
|
|
|
throw Exception("Storage SystemOne only allows one column with name 'dummy' and type 'UInt8'",
|
|
|
|
|
ErrorCodes::ILLEGAL_COLUMN);
|
|
|
|
|
|
2013-02-06 11:26:35 +00:00
|
|
|
|
return StorageSystemOne::create(table_name);
|
2011-10-31 17:30:44 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw Exception("Unknown storage " + name, ErrorCodes::UNKNOWN_STORAGE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|