TheR1sing3un opened a new pull request, #7747:
URL: https://github.com/apache/paimon/pull/7747

   ## Purpose
   
   `pypaimon`'s `Catalog` ABC has stubs for `create_branch` / `drop_branch` / 
`fast_forward` / `list_branches` raising `NotImplementedError`, and is missing 
`rename_branch` entirely. The `RESTCatalog` never overrode any of them, so 
calling any branch operation on a real REST catalog raises 
`NotImplementedError` instead of issuing the REST call. Java defines all five 
(`paimon-core/.../catalog/Catalog.java:843-912`) with a complete REST 
implementation in `paimon-core/.../rest/RESTCatalog.java:703-769`. This PR 
closes that gap.
   
   This is the sister PR of [#7746 — Tag 
CRUD](https://github.com/apache/paimon/pull/7746); same shape (abstract stub + 
RESTCatalog overrides + wire DTOs + URL builders + mock REST server route 
handlers + tests). `FilesystemCatalog` inherits the abstract 
`NotImplementedError` stubs; a Python-side `BranchManager` port is tracked 
separately.
   
   ## Linked issue
   
   n/a — closing an API gap surfaced while auditing pypaimon's `Catalog` 
against the Java contract.
   
   ## Tests
   
   - `pypaimon/tests/api/test_branch_dto_serde.py` — 11 unit tests pinning the 
wire format to Java: exact JSON field names (`branch` / `fromTag` / `toBranch` 
/ `branches`), URL templates 
(`databases/{db}/tables/{tbl}/branches[/{branch}[/rename|/forward]]`), and an 
explicit assertion that `ListBranchesResponse` is **not** paged (no 
`nextPageToken`).
   - `pypaimon/tests/rest/rest_branch_test.py` — 11 end-to-end tests against 
the in-process mock REST server mirroring Java `RESTCatalogTest::testBranches` 
(`paimon-core/.../rest/RESTCatalogTest.java:2138-2191`): create / list happy 
path, table-not-exist on create / list, duplicate create raises 
`BranchAlreadyExistException`, rename happy / collide / source-missing, drop 
happy / missing, fast-forward happy / missing. Plus 1 `FilesystemCatalog` 
`NotImplementedError` sanity test for the new `rename_branch` abstract stub.
   - Regression: `pypaimon/tests/rest/rest_simple_test.py rest_function_test.py 
rest_catalog_test.py` (52 tests) all pass unchanged.
   - All new/edited files pass `flake8 --config=dev/cfg.ini`.
   
   ## API and format
   
   Adds 1 new public method on `Catalog`: `rename_branch(identifier, 
from_branch, to_branch)`. Defaults to `NotImplementedError` — non-breaking; 
existing 4 branch stubs are not modified.
   
   Wire format additions:
   
   | Endpoint | Method | DTO |
   |---|---|---|
   | `/v1/{prefix}/databases/{db}/tables/{tbl}/branches` | POST | 
`CreateBranchRequest { branch, fromTag? }` |
   | `/v1/{prefix}/databases/{db}/tables/{tbl}/branches` | GET | 
`ListBranchesResponse { branches }` (NOT paged) |
   | `/v1/{prefix}/databases/{db}/tables/{tbl}/branches/{branch}` | DELETE | — |
   | `/v1/{prefix}/databases/{db}/tables/{tbl}/branches/{branch}/rename` | POST 
| `RenameBranchRequest { toBranch }` |
   | `/v1/{prefix}/databases/{db}/tables/{tbl}/branches/{branch}/forward` | 
POST | `ForwardBranchRequest {}` (empty body) |
   
   These are wire-compatible with the Java REST server 
(`paimon-api/.../rest/requests/CreateBranchRequest.java`, 
`RenameBranchRequest.java`, `ForwardBranchRequest.java`, 
`responses/ListBranchesResponse.java`, `RESTApi.java:945-1029`, 
`RESTCatalog.java:703-769`).
   
   No new typed exception classes are introduced (`BranchNotExistException` / 
`BranchAlreadyExistException` already exist on master).
   
   ## Documentation
   
   n/a — this is an API gap closure. Java docs cover the semantics; the Python 
port mirrors Java behavior verbatim.
   
   ## Out of scope (separate PRs)
   
   - `FilesystemCatalog` branch implementation — needs a Python-side 
`BranchManager` port (corresponds to Java 
`paimon-core/.../utils/BranchManager.java`).
   - Paged `list_branches` — Java has no paged version, so neither do we. If 
Java adds `listBranchesPaged` in the future, mirror it then.
   - CLI branch commands — pypaimon CLI has no branch commands today.
   - Branch name validation rules (reserved keywords etc.) — Java's 
`RESTCatalog.createBranch` rejects with `BadRequestException`; we map that to 
`IllegalArgumentError` and forward the server message.
   - `from_tag` existence enforcement in the **mock** REST server — pypaimon 
does not yet have a Python-side `TagManager` port, so the mock accepts any 
non-empty `from_tag`. The real Java REST server validates against `TagManager` 
and returns 404+TAG when missing; our `RESTCatalog.create_branch` correctly 
maps that to `TagNotExistException`. The `from_tag` not-exists path will be 
covered once the Python `TagManager` port lands.
   
   ## Strict-Java-alignment checklist
   
   - [x] **Wire DTO field names**: `CreateBranchRequest` = `{branch, fromTag}`, 
`RenameBranchRequest` = `{toBranch}`, `ForwardBranchRequest` = `{}`, 
`ListBranchesResponse` = `{branches}`. Asserted by `test_branch_dto_serde.py`.
   - [x] **URL templates**: exactly match Java `ResourcePaths.java:240-276` 
char-for-char 
(`databases/{db}/tables/{tbl}/branches[/{branch}[/rename|/forward]]`). Asserted 
by `test_resource_path_*` cases.
   - [x] **No paged listing**: `ListBranchesResponse` extends `RESTResponse` 
(NOT `PagedResponse`); `rest_api.list_branches` returns plain `List[str]`. 
`test_response_is_not_paged` asserts no `next_page_token` attribute and no 
`nextPageToken` substring in serialized output.
   - [x] **HTTP-to-exception mapping**: each `except` block in the 5 
RESTCatalog overrides carries an inline `# RESTCatalog.java:<line>` comment 
that points at the Java source it mirrors; reviewers can cross-check at a 
glance.
   - [x] **Method parameter naming**: existing 4 methods keep `branch_name` / 
`tag_name` (master compat); the new `rename_branch` uses Java-style 
`from_branch` / `to_branch` since it has no prior history.
   
   ## Generative AI disclosure
   
   Implementation, tests, and PR description were drafted with the assistance 
of Claude (Anthropic). Claude was supplied with the Java reference files 
(`Catalog.java`, `RESTCatalog.java`, `RESTApi.java`, 
`CreateBranchRequest.java`, `RenameBranchRequest.java`, 
`ForwardBranchRequest.java`, `ListBranchesResponse.java`) and the existing 
pypaimon patterns (`list_partitions_paged`, `create_function`, `RESTBaseTest`, 
the Tag CRUD PR #7746); the design plan and code were reviewed and integrated 
by the author.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to