-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core: Move UpdateRequirement out of rest package #7750
Conversation
dd0b516
to
4bcc34a
Compare
} | ||
} | ||
|
||
public List<UpdateRequirement> build() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the builder makes much sense when these classes are public. The builder was originally creating the UpdateTableRequest
, which needed a list of both changes and requirements. Now, this is only producing a list of requirements from a list of changes so the builder pattern is unnecessary.
I think the cleanest path forward is to try to match the MetadataUpdate
API here. Let's keep the constructors for these classes public like MetadataUpdate
classes and add logic for converting a collection of updates into a collection of requirements elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made all the constructors public in UpdateRequirement
and added UpdateRequirements
with static methods that would then produce a List<UpdateRequirement
from a List<MetadataUpdate>
.
We don't expose a builder anymore in the API, but UpdateRequirements
still uses one internally, since it needs to maintain some state when producing requirements from a given list of updates.
core/src/main/java/org/apache/iceberg/rest/requests/UpdateTableRequest.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/iceberg/rest/requests/UpdateTableRequest.java
Show resolved
Hide resolved
core/src/main/java/org/apache/iceberg/rest/requests/UpdateTableRequest.java
Outdated
Show resolved
Hide resolved
import org.immutables.value.Value; | ||
|
||
@Value.Immutable | ||
public interface CommitTableRequest extends RESTRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we need a new CommitTableRequest
or if it would be fine to continue using UpdateTableRequest
. The breaking change is going to be removing the List<UpdateTableRequest.UpdateRequirement> requirements()
method, but the UpdateRequirement
interface is also deprecated and will be removed.
Since source compatibility is already going to break, I don't see a problem with moving directly from List<UpdateTableRequest.UpdateRequirement> requirements()
to List<UpdateRequirement> requirements()
. The requirements that are returned will implement both interfaces until the older UpdateTableRequest.UpdateRequirement
is removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we 're ok breaking source compability, then we can update UpdateTableRequest
directly and don't need CommitTableRequest
4bcc34a
to
f6550c8
Compare
f6550c8
to
7fecb46
Compare
7fecb46
to
cb859f6
Compare
.palantir/revapi.yml
Outdated
old: "method java.util.List<org.apache.iceberg.rest.requests.UpdateTableRequest.UpdateRequirement>\ | ||
\ org.apache.iceberg.rest.requests.UpdateTableRequest::requirements()" | ||
new: "method java.util.List<org.apache.iceberg.UpdateRequirement> org.apache.iceberg.rest.requests.UpdateTableRequest::requirements()" | ||
justification: "Accepted src API break by moving UpdateTableRequest out of REST" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only an API breaking change if we return a different implementation. Since we are still returning UpdateTableRequest.UpdateRequirement
, I think it is not going to be a binary-breaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct, this is not binary-breaking: SOURCE: BREAKING, BINARY: NON_BREAKING
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I think it would just be better if the justification were a little more clear that we don't expect it to break anything.
core/src/main/java/org/apache/iceberg/rest/CatalogHandlers.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/apache/iceberg/rest/RESTSerializers.java
Outdated
Show resolved
Hide resolved
.addAll(createChanges) | ||
.addAll(metadata.changes()) | ||
.build(); | ||
requirements = UpdateRequirements.forCreateTable(updates); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
baseChanges.forEach(requestBuilder::update); | ||
metadata.changes().forEach(requestBuilder::update); | ||
UpdateTableRequest request = requestBuilder.build(); | ||
UpdateTableRequest request = new UpdateTableRequest(requirements, updates); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other request classes use a builder. I think that the intent here is to use the public constructor because the builder changed substantially and can't be updated to work for both. It would be nice to use a builder later, but I can see why this needs to be public and used at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes exactly, the builder changed substantially. In the long run I think we can add a builder again
.hasSize(2) | ||
.hasOnlyElementsOfTypes( | ||
UpdateRequirement.AssertTableUUID.class, | ||
UpdateRequirement.AssertLastAssignedFieldId.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that these tests are sufficient. The assertions must be based on the base metadata's state. So the AssertTableUUID must contain the base metadata's UUID. And the last assigned field ID assertion should contain the base metadata's last column ID. I think the implementation is correct, but this would not catch some bugs introduced by updating the implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense and I've updated all tests to check values. I've also added more tests that check the failure conditions. Now we have full test coverage of all code branches in UpdateRequirement
via TestUpdateRequirements
@nastra, this is looking really close. I think the only issue is validating that the assertions are created correctly from the base table state, not just that the correct type of requirements are created. I guess this was being tested before by the REST catalog tests since these were embedded, but now that this is stand-alone logic I'd prefer to finish the tests. Also, we should make sure that there are tests for all of the paths in |
cb859f6
to
b617f0c
Compare
b617f0c
to
7482842
Compare
7482842
to
7822a1f
Compare
Thanks, @nastra! |
This currently depends on #7741.
The goal of this PR is to make
UpdateRequirement
available outside of therest
package layer, so that we can use it for #7569.The following things have been done in this PR:
org.apache.iceberg.UpdateRequirement
(copy oforg.apache.iceberg.rest.requests.UpdateTableRequest.UpdateRequirement
) andorg.apache.iceberg.UpdateRequirementParser
(copy oforg.apache.iceberg.rest.requests.UpdateRequirementParser
)org.apache.iceberg.rest.requests.UpdateTableRequest.UpdateRequirement
andorg.apache.iceberg.rest.requests.UpdateTableRequest
org.apache.iceberg.rest.requests.UpdateTableRequest
withorg.apache.iceberg.rest.requests.CommitTableRequest
which has the exact same structure, but takesorg.apache.iceberg.UpdateRequirement
org.apache.iceberg.rest.requests.UpdateTableRequest.UpdateRequirement
toorg.apache.iceberg.UpdateRequirement
org.apache.iceberg.rest.requests.UpdateTableRequest
toorg.apache.iceberg.CommitTableRequest