Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support hints for database engines #58444

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/Databases/DatabaseFactory.cpp
Expand Up @@ -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.
Expand Down
11 changes: 10 additions & 1 deletion src/Databases/DatabaseFactory.h
@@ -1,5 +1,6 @@
#pragma once

#include <Common/NamePrompter.h>
#include <Interpreters/Context_fwd.h>
#include <Databases/IDatabase.h>
#include <Parsers/ASTCreateQuery.h>
Expand All @@ -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:

Expand Down Expand Up @@ -52,6 +53,14 @@ class DatabaseFactory : private boost::noncopyable

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;

Expand Down
25 changes: 25 additions & 0 deletions tests/integration/test_wrong_db_or_table_name/test.py
Expand Up @@ -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(
"""
Expand Down