Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions src/duckdb/src/common/enum_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
#include "duckdb/parser/expression/parameter_expression.hpp"
#include "duckdb/parser/expression/star_expression.hpp"
#include "duckdb/parser/expression/window_expression.hpp"
#include "duckdb/parser/parsed_data/alter_database_info.hpp"
#include "duckdb/parser/parsed_data/alter_info.hpp"
#include "duckdb/parser/parsed_data/alter_scalar_function_info.hpp"
#include "duckdb/parser/parsed_data/alter_table_function_info.hpp"
Expand Down Expand Up @@ -338,6 +339,23 @@ AggregateType EnumUtil::FromString<AggregateType>(const char *value) {
return static_cast<AggregateType>(StringUtil::StringToEnum(GetAggregateTypeValues(), 2, "AggregateType", value));
}

const StringUtil::EnumStringLiteral *GetAlterDatabaseTypeValues() {
static constexpr StringUtil::EnumStringLiteral values[] {
{ static_cast<uint32_t>(AlterDatabaseType::RENAME_DATABASE), "RENAME_DATABASE" }
};
return values;
}

template<>
const char* EnumUtil::ToChars<AlterDatabaseType>(AlterDatabaseType value) {
return StringUtil::EnumToString(GetAlterDatabaseTypeValues(), 1, "AlterDatabaseType", static_cast<uint32_t>(value));
}

template<>
AlterDatabaseType EnumUtil::FromString<AlterDatabaseType>(const char *value) {
return static_cast<AlterDatabaseType>(StringUtil::StringToEnum(GetAlterDatabaseTypeValues(), 1, "AlterDatabaseType", value));
}

const StringUtil::EnumStringLiteral *GetAlterForeignKeyTypeValues() {
static constexpr StringUtil::EnumStringLiteral values[] {
{ static_cast<uint32_t>(AlterForeignKeyType::AFT_ADD), "AFT_ADD" },
Expand Down Expand Up @@ -435,19 +453,20 @@ const StringUtil::EnumStringLiteral *GetAlterTypeValues() {
{ static_cast<uint32_t>(AlterType::ALTER_SCALAR_FUNCTION), "ALTER_SCALAR_FUNCTION" },
{ static_cast<uint32_t>(AlterType::ALTER_TABLE_FUNCTION), "ALTER_TABLE_FUNCTION" },
{ static_cast<uint32_t>(AlterType::SET_COMMENT), "SET_COMMENT" },
{ static_cast<uint32_t>(AlterType::SET_COLUMN_COMMENT), "SET_COLUMN_COMMENT" }
{ static_cast<uint32_t>(AlterType::SET_COLUMN_COMMENT), "SET_COLUMN_COMMENT" },
{ static_cast<uint32_t>(AlterType::ALTER_DATABASE), "ALTER_DATABASE" }
};
return values;
}

template<>
const char* EnumUtil::ToChars<AlterType>(AlterType value) {
return StringUtil::EnumToString(GetAlterTypeValues(), 9, "AlterType", static_cast<uint32_t>(value));
return StringUtil::EnumToString(GetAlterTypeValues(), 10, "AlterType", static_cast<uint32_t>(value));
}

template<>
AlterType EnumUtil::FromString<AlterType>(const char *value) {
return static_cast<AlterType>(StringUtil::StringToEnum(GetAlterTypeValues(), 9, "AlterType", value));
return static_cast<AlterType>(StringUtil::StringToEnum(GetAlterTypeValues(), 10, "AlterType", value));
}

const StringUtil::EnumStringLiteral *GetAlterViewTypeValues() {
Expand Down
11 changes: 9 additions & 2 deletions src/duckdb/src/execution/operator/schema/physical_alter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "duckdb/execution/operator/schema/physical_alter.hpp"
#include "duckdb/parser/parsed_data/alter_table_info.hpp"
#include "duckdb/parser/parsed_data/alter_database_info.hpp"
#include "duckdb/main/database_manager.hpp"
#include "duckdb/catalog/catalog.hpp"

Expand All @@ -9,8 +10,14 @@ namespace duckdb {
// Source
//===--------------------------------------------------------------------===//
SourceResultType PhysicalAlter::GetData(ExecutionContext &context, DataChunk &chunk, OperatorSourceInput &input) const {
auto &catalog = Catalog::GetCatalog(context.client, info->catalog);
catalog.Alter(context.client, *info);
if (info->type == AlterType::ALTER_DATABASE) {
auto &db_info = info->Cast<AlterDatabaseInfo>();
auto &db_manager = DatabaseManager::Get(context.client);
db_manager.Alter(context.client, db_info);
} else {
auto &catalog = Catalog::GetCatalog(context.client, info->catalog);
catalog.Alter(context.client, *info);
}
return SourceResultType::FINISHED;
}

Expand Down
6 changes: 3 additions & 3 deletions src/duckdb/src/function/table/version/pragma_version.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef DUCKDB_PATCH_VERSION
#define DUCKDB_PATCH_VERSION "0-dev4117"
#define DUCKDB_PATCH_VERSION "0-dev4120"
#endif
#ifndef DUCKDB_MINOR_VERSION
#define DUCKDB_MINOR_VERSION 4
Expand All @@ -8,10 +8,10 @@
#define DUCKDB_MAJOR_VERSION 1
#endif
#ifndef DUCKDB_VERSION
#define DUCKDB_VERSION "v1.4.0-dev4117"
#define DUCKDB_VERSION "v1.4.0-dev4120"
#endif
#ifndef DUCKDB_SOURCE_ID
#define DUCKDB_SOURCE_ID "15fba9f47c"
#define DUCKDB_SOURCE_ID "f8761864ef"
#endif
#include "duckdb/function/table/system_functions.hpp"
#include "duckdb/main/database.hpp"
Expand Down
8 changes: 8 additions & 0 deletions src/duckdb/src/include/duckdb/common/enum_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ enum class AggregateOrderDependent : uint8_t;

enum class AggregateType : uint8_t;

enum class AlterDatabaseType : uint8_t;

enum class AlterForeignKeyType : uint8_t;

enum class AlterScalarFunctionType : uint8_t;
Expand Down Expand Up @@ -472,6 +474,9 @@ const char* EnumUtil::ToChars<AggregateOrderDependent>(AggregateOrderDependent v
template<>
const char* EnumUtil::ToChars<AggregateType>(AggregateType value);

template<>
const char* EnumUtil::ToChars<AlterDatabaseType>(AlterDatabaseType value);

template<>
const char* EnumUtil::ToChars<AlterForeignKeyType>(AlterForeignKeyType value);

Expand Down Expand Up @@ -1091,6 +1096,9 @@ AggregateOrderDependent EnumUtil::FromString<AggregateOrderDependent>(const char
template<>
AggregateType EnumUtil::FromString<AggregateType>(const char *value);

template<>
AlterDatabaseType EnumUtil::FromString<AlterDatabaseType>(const char *value);

template<>
AlterForeignKeyType EnumUtil::FromString<AlterForeignKeyType>(const char *value);

Expand Down
3 changes: 3 additions & 0 deletions src/duckdb/src/include/duckdb/main/attached_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class AttachedDatabase : public CatalogEntry, public enable_shared_from_this<Att
const string &GetName() const {
return name;
}
void SetName(const string &new_name) {
name = new_name;
}
bool IsSystem() const;
bool IsTemporary() const;
bool IsReadOnly() const;
Expand Down
8 changes: 8 additions & 0 deletions src/duckdb/src/include/duckdb/main/database_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ClientContext;
class DatabaseInstance;
class TaskScheduler;
struct AttachOptions;
struct AlterInfo;

//! The DatabaseManager is a class that sits at the root of all attached databases
class DatabaseManager {
Expand Down Expand Up @@ -55,6 +56,8 @@ class DatabaseManager {
shared_ptr<AttachedDatabase> database);
//! Detach an existing database
void DetachDatabase(ClientContext &context, const string &name, OnEntryNotFound if_not_found);
//! Alter operation dispatcher
void Alter(ClientContext &context, AlterInfo &info);
//! Rollback the attach of a database
shared_ptr<AttachedDatabase> DetachInternal(const string &name);
//! Returns a reference to the system catalog
Expand Down Expand Up @@ -124,6 +127,11 @@ class DatabaseManager {
string default_database;
//! Manager for ensuring we never open the same database file twice in the same program
shared_ptr<DatabaseFilePathManager> path_manager;

private:
//! Rename an existing database
void RenameDatabase(ClientContext &context, const string &old_name, const string &new_name,
OnEntryNotFound if_not_found);
};

} // namespace duckdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===----------------------------------------------------------------------===//
// DuckDB
//
// duckdb/parser/parsed_data/alter_database_info.hpp
//
//
//===----------------------------------------------------------------------===//

#pragma once

#include "duckdb/parser/parsed_data/alter_info.hpp"

namespace duckdb {

enum class AlterDatabaseType : uint8_t { RENAME_DATABASE = 0 };

struct AlterDatabaseInfo : public AlterInfo {
public:
AlterDatabaseInfo(AlterDatabaseType alter_database_type, string catalog_p, OnEntryNotFound if_not_found);
~AlterDatabaseInfo() override;

AlterDatabaseType alter_database_type;

public:
CatalogType GetCatalogType() const override;
string ToString() const override = 0;

protected:
void Serialize(Serializer &serializer) const override;
};

struct RenameDatabaseInfo : public AlterDatabaseInfo {
public:
RenameDatabaseInfo(string catalog_p, string new_name_p, OnEntryNotFound if_not_found);

string new_name;

public:
unique_ptr<AlterInfo> Copy() const override;
string ToString() const override;

protected:
void Serialize(Serializer &serializer) const override;
};

} // namespace duckdb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ enum class AlterType : uint8_t {
ALTER_SCALAR_FUNCTION = 5,
ALTER_TABLE_FUNCTION = 6,
SET_COMMENT = 7,
SET_COLUMN_COMMENT = 8
SET_COLUMN_COMMENT = 8,
ALTER_DATABASE = 9
};

struct AlterEntryData {
Expand Down
2 changes: 2 additions & 0 deletions src/duckdb/src/include/duckdb/parser/transformer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ class Transformer {
unique_ptr<SelectStatement> TransformSelectStmt(duckdb_libpgquery::PGNode &node, bool is_select = true);
//! Transform a Postgres T_AlterStmt node into a AlterStatement
unique_ptr<AlterStatement> TransformAlter(duckdb_libpgquery::PGAlterTableStmt &stmt);
//! Transform a Postgres T_AlterDatabaseStmt node into a AlterStatement
unique_ptr<AlterStatement> TransformAlterDatabase(duckdb_libpgquery::PGAlterDatabaseStmt &stmt);
//! Transform a Postgres duckdb_libpgquery::T_PGRenameStmt node into a RenameStatement
unique_ptr<AlterStatement> TransformRename(duckdb_libpgquery::PGRenameStmt &stmt);
//! Transform a Postgres duckdb_libpgquery::T_PGCreateStmt node into a CreateStatement
Expand Down
49 changes: 49 additions & 0 deletions src/duckdb/src/main/database_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "duckdb/storage/storage_manager.hpp"
#include "duckdb/transaction/duck_transaction.hpp"
#include "duckdb/transaction/duck_transaction_manager.hpp"
#include "duckdb/parser/parsed_data/alter_database_info.hpp"

namespace duckdb {

Expand Down Expand Up @@ -143,6 +144,54 @@ void DatabaseManager::DetachDatabase(ClientContext &context, const string &name,
attached_db->OnDetach(context);
}

void DatabaseManager::Alter(ClientContext &context, AlterInfo &info) {
auto &db_info = info.Cast<AlterDatabaseInfo>();

switch (db_info.alter_database_type) {
case AlterDatabaseType::RENAME_DATABASE: {
auto &rename_info = db_info.Cast<RenameDatabaseInfo>();
RenameDatabase(context, db_info.catalog, rename_info.new_name, db_info.if_not_found);
break;
}
default:
throw InternalException("Unsupported ALTER DATABASE operation");
}
}

void DatabaseManager::RenameDatabase(ClientContext &context, const string &old_name, const string &new_name,
OnEntryNotFound if_not_found) {
if (AttachedDatabase::NameIsReserved(new_name)) {
throw BinderException("Database name \"%s\" cannot be used because it is a reserved name", new_name);
}

shared_ptr<AttachedDatabase> attached_db;
{
lock_guard<mutex> guard(databases_lock);
auto old_entry = databases.find(old_name);
if (old_entry == databases.end()) {
if (if_not_found == OnEntryNotFound::THROW_EXCEPTION) {
throw BinderException("Failed to rename database \"%s\": database not found", old_name);
}
return;
}

auto new_entry = databases.find(new_name);
if (new_entry != databases.end()) {
throw BinderException("Failed to rename database \"%s\" to \"%s\": database with new name already exists",
old_name, new_name);
}

attached_db = old_entry->second;
databases.erase(old_entry);
attached_db->SetName(new_name);
databases[new_name] = attached_db;
}

if (default_database == old_name) {
default_database = new_name;
}
}

shared_ptr<AttachedDatabase> DatabaseManager::DetachInternal(const string &name) {
shared_ptr<AttachedDatabase> attached_db;
{
Expand Down
42 changes: 42 additions & 0 deletions src/duckdb/src/parser/parsed_data/alter_database_info.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "duckdb/parser/parsed_data/alter_database_info.hpp"
#include "duckdb/common/serializer/serializer.hpp"

namespace duckdb {

AlterDatabaseInfo::AlterDatabaseInfo(AlterDatabaseType alter_database_type, string catalog_p,
OnEntryNotFound if_not_found)
: AlterInfo(AlterType::ALTER_DATABASE, std::move(catalog_p), "", "", if_not_found),
alter_database_type(alter_database_type) {
}

AlterDatabaseInfo::~AlterDatabaseInfo() {
}

CatalogType AlterDatabaseInfo::GetCatalogType() const {
return CatalogType::DATABASE_ENTRY;
}

void AlterDatabaseInfo::Serialize(Serializer &serializer) const {
AlterInfo::Serialize(serializer);
serializer.WriteProperty(100, "alter_database_type", alter_database_type);
}

RenameDatabaseInfo::RenameDatabaseInfo(string catalog_p, string new_name_p, OnEntryNotFound if_not_found)
: AlterDatabaseInfo(AlterDatabaseType::RENAME_DATABASE, std::move(catalog_p), if_not_found),
new_name(std::move(new_name_p)) {
}

unique_ptr<AlterInfo> RenameDatabaseInfo::Copy() const {
return make_uniq<RenameDatabaseInfo>(catalog, new_name, if_not_found);
}

string RenameDatabaseInfo::ToString() const {
return "ALTER DATABASE " + catalog + " RENAME TO " + new_name;
}

void RenameDatabaseInfo::Serialize(Serializer &serializer) const {
AlterDatabaseInfo::Serialize(serializer);
serializer.WriteProperty(200, "new_name", new_name);
}

} // namespace duckdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "duckdb/parser/statement/alter_statement.hpp"
#include "duckdb/parser/parsed_data/alter_database_info.hpp"
#include "duckdb/parser/transformer.hpp"

namespace duckdb {

unique_ptr<AlterStatement> Transformer::TransformAlterDatabase(duckdb_libpgquery::PGAlterDatabaseStmt &stmt) {
auto result = make_uniq<AlterStatement>();

auto database_name = stmt.dbname ? string(stmt.dbname) : string();
if (database_name.empty()) {
throw ParserException("ALTER DATABASE requires a database name");
}

OnEntryNotFound if_not_found = OnEntryNotFound::THROW_EXCEPTION;
if (stmt.missing_ok) {
if_not_found = OnEntryNotFound::RETURN_NULL;
}

switch (stmt.alter_type) {
case duckdb_libpgquery::PG_ALTER_DATABASE_RENAME: {
if (!stmt.new_name) {
throw ParserException("ALTER DATABASE RENAME requires a new name");
}
auto info = make_uniq<RenameDatabaseInfo>(database_name, string(stmt.new_name), if_not_found);
result->info = std::move(info);
break;
}
default:
throw ParserException("Unsupported ALTER DATABASE operation");
}

return result;
}

} // namespace duckdb
2 changes: 2 additions & 0 deletions src/duckdb/src/parser/transformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ unique_ptr<SQLStatement> Transformer::TransformStatementInternal(duckdb_libpgque
return TransformCreateIndex(PGCast<duckdb_libpgquery::PGIndexStmt>(stmt));
case duckdb_libpgquery::T_PGAlterTableStmt:
return TransformAlter(PGCast<duckdb_libpgquery::PGAlterTableStmt>(stmt));
case duckdb_libpgquery::T_PGAlterDatabaseStmt:
return TransformAlterDatabase(PGCast<duckdb_libpgquery::PGAlterDatabaseStmt>(stmt));
case duckdb_libpgquery::T_PGRenameStmt:
return TransformRename(PGCast<duckdb_libpgquery::PGRenameStmt>(stmt));
case duckdb_libpgquery::T_PGPrepareStmt:
Expand Down
Loading
Loading