Merge pull request #58444 from bharatnc/ncb/support-hints-for-db-engines

support hints for database engines
This commit is contained in:
Nikolay Degterinsky 2024-01-05 17:12:44 +01:00 committed by GitHub
commit 56aa835954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 3 deletions

View File

@ -92,9 +92,16 @@ void validate(const ASTCreateQuery & create_query)
DatabasePtr DatabaseFactory::get(const ASTCreateQuery & create, const String & metadata_path, ContextPtr context)
{
const auto engine_name = create.storage->engine->name;
/// check if the database engine is a valid one before proceeding
if (!database_engines.contains(create.storage->engine->name))
throw Exception(ErrorCodes::UNKNOWN_DATABASE_ENGINE, "Unknown database engine: {}", create.storage->engine->name);
if (!database_engines.contains(engine_name))
{
auto hints = getHints(engine_name);
if (!hints.empty())
throw Exception(ErrorCodes::UNKNOWN_DATABASE_ENGINE, "Unknown database engine {}. Maybe you meant: {}", engine_name, toString(hints));
else
throw Exception(ErrorCodes::UNKNOWN_DATABASE_ENGINE, "Unknown database engine: {}", create.storage->engine->name);
}
/// if the engine is found (i.e. registered with the factory instance), then validate if the
/// supplied engine arguments, settings and table overrides are valid for the engine.

View File

@ -1,5 +1,6 @@
#pragma once
#include <Common/NamePrompter.h>
#include <Interpreters/Context_fwd.h>
#include <Databases/IDatabase.h>
#include <Parsers/ASTCreateQuery.h>
@ -24,7 +25,7 @@ static inline ValueType safeGetLiteralValue(const ASTPtr &ast, const String &eng
return ast->as<ASTLiteral>()->value.safeGet<ValueType>();
}
class DatabaseFactory : private boost::noncopyable
class DatabaseFactory : private boost::noncopyable, public IHints<>
{
public:
@ -52,6 +53,14 @@ public:
const DatabaseEngines & getDatabaseEngines() const { return database_engines; }
std::vector<String> getAllRegisteredNames() const override
{
std::vector<String> result;
auto getter = [](const auto & pair) { return pair.first; };
std::transform(database_engines.begin(), database_engines.end(), std::back_inserter(result), getter);
return result;
}
private:
DatabaseEngines database_engines;

View File

@ -57,6 +57,31 @@ def test_drop_wrong_database_name(start):
node.query("DROP DATABASE test;")
def test_database_engine_name(start):
# test with a valid database engine
node.query(
"""
CREATE DATABASE test_atomic ENGINE = Atomic;
CREATE TABLE test_atomic.table_test_atomic (i Int64) ENGINE = MergeTree() ORDER BY i;
INSERT INTO test_atomic.table_test_atomic SELECT 1;
"""
)
assert 1 == int(node.query("SELECT * FROM test_atomic.table_test_atomic".strip()))
# test with a invalid database engine
with pytest.raises(
QueryRuntimeException,
match="DB::Exception: Unknown database engine Atomic123. Maybe you meant: \\['Atomic'\\].",
):
node.query("CREATE DATABASE test_atomic123 ENGINE = Atomic123;")
node.query(
"""
DROP TABLE test_atomic.table_test_atomic;
DROP DATABASE test_atomic;
"""
)
def test_wrong_table_name(start):
node.query(
"""