added SHOW CREATE DATABASE query [#CLICKHOUSE-3590]

This commit is contained in:
Nikolai Kochetov 2018-03-12 17:14:56 +03:00
parent e8aecfa30c
commit 2b3e897aa1
6 changed files with 69 additions and 20 deletions

View File

@ -45,6 +45,12 @@ namespace detail
{ {
return base_path + (endsWith(base_path, "/") ? "" : "/") + escapeForFileName(table_name) + ".sql"; return base_path + (endsWith(base_path, "/") ? "" : "/") + escapeForFileName(table_name) + ".sql";
} }
String getDatabaseMetadataPath(const String & base_path)
{
return (endsWith(base_path, "/") ? base_path.substr(0, base_path.size() - 1) : base_path) + ".sql";
}
} }
static void loadTable( static void loadTable(
@ -332,16 +338,21 @@ void DatabaseOrdinary::removeTable(
static ASTPtr getCreateQueryImpl(const String & path, const String & table_name) static ASTPtr getCreateQueryImpl(const String & path, const String & table_name)
{ {
String table_metadata_path = detail::getTableMetadataPath(path, table_name); String metadata_path;
if (table_name.empty())
metadata_path = detail::getDatabaseMetadataPath(path);
else
metadata_path = detail::getTableMetadataPath(path, table_name);
String query; String query;
{ {
ReadBufferFromFile in(table_metadata_path, 4096); ReadBufferFromFile in(metadata_path, 4096);
readStringUntilEOF(query, in); readStringUntilEOF(query, in);
} }
ParserCreateQuery parser; ParserCreateQuery parser;
return parseQuery(parser, query.data(), query.data() + query.size(), "in file " + table_metadata_path); return parseQuery(parser, query.data(), query.data() + query.size(), "in file " + metadata_path);
} }

View File

@ -124,7 +124,8 @@ public:
const Context & context, const Context & context,
const String & name) = 0; const String & name) = 0;
/// Get the CREATE TABLE query for the table. It can also provide information for detached tables for which there is metadata. /// Get the CREATE TABLE query for the table or CREATE DATABASE query for database if name is empty.
/// It can also provide information for detached tables for which there is metadata.
virtual ASTPtr getCreateQuery( virtual ASTPtr getCreateQuery(
const Context & context, const Context & context,
const String & name) const = 0; const String & name) const = 0;

View File

@ -107,7 +107,11 @@ std::unique_ptr<IInterpreter> InterpreterFactory::get(ASTPtr & query, Context &
{ {
return std::make_unique<InterpreterExistsQuery>(query, context); return std::make_unique<InterpreterExistsQuery>(query, context);
} }
else if (typeid_cast<ASTShowCreateQuery *>(query.get())) else if (typeid_cast<ASTShowCreateTableQuery *>(query.get()))
{
return std::make_unique<InterpreterShowCreateQuery>(query, context);
}
else if (typeid_cast<ASTShowCreateDatabaseQuery *>(query.get()))
{ {
return std::make_unique<InterpreterShowCreateQuery>(query, context); return std::make_unique<InterpreterShowCreateQuery>(query, context);
} }

View File

@ -39,7 +39,7 @@ Block InterpreterShowCreateQuery::getSampleBlock()
BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl() BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl()
{ {
const ASTShowCreateQuery & ast = typeid_cast<const ASTShowCreateQuery &>(*query_ptr); const auto & ast = dynamic_cast<const ASTQueryWithTableAndOutput &>(*query_ptr);
if (ast.temporary && !ast.database.empty()) if (ast.temporary && !ast.database.empty())
throw Exception("Temporary databases are not possible.", ErrorCodes::SYNTAX_ERROR); throw Exception("Temporary databases are not possible.", ErrorCodes::SYNTAX_ERROR);

View File

@ -19,6 +19,7 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
ParserKeyword s_desc("DESC"); ParserKeyword s_desc("DESC");
ParserKeyword s_show("SHOW"); ParserKeyword s_show("SHOW");
ParserKeyword s_create("CREATE"); ParserKeyword s_create("CREATE");
ParserKeyword s_database("DATABASE");
ParserKeyword s_table("TABLE"); ParserKeyword s_table("TABLE");
ParserToken s_dot(TokenType::Dot); ParserToken s_dot(TokenType::Dot);
ParserIdentifier name_p; ParserIdentifier name_p;
@ -27,6 +28,8 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
ASTPtr table; ASTPtr table;
std::shared_ptr<ASTQueryWithTableAndOutput> query; std::shared_ptr<ASTQueryWithTableAndOutput> query;
bool parse_only_database_name = false;
if (s_exists.ignore(pos, expected)) if (s_exists.ignore(pos, expected))
{ {
query = std::make_shared<ASTExistsQuery>(); query = std::make_shared<ASTExistsQuery>();
@ -36,26 +39,40 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
if (!s_create.ignore(pos, expected)) if (!s_create.ignore(pos, expected))
return false; return false;
query = std::make_shared<ASTShowCreateQuery>(); if (s_database.ignore(pos, expected))
{
parse_only_database_name = true;
query = std::make_shared<ASTShowCreateDatabaseQuery>();
}
else
query = std::make_shared<ASTShowCreateTableQuery>();
} }
else else
{ {
return false; return false;
} }
if (s_temporary.ignore(pos, expected)) if (parse_only_database_name)
query->temporary = true;
s_table.ignore(pos, expected);
if (!name_p.parse(pos, table, expected))
return false;
if (s_dot.ignore(pos, expected))
{ {
database = table; if (!name_p.parse(pos, database, expected))
return false;
}
else
{
if (s_temporary.ignore(pos, expected))
query->temporary = true;
s_table.ignore(pos, expected);
if (!name_p.parse(pos, table, expected)) if (!name_p.parse(pos, table, expected))
return false; return false;
if (s_dot.ignore(pos, expected))
{
database = table;
if (!name_p.parse(pos, table, expected))
return false;
}
} }
if (database) if (database)

View File

@ -12,12 +12,18 @@ struct ASTExistsQueryIDAndQueryNames
static constexpr auto Query = "EXISTS TABLE"; static constexpr auto Query = "EXISTS TABLE";
}; };
struct ASTShowCreateQueryIDAndQueryNames struct ASTShowCreateTableQueryIDAndQueryNames
{ {
static constexpr auto ID = "ShowCreateQuery"; static constexpr auto ID = "ShowCreateTableQuery";
static constexpr auto Query = "SHOW CREATE TABLE"; static constexpr auto Query = "SHOW CREATE TABLE";
}; };
struct ASTShowCreateDatabaseQueryIDAndQueryNames
{
static constexpr auto ID = "ShowCreateDatabaseQuery";
static constexpr auto Query = "SHOW CREATE DATABASE";
};
struct ASTDescribeQueryExistsQueryIDAndQueryNames struct ASTDescribeQueryExistsQueryIDAndQueryNames
{ {
static constexpr auto ID = "DescribeQuery"; static constexpr auto ID = "DescribeQuery";
@ -25,7 +31,17 @@ struct ASTDescribeQueryExistsQueryIDAndQueryNames
}; };
using ASTExistsQuery = ASTQueryWithTableAndOutputImpl<ASTExistsQueryIDAndQueryNames>; using ASTExistsQuery = ASTQueryWithTableAndOutputImpl<ASTExistsQueryIDAndQueryNames>;
using ASTShowCreateQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateQueryIDAndQueryNames>; using ASTShowCreateTableQuery = ASTQueryWithTableAndOutputImpl<ASTShowCreateTableQueryIDAndQueryNames>;
class ASTShowCreateDatabaseQuery : public ASTQueryWithTableAndOutputImpl<ASTShowCreateDatabaseQueryIDAndQueryNames>
{
protected:
void formatQueryImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << ASTShowCreateDatabaseQueryIDAndQueryNames::Query
<< " " << (settings.hilite ? hilite_none : "") << backQuoteIfNeed(database);
}
};
class ASTDescribeQuery : public ASTQueryWithOutput class ASTDescribeQuery : public ASTQueryWithOutput
{ {