Skip to content
Open
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
46 changes: 44 additions & 2 deletions include/paimon/catalog/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,33 @@

#pragma once

#include <chrono>
#include <map>
#include <memory>
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catalog now uses std::optional in multiple method signatures (e.g., RollbackTo/CreateBranch/CreateTag) but the header does not include <optional>, which will cause compilation failures for translation units that include this header without already including <optional>. Add #include <optional> here.

Suggested change
#include <memory>
#include <memory>
#include <optional>

Copilot uses AI. Check for mistakes.
#include <string>
#include <variant>
#include <vector>

#include "paimon/catalog/identifier.h"
#include "paimon/result.h"
#include "paimon/schema/schema.h"
#include "paimon/status.h"
#include "paimon/type_fwd.h"
#include "paimon/visibility.h"

struct ArrowSchema;

namespace paimon {
// Tag name or snapshot id
using Instant = std::variant<std::string, int64_t>;

class Database;
class Table;
class View;
class Schema;
class Snapshot;
class PartitionStatistics;
class Tag;
class Identifier;
Comment on lines +38 to +45
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This public header forward-declares Table, View, Snapshot, Tag, etc., and returns/accepts them via std::shared_ptr<> in the public API. Since only include/ is installed (not src/), API consumers won’t have access to these type definitions, and destroying a std::shared_ptr<IncompleteType> (created in the library with the default deleter) typically requires the complete type in the consumer TU. Please either move these interface types into public headers under include/, or adjust the API to avoid owning shared_ptr to incomplete types (e.g., return metadata/IDs, or use an exported custom deleter pattern).

Copilot uses AI. Check for mistakes.

/// This interface is responsible for reading and writing metadata such as database/table from a
/// paimon catalog.
class PAIMON_EXPORT Catalog {
Expand Down Expand Up @@ -99,6 +109,38 @@ class PAIMON_EXPORT Catalog {
/// status.
virtual Result<std::vector<std::string>> ListTables(const std::string& db_name) const = 0;

/// Drops a database.
///
/// @param name Name of the database to be dropped.
/// @param ignore_if_not_exists If true, no action is taken if the database does not exist.
/// @param cascade If true, drops all tables and functions in the database before dropping the
/// database.
/// @return A status indicating success or failure.
virtual Status DropDatabase(const std::string& name, bool ignore_if_not_exists,
bool cascade) = 0;

/// Drops a table.
///
/// @param identifier Identifier of the table to drop.
/// @param ignore_if_not_exists If true, no action is taken if the table does not exist.
/// @return A status indicating success or failure.
virtual Status DropTable(const Identifier& identifier, bool ignore_if_not_exists) = 0;

/// Renames a table.
///
/// @param from_table Current identifier of the table.
/// @param to_table New identifier for the table.
/// @param ignore_if_not_exists If true, no action is taken if the table does not exist.
/// @return A status indicating success or failure.
virtual Status RenameTable(const Identifier& from_table, const Identifier& to_table,
bool ignore_if_not_exists) = 0;

/// Gets a table.
///
/// @param identifier Identifier of the table to get.
/// @return A result containing the table, or an error status.
virtual Result<std::shared_ptr<Table>> GetTable(const Identifier& identifier) const = 0;

/// Checks whether a database with the specified name exists in the catalog.
///
/// @param db_name The name of the database to check for existence.
Expand Down
50 changes: 50 additions & 0 deletions include/paimon/catalog/database.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2026-present Alibaba Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <map>
#include <memory>
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header uses std::optional in Comment() but does not include <optional>, which can cause compilation failures depending on include order. Add #include <optional> to this header.

Suggested change
#include <memory>
#include <memory>
#include <optional>

Copilot uses AI. Check for mistakes.
#include <string>
#include <vector>

#include "paimon/result.h"
#include "paimon/status.h"
#include "paimon/type_fwd.h"
#include "paimon/visibility.h"

struct ArrowSchema;

namespace paimon {

/// Interface of a database in a catalog.
class PAIMON_EXPORT Database {
public:
/// ================== Table Metadata =====================
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

virtual ~Database() = default;


/// A name to identify this database.
virtual std::string Name() const = 0;

Comment on lines +34 to +40
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Database declares virtual methods but does not declare a virtual destructor. Deleting a derived instance through a Database* (or via smart pointers) would be undefined behavior. Add virtual ~Database() = default; (or a protected non-virtual destructor if you want to prevent deletion via base pointer).

Copilot uses AI. Check for mistakes.
/// Get the table-level options associated with this schema.
/// @return Options
virtual const std::map<std::string, std::string>& Options() const = 0;

/// Get an optional comment describing the table.
/// @return The table comment if set, or std::nullopt otherwise.
Comment on lines +41 to +46
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstrings here refer to “table-level options” and “table comment”, but this interface is for a database. Please update the wording (database-level options/comment) to match the actual type and avoid confusing generated API docs.

Suggested change
/// Get the table-level options associated with this schema.
/// @return Options
virtual const std::map<std::string, std::string>& Options() const = 0;
/// Get an optional comment describing the table.
/// @return The table comment if set, or std::nullopt otherwise.
/// Get the database-level options associated with this database.
/// @return Options
virtual const std::map<std::string, std::string>& Options() const = 0;
/// Get an optional comment describing the database.
/// @return The database comment if set, or std::nullopt otherwise.

Copilot uses AI. Check for mistakes.
virtual std::optional<std::string> Comment() const = 0;
};

} // namespace paimon
107 changes: 106 additions & 1 deletion src/paimon/core/catalog/file_system_catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "paimon/common/utils/arrow/status_utils.h"
#include "paimon/common/utils/path_util.h"
#include "paimon/common/utils/string_utils.h"
#include "paimon/core/schema/schema_manager.h"
#include "paimon/fs/file_system.h"
#include "paimon/logging.h"
#include "paimon/result.h"
Expand Down Expand Up @@ -240,4 +239,110 @@ Result<std::shared_ptr<Schema>> FileSystemCatalog::LoadTableSchema(
return std::static_pointer_cast<Schema>(*latest_schema);
}

Result<std::shared_ptr<Table>> FileSystemCatalog::GetTable(const Identifier& identifier) const {
std::string table_path = GetTableLocation(identifier);
PAIMON_ASSIGN_OR_RAISE(bool exist, fs_->Exists(table_path));
if (!exist) {
return Status::NotExist(fmt::format("{} not exist", identifier.ToString()));
}
PAIMON_ASSIGN_OR_RAISE(std::optional<std::shared_ptr<TableSchema>> latest_schema,
TableSchemaExists(identifier));
if (!latest_schema) {
return Status::NotExist(
fmt::format("load table schema for {} failed", identifier.ToString()));
}
auto schema = std::static_pointer_cast<Schema>(*latest_schema);
return std::make_shared<Table>(schema, identifier.GetDatabaseName(), identifier.GetTableName());
}

Status FileSystemCatalog::DropDatabase(const std::string& name, bool ignore_if_not_exists,
bool cascade) {
if (IsSystemDatabase(name)) {
return Status::Invalid(fmt::format("Cannot drop system database {}.", name));
}

PAIMON_ASSIGN_OR_RAISE(bool exist, DatabaseExists(name));
if (!exist) {
if (ignore_if_not_exists) {
return Status::OK();
} else {
return Status::NotExist(fmt::format("database {} does not exist", name));
}
}

std::string db_path = NewDatabasePath(warehouse_, name);

if (cascade) {
// List all tables in the database and drop them
PAIMON_ASSIGN_OR_RAISE(std::vector<std::string> tables, ListTables(name));
for (const std::string& table_name : tables) {
Identifier table_id(name, table_name);
PAIMON_RETURN_NOT_OK(DropTable(table_id, false));
}
} else {
// Check if database is empty
PAIMON_ASSIGN_OR_RAISE(std::vector<std::string> tables, ListTables(name));
if (!tables.empty()) {
return Status::Invalid(
fmt::format("Cannot drop non-empty database {}. Use cascade=true to force.", name));
}
}

// Delete the database directory
PAIMON_RETURN_NOT_OK(fs_->Delete(db_path));
return Status::OK();
}

Status FileSystemCatalog::DropTable(const Identifier& identifier, bool ignore_if_not_exists) {
if (IsSystemTable(identifier)) {
return Status::Invalid(fmt::format("Cannot drop system table {}.", identifier.ToString()));
}

PAIMON_ASSIGN_OR_RAISE(bool exist, TableExists(identifier));
Copy link
Collaborator

@lszskye lszskye Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

support drop external path here~

if (!exist) {
if (ignore_if_not_exists) {
return Status::OK();
} else {
return Status::NotExist(fmt::format("table {} does not exist", identifier.ToString()));
}
}

std::string table_path = GetTableLocation(identifier);
PAIMON_RETURN_NOT_OK(fs_->Delete(table_path));
return Status::OK();
}

Status FileSystemCatalog::RenameTable(const Identifier& from_table, const Identifier& to_table,
bool ignore_if_not_exists) {
if (IsSystemTable(from_table) || IsSystemTable(to_table)) {
return Status::Invalid(fmt::format("Cannot rename system table {} or {}.",
from_table.ToString(), to_table.ToString()));
}

if (from_table.GetDatabaseName() != to_table.GetDatabaseName()) {
return Status::Invalid(
"Cannot rename table across databases. Cross-database rename is not supported.");
}

PAIMON_ASSIGN_OR_RAISE(bool from_exist, TableExists(from_table));
if (!from_exist) {
if (ignore_if_not_exists) {
return Status::OK();
} else {
return Status::NotExist(
fmt::format("source table {} does not exist", from_table.ToString()));
}
}

PAIMON_ASSIGN_OR_RAISE(bool to_exist, TableExists(to_table));
if (to_exist) {
return Status::Invalid(fmt::format("target table {} already exists", to_table.ToString()));
}

std::string from_path = GetTableLocation(from_table);
std::string to_path = GetTableLocation(to_table);
PAIMON_RETURN_NOT_OK(fs_->Rename(from_path, to_path));
return Status::OK();
}

} // namespace paimon
8 changes: 7 additions & 1 deletion src/paimon/core/catalog/file_system_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <vector>

#include "paimon/catalog/catalog.h"
#include "paimon/core/schema/schema_manager.h"
#include "paimon/core/table/table.h"
#include "paimon/logging.h"
#include "paimon/result.h"
#include "paimon/status.h"
Expand All @@ -46,7 +48,10 @@ class FileSystemCatalog : public Catalog {
const std::vector<std::string>& primary_keys,
const std::map<std::string, std::string>& options,
bool ignore_if_exists) override;

Status DropDatabase(const std::string& name, bool ignore_if_not_exists, bool cascade) override;
Status DropTable(const Identifier& identifier, bool ignore_if_not_exists) override;
Status RenameTable(const Identifier& from_table, const Identifier& to_table,
bool ignore_if_not_exists) override;
Result<std::vector<std::string>> ListDatabases() const override;
Result<std::vector<std::string>> ListTables(const std::string& db_name) const override;
Result<bool> DatabaseExists(const std::string& db_name) const override;
Expand All @@ -56,6 +61,7 @@ class FileSystemCatalog : public Catalog {
Result<std::shared_ptr<Schema>> LoadTableSchema(const Identifier& identifier) const override;
std::string GetRootPath() const override;
std::shared_ptr<FileSystem> GetFileSystem() const override;
Result<std::shared_ptr<Table>> GetTable(const Identifier& identifier) const override;

private:
static std::string NewDatabasePath(const std::string& warehouse, const std::string& db_name);
Expand Down
Loading
Loading