|
25 | 25 |
|
26 | 26 | #include "arrow/api.h" |
27 | 27 | #include "gtest/gtest.h" |
| 28 | +#include "paimon/commit_context.h" |
28 | 29 | #include "paimon/core/schema/schema_manager.h" |
29 | 30 | #include "paimon/core/schema/table_schema.h" |
| 31 | +#include "paimon/file_store_commit.h" |
| 32 | +#include "paimon/file_store_write.h" |
| 33 | +#include "paimon/read_context.h" |
| 34 | +#include "paimon/scan_context.h" |
30 | 35 | #include "paimon/schema/schema.h" |
| 36 | +#include "paimon/table/source/table_read.h" |
| 37 | +#include "paimon/table/source/table_scan.h" |
| 38 | +#include "paimon/testing/mock/mock_catalog.h" |
31 | 39 | #include "paimon/testing/utils/testharness.h" |
| 40 | +#include "paimon/write_context.h" |
32 | 41 |
|
33 | 42 | namespace paimon::test { |
34 | 43 |
|
| 44 | +namespace { |
| 45 | + |
| 46 | +// Creates a managed table directory and opens it as a `Table` under `identifier`. |
| 47 | +Result<std::shared_ptr<Table>> CreateManagedTable(const std::shared_ptr<FileSystem>& file_system, |
| 48 | + const std::string& path, |
| 49 | + const Identifier& identifier) { |
| 50 | + SchemaManager schema_manager(file_system, path); |
| 51 | + auto schema = arrow::schema({arrow::field("id", arrow::int32(), /*nullable=*/false)}); |
| 52 | + PAIMON_ASSIGN_OR_RAISE([[maybe_unused]] std::unique_ptr<TableSchema> created, |
| 53 | + schema_manager.CreateTable(schema, /*partition_keys=*/{}, |
| 54 | + /*primary_keys=*/{}, /*options=*/{})); |
| 55 | + return Table::Create(file_system, path, identifier); |
| 56 | +} |
| 57 | + |
| 58 | +} // namespace |
| 59 | + |
35 | 60 | TEST(TableTest, TestCreateWithUnknownDatabase) { |
36 | 61 | auto dir = UniqueTestDirectory::Create(); |
37 | 62 | ASSERT_TRUE(dir); |
@@ -123,4 +148,89 @@ TEST(TableTest, TestCreateFailedWithNonExistSchema) { |
123 | 148 | "load table schema for Identifier{database='unknown', object='tbl1'} failed"); |
124 | 149 | } |
125 | 150 |
|
| 151 | +TEST(TableTest, TestNewScanCreatesATableScan) { |
| 152 | + auto dir = UniqueTestDirectory::Create(); |
| 153 | + ASSERT_TRUE(dir); |
| 154 | + const Identifier identifier("db", "tbl"); |
| 155 | + ASSERT_OK_AND_ASSIGN(std::shared_ptr<Table> table, |
| 156 | + CreateManagedTable(dir->GetFileSystem(), dir->Str(), identifier)); |
| 157 | + |
| 158 | + auto catalog = std::make_shared<MockVersionManagedCatalog>(); |
| 159 | + catalog->SetFileSystem(dir->GetFileSystem()); |
| 160 | + |
| 161 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<ScanContext> ctx, |
| 162 | + ScanContextBuilder(dir->Str()).WithCatalog(catalog, identifier).Finish()); |
| 163 | + ASSERT_OK_AND_ASSIGN([[maybe_unused]] std::unique_ptr<TableScan> scan, |
| 164 | + table->NewScan(std::move(ctx))); |
| 165 | +} |
| 166 | + |
| 167 | +TEST(TableTest, TestNewReadCreatesATableRead) { |
| 168 | + auto dir = UniqueTestDirectory::Create(); |
| 169 | + ASSERT_TRUE(dir); |
| 170 | + const Identifier identifier("db", "tbl"); |
| 171 | + ASSERT_OK_AND_ASSIGN(std::shared_ptr<Table> table, |
| 172 | + CreateManagedTable(dir->GetFileSystem(), dir->Str(), identifier)); |
| 173 | + |
| 174 | + auto catalog = std::make_shared<MockVersionManagedCatalog>(); |
| 175 | + catalog->SetFileSystem(dir->GetFileSystem()); |
| 176 | + |
| 177 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<ReadContext> ctx, |
| 178 | + ReadContextBuilder(dir->Str()).WithCatalog(catalog, identifier).Finish()); |
| 179 | + ASSERT_OK_AND_ASSIGN([[maybe_unused]] std::unique_ptr<TableRead> read, |
| 180 | + table->NewRead(std::move(ctx))); |
| 181 | +} |
| 182 | + |
| 183 | +TEST(TableTest, TestNewWriteCreatesAFileStoreWrite) { |
| 184 | + auto dir = UniqueTestDirectory::Create(); |
| 185 | + ASSERT_TRUE(dir); |
| 186 | + const Identifier identifier("db", "tbl"); |
| 187 | + ASSERT_OK_AND_ASSIGN(std::shared_ptr<Table> table, |
| 188 | + CreateManagedTable(dir->GetFileSystem(), dir->Str(), identifier)); |
| 189 | + |
| 190 | + auto catalog = std::make_shared<MockVersionManagedCatalog>(); |
| 191 | + catalog->SetFileSystem(dir->GetFileSystem()); |
| 192 | + // A catalog write reads the current schema from the catalog on the main branch. |
| 193 | + catalog->SetTableSchema(table->LatestSchema()); |
| 194 | + |
| 195 | + ASSERT_OK_AND_ASSIGN( |
| 196 | + std::unique_ptr<WriteContext> ctx, |
| 197 | + WriteContextBuilder(dir->Str(), "commit-user").WithCatalog(catalog, identifier).Finish()); |
| 198 | + ASSERT_OK_AND_ASSIGN([[maybe_unused]] std::unique_ptr<FileStoreWrite> write, |
| 199 | + table->NewWrite(std::move(ctx))); |
| 200 | +} |
| 201 | + |
| 202 | +TEST(TableTest, TestNewCommitCreatesAFileStoreCommit) { |
| 203 | + auto dir = UniqueTestDirectory::Create(); |
| 204 | + ASSERT_TRUE(dir); |
| 205 | + const Identifier identifier("db", "tbl"); |
| 206 | + ASSERT_OK_AND_ASSIGN(std::shared_ptr<Table> table, |
| 207 | + CreateManagedTable(dir->GetFileSystem(), dir->Str(), identifier)); |
| 208 | + |
| 209 | + auto catalog = std::make_shared<MockVersionManagedCatalog>(); |
| 210 | + catalog->SetFileSystem(dir->GetFileSystem()); |
| 211 | + // Like a write, a catalog commit reads the current schema from the catalog. |
| 212 | + catalog->SetTableSchema(table->LatestSchema()); |
| 213 | + |
| 214 | + ASSERT_OK_AND_ASSIGN( |
| 215 | + std::unique_ptr<CommitContext> ctx, |
| 216 | + CommitContextBuilder(dir->Str(), "commit-user").WithCatalog(catalog, identifier).Finish()); |
| 217 | + ASSERT_OK_AND_ASSIGN([[maybe_unused]] std::unique_ptr<FileStoreCommit> commit, |
| 218 | + table->NewCommit(std::move(ctx))); |
| 219 | +} |
| 220 | + |
| 221 | +TEST(TableTest, TestNewScanReadWriteCommitRejectANullContext) { |
| 222 | + auto dir = UniqueTestDirectory::Create(); |
| 223 | + ASSERT_TRUE(dir); |
| 224 | + ASSERT_OK_AND_ASSIGN( |
| 225 | + std::shared_ptr<Table> table, |
| 226 | + CreateManagedTable(dir->GetFileSystem(), dir->Str(), Identifier("db", "tbl"))); |
| 227 | + |
| 228 | + // The operators report the null context themselves; the table stands in without swallowing |
| 229 | + // the error, so behavior matches `TableScan::Create` and friends. |
| 230 | + ASSERT_NOK_WITH_MSG(table->NewScan(nullptr), "scan context is null pointer"); |
| 231 | + ASSERT_NOK_WITH_MSG(table->NewRead(nullptr), "read context is null pointer"); |
| 232 | + ASSERT_NOK_WITH_MSG(table->NewWrite(nullptr), "write context is null pointer"); |
| 233 | + ASSERT_NOK_WITH_MSG(table->NewCommit(nullptr), "commit context is null pointer"); |
| 234 | +} |
| 235 | + |
126 | 236 | } // namespace paimon::test |
0 commit comments