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";
}
String getDatabaseMetadataPath(const String & base_path)
{
return (endsWith(base_path, "/") ? base_path.substr(0, base_path.size() - 1) : base_path) + ".sql";
}
}
static void loadTable(
@ -332,16 +338,21 @@ void DatabaseOrdinary::removeTable(
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;
{
ReadBufferFromFile in(table_metadata_path, 4096);
ReadBufferFromFile in(metadata_path, 4096);
readStringUntilEOF(query, in);
}
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 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(
const Context & context,
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);
}
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);
}

View File

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

View File

@ -12,12 +12,18 @@ struct ASTExistsQueryIDAndQueryNames
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";
};
struct ASTShowCreateDatabaseQueryIDAndQueryNames
{
static constexpr auto ID = "ShowCreateDatabaseQuery";
static constexpr auto Query = "SHOW CREATE DATABASE";
};
struct ASTDescribeQueryExistsQueryIDAndQueryNames
{
static constexpr auto ID = "DescribeQuery";
@ -25,7 +31,17 @@ struct ASTDescribeQueryExistsQueryIDAndQueryNames
};
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
{