optimize drop tables

This commit is contained in:
zhongyuankai 2024-04-06 10:31:45 +08:00
parent ec22d64fc8
commit 832c7087a7
7 changed files with 35 additions and 19 deletions

View File

@ -16,7 +16,6 @@
#include <Parsers/parseQuery.h>
#include <Parsers/queryToString.h>
#include <Parsers/ASTQueryWithTableAndOutput.h>
#include <Parsers/ASTDropQuery.h>
namespace DB
@ -201,14 +200,6 @@ void DDLTaskBase::parseQueryFromEntry(ContextPtr context)
ParserQuery parser_query(end, settings.allow_settings_after_format_in_insert);
String description;
query = parseQuery(parser_query, begin, end, description, 0, settings.max_parser_depth, settings.max_parser_backtracks);
if (auto * query_drop = query->as<ASTDropQuery>())
{
ASTs drops = query_drop->getRewrittenASTsOfSingleTable();
if (drops.size() > 1)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Not supports drop multiple tables for ddl task.");
query = drops[0];
}
}
void DDLTaskBase::formatRewrittenQuery(ContextPtr context)

View File

@ -557,7 +557,7 @@ bool InterpreterDropQuery::supportsTransactions() const
return drop.cluster.empty()
&& !drop.temporary
&& drop.kind == ASTDropQuery::Kind::Truncate
&& drop.database_and_tables;
&& drop.table;
}
void registerInterpreterDropQuery(InterpreterFactory & factory)

View File

@ -40,7 +40,7 @@ public:
// We detach the object permanently, so it will not be reattached back during server restart.
bool permanently{false};
/// Example: Drop TABLE t1, t2, t3...
/// Used to drop multiple tables only, example: Drop TABLE t1, t2, t3...
ASTPtr database_and_tables;
/** Get the text that identifies this element. */
@ -52,6 +52,7 @@ public:
return removeOnCluster<ASTDropQuery>(clone(), params.default_database);
}
/** Convert an AST that deletes multiple tables into multiple ASTs that delete a single table. */
ASTs getRewrittenASTsOfSingleTable();
QueryKind getQueryKind() const override { return QueryKind::Drop; }

View File

@ -7,6 +7,11 @@
namespace DB
{
namespace ErrorCodes
{
extern const int SYNTAX_ERROR;
}
namespace
{
@ -84,6 +89,9 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected, cons
if (!tables_p.parse(pos, database_and_tables, expected))
return false;
if (database_and_tables->size() > 1 && kind != ASTDropQuery::Kind::Drop)
throw Exception(ErrorCodes::SYNTAX_ERROR, "Only Support DROP multiple tables currently");
}
/// common for tables / dictionaries / databases
@ -123,6 +131,9 @@ bool parseDropQuery(IParser::Pos & pos, ASTPtr & node, Expected & expected, cons
query->cluster = cluster_str;
if (database_and_tables && database_and_tables->size() == 1)
node = query->getRewrittenASTsOfSingleTable()[0];
return true;
}

View File

@ -301,10 +301,8 @@ TEST(ParserDictionaryDDL, ParseDropQuery)
ASTDropQuery * drop1 = ast1->as<ASTDropQuery>();
EXPECT_TRUE(drop1->is_dictionary);
auto & database_and_tables1 = drop1->database_and_tables->as<ASTExpressionList &>();
auto identifier1 = dynamic_pointer_cast<ASTTableIdentifier>(database_and_tables1.children[0]);
EXPECT_EQ(identifier1->getDatabaseName(), "test");
EXPECT_EQ(identifier1->shortName(), "dict1");
EXPECT_EQ(drop1->getDatabase(), "test");
EXPECT_EQ(drop1->getTable(), "dict1");
auto str1 = serializeAST(*drop1);
EXPECT_EQ(input1, str1);
@ -314,10 +312,8 @@ TEST(ParserDictionaryDDL, ParseDropQuery)
ASTDropQuery * drop2 = ast2->as<ASTDropQuery>();
EXPECT_TRUE(drop2->is_dictionary);
auto & database_and_tables2 = drop2->database_and_tables->as<ASTExpressionList &>();
auto identifier2 = dynamic_pointer_cast<ASTTableIdentifier>(database_and_tables2.children[0]);
EXPECT_EQ(identifier2->getDatabaseName(), "");
EXPECT_EQ(identifier2->shortName(), "dict2");
EXPECT_EQ(drop2->getDatabase(), "");
EXPECT_EQ(drop2->getTable(), "dict2");
auto str2 = serializeAST(*drop2);
EXPECT_EQ(input2, str2);
}

View File

@ -6,3 +6,6 @@ Test when deletion of existing table fails
-- check which tables exist in 02961_db1
-- check which tables exist in 02961_db2
02961_tb5
Test when deletion of not empty table fails
tab2
tab3

View File

@ -27,6 +27,20 @@ SHOW TABLES FROM 02961_db1;
SELECT '-- check which tables exist in 02961_db2';
SHOW TABLES FROM 02961_db2;
DROP TABLE IF EXISTS tab1, tab2, tab3;
CREATE TABLE IF NOT EXISTS tab1 (id UInt32) Engine=Memory();
CREATE TABLE IF NOT EXISTS tab2 (id UInt32) Engine=Memory();
CREATE TABLE IF NOT EXISTS tab3 (id UInt32) Engine=Memory();
INSERT INTO tab2 SELECT number FROM system.numbers limit 10;
DROP TABLE IF EMPTY tab1, tab2, tab3; -- { serverError TABLE_NOT_EMPTY }
SELECT 'Test when deletion of not empty table fails';
SHOW TABLES;
TRUNCATE TABLE tab2, tab3; -- { clientError SYNTAX_ERROR }
DROP TABLE IF EXISTS tab1, tab2, tab3;
DROP DATABASE IF EXISTS 02961_db1;
DROP DATABASE IF EXISTS 02961_db2;