This commit is contained in:
Alexey Arno 2015-04-24 15:26:23 +03:00
parent a63971e5fb
commit e1b6730e5b
3 changed files with 131 additions and 0 deletions

View File

@ -0,0 +1,38 @@
#pragma once
#include <DB/Storages/IStorage.h>
#include <DB/Interpreters/Context.h>
namespace DB
{
/** Реализует системную таблицу columns, которая позволяет получить информацию
* о столбцах каждой таблицы для всех баз данных.
*/
class StorageSystemColumns : public IStorage
{
public:
static StoragePtr create(const std::string & name_);
std::string getName() const override { return "SystemColumns"; }
std::string getTableName() const override { return name; }
const NamesAndTypesList & getColumnsListImpl() const override { return columns; }
BlockInputStreams read(
const Names & column_names,
ASTPtr query,
const Context & context,
const Settings & settings,
QueryProcessingStage::Enum & processed_stage,
size_t max_block_size = DEFAULT_BLOCK_SIZE,
unsigned threads = 1) override;
private:
StorageSystemColumns(const std::string & name_);
private:
const std::string name;
NamesAndTypesList columns;
};
}

View File

@ -31,6 +31,7 @@
#include <DB/Storages/StorageSystemZooKeeper.h>
#include <DB/Storages/StorageSystemReplicas.h>
#include <DB/Storages/StorageSystemDictionaries.h>
#include <DB/Storages/StorageSystemColumns.h>
#include <DB/IO/copyData.h>
#include <DB/IO/LimitReadBuffer.h>
@ -537,6 +538,7 @@ int Server::main(const std::vector<std::string> & args)
global_context->addTable("system", "merges", StorageSystemMerges::create("merges"));
global_context->addTable("system", "replicas", StorageSystemReplicas::create("replicas"));
global_context->addTable("system", "dictionaries", StorageSystemDictionaries::create("dictionaries"));
global_context->addTable("system", "columns", StorageSystemColumns::create("columns"));
if (has_zookeeper)
global_context->addTable("system", "zookeeper", StorageSystemZooKeeper::create("zookeeper"));

View File

@ -0,0 +1,91 @@
#include <DB/Storages/StorageSystemColumns.h>
#include <DB/Columns/ColumnString.h>
#include <DB/DataTypes/DataTypeString.h>
#include <DB/DataStreams/OneBlockInputStream.h>
namespace DB
{
StorageSystemColumns::StorageSystemColumns(const std::string & name_)
: name(name_)
, columns{
{ "database", new DataTypeString },
{ "table", new DataTypeString },
{ "name", new DataTypeString },
{ "type", new DataTypeString },
{ "default_type", new DataTypeString },
{ "default_expression", new DataTypeString }
}
{
}
StoragePtr StorageSystemColumns::create(const std::string & name_)
{
return (new StorageSystemColumns{name_})->thisPtr();
}
BlockInputStreams StorageSystemColumns::read(
const Names & column_names,
ASTPtr query,
const Context & context,
const Settings & settings,
QueryProcessingStage::Enum & processed_stage,
const size_t max_block_size,
const unsigned threads)
{
ColumnWithNameAndType column_database{ new ColumnString, new DataTypeString, "database" };
ColumnWithNameAndType column_table{ new ColumnString, new DataTypeString, "table" };
ColumnWithNameAndType column_name{ new ColumnString, new DataTypeString, "name" };
ColumnWithNameAndType column_type{ new ColumnString, new DataTypeString, "type" };
ColumnWithNameAndType column_default_type{ new ColumnString, new DataTypeString, "default_type" };
ColumnWithNameAndType column_default_expression{ new ColumnString, new DataTypeString, "default_expression" };
Poco::ScopedLock<Poco::Mutex> lock(context.getMutex());
const Databases & databases = context.getDatabases();
for (const auto & database : databases)
{
const Tables & tables = database.second;
for (const auto & table : tables)
{
NamesAndTypesList columns;
ColumnDefaults column_defaults;
{
StoragePtr storage = table.second;
storage->lockStructure(false);
columns = storage->getColumnsList();
columns.insert(std::end(columns), std::begin(storage->alias_columns), std::end(storage->alias_columns));
column_defaults = storage->column_defaults;
}
for (const auto & column : columns)
{
column_database.column->insert(database.first);
column_table.column->insert(table.first);
column_name.column->insert(column.name);
column_type.column->insert(column.type->getName());
const auto it = column_defaults.find(column.name);
if (it == std::end(column_defaults))
{
column_default_type.column->insertDefault();
column_default_expression.column->insertDefault();
}
else
{
column_default_type.column->insert(toString(it->second.type));
column_default_expression.column->insert(queryToString(it->second.expression));
}
}
}
}
return BlockInputStreams{ 1, new OneBlockInputStream{
{ column_database, column_table, column_name, column_type, column_default_type, column_default_expression }
}
};
}
}