Skip to content

Commit 92b61e3

Browse files
authored
feat(catalog, schema): Add existence check and schema improvements (alibaba#56)
1 parent a55b218 commit 92b61e3

8 files changed

Lines changed: 74 additions & 95 deletions

File tree

include/paimon/catalog/catalog.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ class PAIMON_EXPORT Catalog {
9595
/// status.
9696
virtual Result<std::vector<std::string>> ListTables(const std::string& db_name) const = 0;
9797

98+
/// Checks whether a database with the specified name exists in the catalog.
99+
///
100+
/// @param db_name The name of the database to check for existence.
101+
/// @return A result containing true if the database exists, false otherwise, or an error
102+
/// status.
103+
virtual Result<bool> DataBaseExists(const std::string& db_name) const = 0;
104+
105+
/// Checks whether a table with the specified identifier exists in the catalog.
106+
///
107+
/// @param identifier The identifier of the table to check for existence.
108+
/// @return A result containing true if the table exists, false otherwise, or an error status.
109+
virtual Result<bool> TableExists(const Identifier& identifier) const = 0;
110+
98111
/// Loads the latest schema of a specified table.
99112
///
100113
/// @note System tables will not be supported.

include/paimon/schema/schema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ class PAIMON_EXPORT Schema {
3939
/// @return A result containing an ArrowSchema, or an error status if conversion fails.
4040
virtual Result<std::unique_ptr<::ArrowSchema>> GetArrowSchema() const = 0;
4141

42+
/// Get the JSON schema representation of this table schema.
43+
///
44+
/// This method provides a JSON string that represents the complete schema information.
45+
///
46+
/// @return A string containing the JSON schema, or an error status on failure.
47+
virtual Result<std::string> GetJsonSchema() const = 0;
48+
4249
/// Get the names of all fields in the table schema.
4350
/// @return A vector of field names.
4451
virtual std::vector<std::string> FieldNames() const = 0;

src/paimon/core/catalog/file_system_catalog.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "paimon/common/utils/arrow/status_utils.h"
2828
#include "paimon/common/utils/path_util.h"
2929
#include "paimon/common/utils/string_utils.h"
30-
#include "paimon/core/schema/schema_impl.h"
3130
#include "paimon/core/schema/schema_manager.h"
3231
#include "paimon/fs/file_system.h"
3332
#include "paimon/logging.h"
@@ -87,6 +86,12 @@ Result<bool> FileSystemCatalog::DataBaseExists(const std::string& db_name) const
8786
return fs_->Exists(NewDatabasePath(warehouse_, db_name));
8887
}
8988

89+
Result<bool> FileSystemCatalog::TableExists(const Identifier& identifier) const {
90+
PAIMON_ASSIGN_OR_RAISE(std::optional<std::shared_ptr<TableSchema>> latest_schema,
91+
TableSchemaExists(identifier));
92+
return latest_schema != std::nullopt;
93+
}
94+
9095
Status FileSystemCatalog::CreateTable(const Identifier& identifier, ArrowSchema* c_schema,
9196
const std::vector<std::string>& partition_keys,
9297
const std::vector<std::string>& primary_keys,
@@ -216,7 +221,7 @@ Result<std::shared_ptr<Schema>> FileSystemCatalog::LoadTableSchema(
216221
if (!latest_schema) {
217222
return Status::NotExist(fmt::format("{} not exist", identifier.ToString()));
218223
}
219-
return std::make_shared<SchemaImpl>(*latest_schema);
224+
return std::static_pointer_cast<Schema>(*latest_schema);
220225
}
221226

222227
} // namespace paimon

src/paimon/core/catalog/file_system_catalog.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class FileSystemCatalog : public Catalog {
4949

5050
Result<std::vector<std::string>> ListDatabases() const override;
5151
Result<std::vector<std::string>> ListTables(const std::string& database_names) const override;
52+
Result<bool> DataBaseExists(const std::string& db_name) const override;
53+
Result<bool> TableExists(const Identifier& identifier) const override;
5254
Result<std::shared_ptr<Schema>> LoadTableSchema(const Identifier& identifier) const override;
5355

5456
private:
@@ -57,7 +59,6 @@ class FileSystemCatalog : public Catalog {
5759
static bool IsSystemDatabase(const std::string& db_name);
5860
static bool IsSpecifiedSystemTable(const Identifier& identifier);
5961
static bool IsSystemTable(const Identifier& identifier);
60-
Result<bool> DataBaseExists(const std::string& db_name) const;
6162
Result<std::optional<std::shared_ptr<TableSchema>>> TableSchemaExists(
6263
const Identifier& identifier) const;
6364

src/paimon/core/catalog/file_system_catalog_test.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,16 @@ TEST(FileSystemCatalogTest, TestCreateTable) {
134134
arrow::Schema typed_schema(fields);
135135
::ArrowSchema schema;
136136
ASSERT_TRUE(arrow::ExportSchema(typed_schema, &schema).ok());
137-
ASSERT_OK(catalog.CreateTable(Identifier("db1", "tbl1"), &schema,
137+
Identifier identifier("db1", "tbl1");
138+
ASSERT_OK_AND_ASSIGN(auto exist, catalog.TableExists(identifier));
139+
ASSERT_FALSE(exist);
140+
141+
ASSERT_OK(catalog.CreateTable(identifier, &schema,
138142
/*partition_keys=*/{"f1", "f2"}, /*primary_keys=*/{"f3"}, options,
139143
false));
140-
ASSERT_OK_AND_ASSIGN(std::vector<std::string> table_names, catalog.ListTables("db1"));
141-
ASSERT_EQ(1, table_names.size());
142-
ASSERT_EQ(table_names[0], "tbl1");
144+
145+
ASSERT_OK_AND_ASSIGN(exist, catalog.TableExists(identifier));
146+
ASSERT_TRUE(exist);
143147
ArrowSchemaRelease(&schema);
144148
}
145149

@@ -349,13 +353,19 @@ TEST(FileSystemCatalogTest, TestValidateTableSchema) {
349353
std::vector<std::string> expected_field_names = {"f0", "f1", "f2", "f3"};
350354
ASSERT_EQ(field_names, expected_field_names);
351355

356+
ASSERT_OK_AND_ASSIGN(auto fs, FileSystemFactory::Get("local", dir->Str(), {}));
357+
std::string schema_path = PathUtil::JoinPath(dir->Str(), "db1.db/tbl1/schema/schema-0");
358+
std::string expected_json_schema;
359+
ASSERT_OK(fs->ReadFile(schema_path, &expected_json_schema));
360+
361+
ASSERT_OK_AND_ASSIGN(auto json_schema, table_schema->GetJsonSchema());
362+
ASSERT_EQ(expected_json_schema, json_schema);
363+
352364
ASSERT_OK_AND_ASSIGN(auto arrow_schema, table_schema->GetArrowSchema());
353365
auto loaded_schema = arrow::ImportSchema(arrow_schema.get()).ValueOrDie();
354366
ASSERT_TRUE(typed_schema.Equals(loaded_schema));
355367

356-
ASSERT_OK_AND_ASSIGN(auto fs, FileSystemFactory::Get("local", dir->Str(), {}));
357-
ASSERT_OK(fs->Delete(PathUtil::JoinPath(dir->Str(), "db1.db/tbl1/schema/schema-0")));
358-
368+
ASSERT_OK(fs->Delete(schema_path));
359369
ASSERT_NOK_WITH_MSG(catalog.LoadTableSchema(Identifier("db1", "tbl1")),
360370
"Identifier{database=\'db1\', table=\'tbl1\'} not exist");
361371

src/paimon/core/schema/schema_impl.h

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/paimon/core/schema/table_schema.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "fmt/format.h"
2828
#include "paimon/common/utils/arrow/status_utils.h"
2929
#include "paimon/common/utils/date_time_utils.h"
30+
#include "paimon/common/utils/field_type_utils.h"
3031
#include "paimon/common/utils/object_utils.h"
3132
#include "paimon/common/utils/options_utils.h"
3233
#include "paimon/common/utils/rapidjson_util.h"
@@ -169,6 +170,14 @@ bool TableSchema::operator==(const TableSchema& other) const {
169170
options_ == other.options_ && comment_ == other.comment_ &&
170171
time_millis_ == other.time_millis_;
171172
}
173+
174+
Result<std::unique_ptr<::ArrowSchema>> TableSchema::GetArrowSchema() const {
175+
auto schema = DataField::ConvertDataFieldsToArrowSchema(fields_);
176+
auto c_schema = std::make_unique<::ArrowSchema>();
177+
PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportSchema(*schema, c_schema.get()));
178+
return c_schema;
179+
}
180+
172181
std::vector<std::string> TableSchema::FieldNames() const {
173182
std::vector<std::string> field_names;
174183
field_names.reserve(fields_.size());

src/paimon/core/schema/table_schema.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "paimon/common/types/data_field.h"
2828
#include "paimon/common/utils/jsonizable.h"
2929
#include "paimon/result.h"
30+
#include "paimon/schema/schema.h"
3031
#include "rapidjson/allocators.h"
3132
#include "rapidjson/document.h"
3233
#include "rapidjson/rapidjson.h"
@@ -35,7 +36,7 @@ struct ArrowSchema;
3536

3637
namespace paimon {
3738
/// Schema of a table, including schemaId and fieldId.
38-
class TableSchema : public Jsonizable<TableSchema> {
39+
class TableSchema : public Schema, public Jsonizable<TableSchema> {
3940
public:
4041
static constexpr int64_t FIRST_SCHEMA_ID = 0;
4142
static constexpr int32_t PAIMON_07_VERSION = 1;
@@ -57,28 +58,35 @@ class TableSchema : public Jsonizable<TableSchema> {
5758

5859
bool operator==(const TableSchema& other) const;
5960

60-
std::vector<std::string> FieldNames() const;
61-
int64_t Id() const {
61+
Result<std::unique_ptr<::ArrowSchema>> GetArrowSchema() const override;
62+
63+
Result<std::string> GetJsonSchema() const override {
64+
return ToJsonString();
65+
}
66+
67+
std::vector<std::string> FieldNames() const override;
68+
69+
int64_t Id() const override {
6270
return id_;
6371
}
64-
const std::vector<std::string>& PrimaryKeys() const {
72+
const std::vector<std::string>& PrimaryKeys() const override {
6573
return primary_keys_;
6674
}
67-
const std::vector<std::string>& PartitionKeys() const {
75+
const std::vector<std::string>& PartitionKeys() const override {
6876
return partition_keys_;
6977
}
7078

71-
const std::vector<std::string>& BucketKeys() const {
79+
const std::vector<std::string>& BucketKeys() const override {
7280
return bucket_keys_;
7381
}
7482

75-
int32_t NumBuckets() const {
83+
int32_t NumBuckets() const override {
7684
return num_bucket_;
7785
}
78-
int32_t HighestFieldId() const {
86+
int32_t HighestFieldId() const override {
7987
return highest_field_id_;
8088
}
81-
const std::map<std::string, std::string>& Options() const {
89+
const std::map<std::string, std::string>& Options() const override {
8290
return options_;
8391
}
8492
const std::vector<DataField>& Fields() const {
@@ -92,7 +100,7 @@ class TableSchema : public Jsonizable<TableSchema> {
92100
Result<std::vector<DataField>> GetFields(const std::vector<std::string>& field_names) const;
93101
Result<std::vector<std::string>> TrimmedPrimaryKeys() const;
94102

95-
std::optional<std::string> Comment() const {
103+
std::optional<std::string> Comment() const override {
96104
return comment_;
97105
}
98106

@@ -130,7 +138,7 @@ class TableSchema : public Jsonizable<TableSchema> {
130138
std::vector<std::string> partition_keys_;
131139
std::vector<std::string> primary_keys_;
132140
std::vector<std::string> bucket_keys_;
133-
int32_t num_bucket_;
141+
int32_t num_bucket_ = -1;
134142
std::map<std::string, std::string> options_;
135143
std::optional<std::string> comment_;
136144
int64_t time_millis_ = -1;

0 commit comments

Comments
 (0)