mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #1901 from zhang2014/fix/ISSUES-117
ISSUES-117 add show create & exist temporary table
This commit is contained in:
commit
1ecb9dac72
@ -673,6 +673,11 @@ bool Context::isDatabaseExist(const String & database_name) const
|
||||
return shared->databases.end() != shared->databases.find(db);
|
||||
}
|
||||
|
||||
bool Context::isExternalTableExist(const String & table_name) const
|
||||
{
|
||||
return external_tables.end() != external_tables.find(table_name);
|
||||
}
|
||||
|
||||
|
||||
void Context::assertTableExists(const String & database_name, const String & table_name) const
|
||||
{
|
||||
@ -733,7 +738,10 @@ Tables Context::getExternalTables() const
|
||||
{
|
||||
auto lock = getLock();
|
||||
|
||||
Tables res = external_tables;
|
||||
Tables res;
|
||||
for (auto & table : external_tables)
|
||||
res[table.first] = table.second.first;
|
||||
|
||||
if (session_context && session_context != this)
|
||||
{
|
||||
Tables buf = session_context->getExternalTables();
|
||||
@ -750,10 +758,11 @@ Tables Context::getExternalTables() const
|
||||
|
||||
StoragePtr Context::tryGetExternalTable(const String & table_name) const
|
||||
{
|
||||
auto it = external_tables.find(table_name);
|
||||
if (external_tables.end() == it)
|
||||
TableAndCreateASTs::const_iterator jt = external_tables.find(table_name);
|
||||
if (external_tables.end() == jt)
|
||||
return StoragePtr();
|
||||
return it->second;
|
||||
|
||||
return jt->second.first;
|
||||
}
|
||||
|
||||
|
||||
@ -807,12 +816,12 @@ StoragePtr Context::getTableImpl(const String & database_name, const String & ta
|
||||
}
|
||||
|
||||
|
||||
void Context::addExternalTable(const String & table_name, const StoragePtr & storage)
|
||||
void Context::addExternalTable(const String & table_name, const StoragePtr & storage, const ASTPtr & ast)
|
||||
{
|
||||
if (external_tables.end() != external_tables.find(table_name))
|
||||
throw Exception("Temporary table " + table_name + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS);
|
||||
|
||||
external_tables[table_name] = storage;
|
||||
external_tables[table_name] = std::pair(storage, ast);
|
||||
|
||||
if (process_list_elem)
|
||||
{
|
||||
@ -823,11 +832,12 @@ void Context::addExternalTable(const String & table_name, const StoragePtr & sto
|
||||
|
||||
StoragePtr Context::tryRemoveExternalTable(const String & table_name)
|
||||
{
|
||||
auto it = external_tables.find(table_name);
|
||||
TableAndCreateASTs::const_iterator it = external_tables.find(table_name);
|
||||
|
||||
if (external_tables.end() == it)
|
||||
return StoragePtr();
|
||||
|
||||
auto storage = it->second;
|
||||
auto storage = it->second.first;
|
||||
external_tables.erase(it);
|
||||
return storage;
|
||||
}
|
||||
@ -917,6 +927,15 @@ ASTPtr Context::getCreateQuery(const String & database_name, const String & tabl
|
||||
return shared->databases[db]->getCreateQuery(*this, table_name);
|
||||
}
|
||||
|
||||
ASTPtr Context::getCreateExternalQuery(const String & table_name) const
|
||||
{
|
||||
TableAndCreateASTs::const_iterator jt = external_tables.find(table_name);
|
||||
if (external_tables.end() == jt)
|
||||
throw Exception("Temporary Table" + table_name + " doesn't exist", ErrorCodes::UNKNOWN_TABLE);
|
||||
|
||||
return jt->second.second;
|
||||
}
|
||||
|
||||
|
||||
Settings Context::getSettings() const
|
||||
{
|
||||
|
@ -77,6 +77,9 @@ using DatabaseAndTableName = std::pair<String, String>;
|
||||
using ViewDependencies = std::map<DatabaseAndTableName, std::set<DatabaseAndTableName>>;
|
||||
using Dependencies = std::vector<DatabaseAndTableName>;
|
||||
|
||||
using TableAndCreateAST = std::pair<StoragePtr, ASTPtr>;
|
||||
using TableAndCreateASTs = std::map<String, TableAndCreateAST>;
|
||||
|
||||
|
||||
/** A set of known objects that can be used in the query.
|
||||
* Consists of a shared part (always common to all sessions and queries)
|
||||
@ -103,7 +106,7 @@ private:
|
||||
|
||||
String default_format; /// Format, used when server formats data by itself and if query does not have FORMAT specification.
|
||||
/// Thus, used in HTTP interface. If not specified - then some globally default format is used.
|
||||
Tables external_tables; /// Temporary tables. Keyed by table name.
|
||||
TableAndCreateASTs external_tables; /// Temporary tables.
|
||||
Tables table_function_results; /// Temporary tables obtained by execution of table functions. Keyed by AST tree id.
|
||||
Context * query_context = nullptr;
|
||||
Context * session_context = nullptr; /// Session context or nullptr. Could be equal to this.
|
||||
@ -165,6 +168,7 @@ public:
|
||||
/// Checking the existence of the table/database. Database can be empty - in this case the current database is used.
|
||||
bool isTableExist(const String & database_name, const String & table_name) const;
|
||||
bool isDatabaseExist(const String & database_name) const;
|
||||
bool isExternalTableExist(const String & table_name) const;
|
||||
void assertTableExists(const String & database_name, const String & table_name) const;
|
||||
|
||||
/** The parameter check_database_access_rights exists to not check the permissions of the database again,
|
||||
@ -180,7 +184,7 @@ public:
|
||||
StoragePtr tryGetExternalTable(const String & table_name) const;
|
||||
StoragePtr getTable(const String & database_name, const String & table_name) const;
|
||||
StoragePtr tryGetTable(const String & database_name, const String & table_name) const;
|
||||
void addExternalTable(const String & table_name, const StoragePtr & storage);
|
||||
void addExternalTable(const String & table_name, const StoragePtr & storage, const ASTPtr & ast = {});
|
||||
StoragePtr tryRemoveExternalTable(const String & table_name);
|
||||
|
||||
StoragePtr executeTableFunction(const ASTPtr & table_expression);
|
||||
@ -240,6 +244,7 @@ public:
|
||||
|
||||
/// Get query for the CREATE table.
|
||||
ASTPtr getCreateQuery(const String & database_name, const String & table_name) const;
|
||||
ASTPtr getCreateExternalQuery(const String & table_name) const;
|
||||
|
||||
const DatabasePtr getDatabase(const String & database_name) const;
|
||||
DatabasePtr getDatabase(const String & database_name);
|
||||
|
@ -538,7 +538,7 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create)
|
||||
false);
|
||||
|
||||
if (create.is_temporary)
|
||||
context.getSessionContext().addExternalTable(table_name, res);
|
||||
context.getSessionContext().addExternalTable(table_name, res, query_ptr);
|
||||
else
|
||||
database->createTable(context, table_name, res, query_ptr);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ Block InterpreterExistsQuery::getSampleBlock()
|
||||
BlockInputStreamPtr InterpreterExistsQuery::executeImpl()
|
||||
{
|
||||
const ASTExistsQuery & ast = typeid_cast<const ASTExistsQuery &>(*query_ptr);
|
||||
bool res = context.isTableExist(ast.database, ast.table);
|
||||
bool res = ast.temporary ? context.isExternalTableExist(ast.table) : context.isTableExist(ast.database, ast.table);
|
||||
|
||||
return std::make_shared<OneBlockInputStream>(Block{{
|
||||
ColumnUInt8::create(1, res),
|
||||
|
@ -11,10 +11,15 @@
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/InterpreterShowCreateQuery.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int SYNTAX_ERROR;
|
||||
extern const int THERE_IS_NO_QUERY;
|
||||
}
|
||||
|
||||
BlockIO InterpreterShowCreateQuery::execute()
|
||||
{
|
||||
BlockIO res;
|
||||
@ -36,8 +41,17 @@ BlockInputStreamPtr InterpreterShowCreateQuery::executeImpl()
|
||||
{
|
||||
const ASTShowCreateQuery & ast = typeid_cast<const ASTShowCreateQuery &>(*query_ptr);
|
||||
|
||||
if (ast.temporary && !ast.database.empty())
|
||||
throw Exception("Temporary databases are not possible.", ErrorCodes::SYNTAX_ERROR);
|
||||
|
||||
ASTPtr create_query = (ast.temporary ? context.getCreateExternalQuery(ast.table) :
|
||||
context.getCreateQuery(ast.database, ast.table));
|
||||
|
||||
if (!create_query && ast.temporary)
|
||||
throw Exception("Unable to show the create query of " + ast.table + ". Maybe it was created by the system.", ErrorCodes::THERE_IS_NO_QUERY);
|
||||
|
||||
std::stringstream stream;
|
||||
formatAST(*context.getCreateQuery(ast.database, ast.table), stream, false, true);
|
||||
formatAST(*create_query, stream, false, true);
|
||||
String res = stream.str();
|
||||
|
||||
MutableColumnPtr column = ColumnString::create();
|
||||
|
@ -15,6 +15,7 @@ class ASTQueryWithTableAndOutput : public ASTQueryWithOutput
|
||||
public:
|
||||
String database;
|
||||
String table;
|
||||
bool temporary{false};
|
||||
|
||||
protected:
|
||||
void formatHelper(const FormatSettings & settings, const char * name) const
|
||||
|
@ -14,6 +14,7 @@ namespace DB
|
||||
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
ParserKeyword s_exists("EXISTS");
|
||||
ParserKeyword s_temporary("TEMPORARY");
|
||||
ParserKeyword s_describe("DESCRIBE");
|
||||
ParserKeyword s_desc("DESC");
|
||||
ParserKeyword s_show("SHOW");
|
||||
@ -42,6 +43,9 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, ASTPtr & node, Expected &
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_temporary.ignore(pos, expected))
|
||||
query->temporary = true;
|
||||
|
||||
s_table.ignore(pos, expected);
|
||||
|
||||
if (!name_p.parse(pos, table, expected))
|
||||
|
@ -1 +0,0 @@
|
||||
temp_tab
|
@ -1,4 +0,0 @@
|
||||
DROP TEMPORARY TABLE IF EXISTS temp_tab;
|
||||
CREATE TEMPORARY TABLE temp_tab (number UInt64);
|
||||
SHOW TEMPORARY TABLES LIKE 'temp_tab';
|
||||
DROP TEMPORARY TABLE temp_tab;
|
@ -0,0 +1,4 @@
|
||||
1
|
||||
CREATE TEMPORARY TABLE temp_tab ( number UInt64) ENGINE = Memory
|
||||
temp_tab
|
||||
0
|
@ -0,0 +1,7 @@
|
||||
DROP TEMPORARY TABLE IF EXISTS temp_tab;
|
||||
CREATE TEMPORARY TABLE temp_tab (number UInt64);
|
||||
EXISTS TEMPORARY TABLE temp_tab;
|
||||
SHOW CREATE TEMPORARY TABLE temp_tab;
|
||||
SHOW TEMPORARY TABLES LIKE 'temp_tab';
|
||||
DROP TEMPORARY TABLE temp_tab;
|
||||
EXISTS TEMPORARY TABLE temp_tab;
|
@ -184,7 +184,7 @@ Deletes all tables inside the 'db' database, then deletes the 'db' database itse
|
||||
If `IF EXISTS` is specified, it doesn't return an error if the database doesn't exist.
|
||||
|
||||
```sql
|
||||
DROP TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster]
|
||||
DROP [TEMPORARY] TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster]
|
||||
```
|
||||
|
||||
Deletes the table.
|
||||
@ -452,7 +452,7 @@ See also the section "Formats".
|
||||
## SHOW TABLES
|
||||
|
||||
```sql
|
||||
SHOW TABLES [FROM db] [LIKE 'pattern'] [INTO OUTFILE filename] [FORMAT format]
|
||||
SHOW [TEMPORARY] TABLES [FROM db] [LIKE 'pattern'] [INTO OUTFILE filename] [FORMAT format]
|
||||
```
|
||||
|
||||
Displays a list of tables
|
||||
@ -499,7 +499,7 @@ watch -n1 "clickhouse-client --query='SHOW PROCESSLIST'"
|
||||
## SHOW CREATE TABLE
|
||||
|
||||
```sql
|
||||
SHOW CREATE TABLE [db.]table [INTO OUTFILE filename] [FORMAT format]
|
||||
SHOW CREATE [TEMPORARY] TABLE [db.]table [INTO OUTFILE filename] [FORMAT format]
|
||||
```
|
||||
|
||||
Returns a single `String`-type 'statement' column, which contains a single value – the `CREATE` query used for creating the specified table.
|
||||
@ -517,7 +517,7 @@ Nested data structures are output in "expanded" format. Each column is shown sep
|
||||
## EXISTS
|
||||
|
||||
```sql
|
||||
EXISTS TABLE [db.]name [INTO OUTFILE filename] [FORMAT format]
|
||||
EXISTS [TEMPORARY] TABLE [db.]name [INTO OUTFILE filename] [FORMAT format]
|
||||
```
|
||||
|
||||
Returns a single `UInt8`-type column, which contains the single value `0` if the table or database doesn't exist, or `1` if the table exists in the specified database.
|
||||
|
Loading…
Reference in New Issue
Block a user