-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Nessie: Support views for NessieCatalog #8909
Conversation
66ea0be
to
89b3a21
Compare
.isInstanceOf(NoSuchTableException.class) | ||
.hasMessageStartingWith("Table does not exist: ns.view"), | ||
throwable -> | ||
assertThat(throwable) |
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.
Nessie throws AlreadyExistsException
for a view in this case. Do we need to wrap it up with NoSuchTableException
for a table in this case to generalize like other catalogs?
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.
Even Hive view support has same problem
#8907
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.
Altering core test expectation on a PR that adds a specific view implementation does not look right to me.
If core test expectations are sub-optimal perhaps we can adjust them in a separate PR, then rebase the Nessie view PR.
That said, I think the exception thrown in this test case should be the same across all catalog implementations. WDYT?
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.
So far, REST and inmemory catalog follows one pattern (NoSuchTableException) and all other catalogs follows one pattern (AlreadyExistsException).
I tried making Nessie to follow as REST catalog, but it breaks other testcases. I will check more.
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.
replaceTableViaTransactionThatAlreadyExistsAsView
NessieTableOperations.doRefresh()
--> throws AlreadyExistsException
. But expecting NoSuchViewException
.
If I fix it, another test case (createOrReplaceTableViaTransactionThatAlreadyExistsAsView) fails.
Because from the same place doRefresh()
we are expecting two different kind of exceptions. I think test case need to be modified instead of unifying code.
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.
Can we follow the in-memory catalog pattern in Nessie?
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 actually think that the way Nessie currently handles this error case is correct by saying that a view with the same name already exists when you try to create a table. To achieve the same for REST is actually slightly more difficult. There's also a TODO in the test a few lines above where I wanted to improve the error reporting for these 2 particular cases that were adjusted in this test. That being said, I'm +1 on these 2 changes in the test
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 should be addressed by c63be65
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.
@nastra: Awesome. Thanks for fixing it for REST and in-memory catalog. That should help in having a unified behaviour.
// View loaded from catalog will have all the representation as it parses the view metadata | ||
// file. | ||
SQLViewRepresentation sqlViewRepresentation = | ||
(SQLViewRepresentation) metadata.currentVersion().representations().get(0); |
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.
Currently Nessie's IcebergView
model stores only one dialect and representation. I didn't change Nessie side to hold multiple representation because it was needed for global state. Now that global state is removed in Nessie, only view metadata location is enough. It will have current version id and all the representation for that version.
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.
it seems weird to only store one and not all of the representations
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.
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.
Should we even bother with storing representations in Nessie at this point? I'd say, until Nessie supports multiple representations, we can just keep metadata location and ignore all representations here. These fields are nullable in Nessie.
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.
True. I mentioned this above.
Either Nessie can store all the representations or None I guess
I think we don't need to store any representation if we don't need those for metadata in Nessie project. So, I am waiting for @snazy's reply.
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.
Agree.
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.
All metadata should really be taken directly from the view metadata - Nessie should really not store the dialect nor the SQL representation. I don't understand how this related to "global state" - those things are not related to each other at all.
Also the unconditional cast is error prone IMO - similar to assuming that there is only one representation - either of different kinds or multiple SQL representation.
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 understand how this related to "global state" - those things are not related to each other at all.
IcebergTable
model used to only store table metadata location. But then it started storing other info like schema id, snapshot id etc to support global state. The IcebergView
model developed was also based on the design of IcebergTable
(which was based on global state). Else just View metadata location was enough. Thats how I thought it is designed.
Nessie should really not store the dialect nor the SQL representation
Ok. I will update as per this.
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.
Aah, SqlText
is not nullable. So, I cannot construct without it. I will raise a PR at Nessie side to make it Nullable.
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.
added a dummy sqlText and dummy dialect as we have concluded that we don't have to modify at Nessie side.
import org.projectnessie.model.Branch; | ||
import org.projectnessie.model.Reference; | ||
|
||
public class TestBranchVisibilityForView extends BaseTestIceberg { |
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.
Similar to Table's TestBranchVisibility
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 test class duplicates the test cases - most are not specific to views.
It seems the view-specific stuff can be merged into TestBranchVisibility
.
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 test class duplicates the test cases - most are not specific to views.
I will remove TestBranchVisibilityForView
nessie/src/main/java/org/apache/iceberg/nessie/UpdateableReference.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieCatalog.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieCatalog.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieCatalog.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
maybeThrowSpecializedException((NessieReferenceConflictException) ex); | ||
} catch (NessieConflictException | NessieNotFoundException | HttpClientException ex) { | ||
NessieUtil.handleExceptionsForCommits(ex, client.refName(), failure); | ||
} catch (NessieBadRequestException ex) { |
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.
Here too, I think this catch block is a code smell, but this one is trickier to solve.
The issue is that in the test called createTableViaTransactionThatAlreadyExistsAsView
, we create a transaction based on current hash (let's call it c0), then we commit something outside the transaction (let's call it c1), then we attempt to commit the transaction.
As a result, the transaction/client is trying to commit using the expected hash of c1, but it should really use c0 as the expected commit hash.
There is a property to convey the commit ID: NESSIE_COMMIT_ID_PROPERTY
, but it doesn't work when creating things, only when updating.
I think we could solve the problem by storing the current expected hash in a field inside NessieTableOperations
, then passing that to the client:
public class NessieTableOperations extends BaseMetastoreTableOperations {
...
private Reference reference;
...
NessieTableOperations(...) {
...
reference = client.getRef().getReference();
}
...
protected void doRefresh() {
...
String metadataLocation = null;
this.reference = client.getRef().getReference();
...
}
...
protected void doCommit(TableMetadata base, TableMetadata metadata) {
...
client.commitTable(base, metadata, newMetadataLocation, contentId, key, reference);
...
}
}
I did a quick experiment with the above suggestion and the test threw NessieConflictException
as expected, instead of NessieBadRequestException
.
@dimas-b what would you suggest in this situation?
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.
In my understanding, commits will be retried on failure for NessieConflictException
and it will call doRefresh()
for retry which will again use the new reference?
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 think the proper way to fix it is to check if any different kind of content exist for the key while committing this key in doCommit()
of NessieTableOperation
and NessieViewOperation
. But that is an extra round trip with server and might degrade commit performance slightly?
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.
- Conflicts will not be retried for
NessieReferenceConflictException
since we throw specialized errors, see here:iceberg/nessie/src/main/java/org/apache/iceberg/nessie/NessieUtil.java
Lines 188 to 192 in 89b3a21
if (exception instanceof NessieReferenceConflictException) { // Throws a specialized exception, if possible NessieUtil.maybeThrowSpecializedException( (NessieReferenceConflictException) exception, false); } - My main point was: we should get rid of this
catch (NessieBadRequestException ex)
block as, in my opinion, it denotes a code smell.
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 think the proper way to fix it is to check if any different kind of content exist for the key while committing this key in doCommit() of NessieTableOperation and NessieViewOperation. But that is an extra round trip with server and might degrade commit performance slightly?
This solution is viable but would imho be less efficient since, as you mentioned, it involves an extra roundtrip.
I personally think that if NessieTableOperation
could "memorize" the commit hash of that last time it did a refresh, then reuse it to commit the table changes, that would solve the problem in a better way since it does not involve fetching contents.
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.
That particular testcase is tricky because createTransaction()
will call refresh()
which already has code to check if any other content exist with the same name. But during commitTransaction()
it will not call refresh()
so that code is never hit and we need to check again if any new content created with same key concurrently.
So, I have added that logic now instead of catching NessieBadRequestException
later on.
I am not sure about memorize
commit hash solution. Last time (some other PR) we concluded that we need to be as stateless as possible. Lets see what others think.
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 think it's a good idea to record the current commit hash for "new" table/view commits at the time NessieTableOperations
is created. At the same time, if the commit is an update, I think we should use the hash from the metadata (basically track it for views too).
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.
Re: NessieBadRequestException
, I agree that we should not try to "handle" it. Instead the catalog should be implemented such that NessieBadRequestException
does not happen.
nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java
Outdated
Show resolved
Hide resolved
Content content = null; | ||
try { | ||
content = | ||
client.getApi().getContent().key(key).reference(client.getReference()).get().get(key); |
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.
Checking for the content here imho defeats the purpose of calling doRefresh
only when necessary. I think I still prefer to store the hash of the last refresh, then use it for commit. @dimas-b wdyt?
nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
// Need a fix from Nessie (https://github.com/projectnessie/nessie/issues/7645) | ||
} | ||
|
||
// Overriding the below rename view testcases to exclude checking same view metadata after rename. |
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 seems problematic to me. It would be better to engage with core devs and check whether the metadata is allowed to have extra properties. @nastra wdyt?
At first glance, the assertion seems indeed a bit restrictive:
assertThat(((BaseView) renamed).operations().current())
.usingRecursiveComparison()
.ignoringFieldsOfTypes(Schema.class)
.isEqualTo(original);
Maybe change the semantics to "contains all the original fields but may also contain some extra ones?"
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 think that would be ok to change the semantics to contains all the original fields but may also contain some extra ones (in case a catalog impl decides to add new properties)
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.
Not just that. The original property might modified during rename for Nessie.
Like "nessie.commit.id" is different for original and renamed one.
Shall I ignore the properties aomparision as a whole?
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.
@ajantha-bhat can you please follow-up on this in a separate PR?
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/BaseTestIceberg.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/BaseTestIceberg.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestBranchVisibilityForView.java
Outdated
Show resolved
Hide resolved
nessie/src/test/java/org/apache/iceberg/nessie/TestNessieView.java
Outdated
Show resolved
Hide resolved
// Need a fix from Nessie (https://github.com/projectnessie/nessie/issues/7645) | ||
} | ||
|
||
// Overriding the below rename view testcases to exclude checking same view metadata after rename. |
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 think that would be ok to change the semantics to contains all the original fields but may also contain some extra ones (in case a catalog impl decides to add new properties)
217aee0
to
c727200
Compare
} | ||
|
||
/** Lists Iceberg table or view from the given namespace */ | ||
protected List<TableIdentifier> listContents(Namespace namespace, Content.Type type) { |
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.
is there any value in keeping this (and others) protected? I would have thought it should be ok to make this private, since all the other places would then use the table/view-specific methods
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.
In the NessieCatalog
itself I have some common code for content which calls these protected classes.
If I doesn't have common code in NessieCatalog
, it will be code duplication.
For example see, NessieCatalog.renameContent()
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.
NessieCatalog.table --> NessieCatalog.content --> NessieClient.content
this way it is less code duplication.
NessieCatalog.table --> NessieClient.table --> NessieClient.content
will cause duplicate lines of code in NessieCatalog
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.
why can't those places just call renameTable()
/ renameView()
directly?
c727200
to
d3381b4
Compare
@nastra: I have addressed the comments. Thanks for the review. |
02ce26a
to
386b2dc
Compare
386b2dc
to
3b44157
Compare
@@ -239,33 +240,24 @@ public boolean dropTable(TableIdentifier identifier, boolean purge) { | |||
TableReference tableReference = parseTableReference(identifier); | |||
return client | |||
.withReference(tableReference.getReference(), tableReference.getHash()) | |||
.dropTable(identifierWithoutTableReference(identifier, tableReference), purge); | |||
.dropTable(identifierWithoutTableReference(identifier, tableReference), false); |
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.
@ajantha-bhat shouldn't this keep the purge
flag?
fromReference.equalsIgnoreCase(toReference), | ||
"Cannot rename %s '%s' on reference '%s' to '%s' on reference '%s':" | ||
+ " source and target references must be the same.", | ||
NessieUtil.contentTypeString(type).toLowerCase(), |
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.
Since the expected text is in English we should use .toLowerCase(Locale.ENGLISH))
. Using the default locale can have surprising results.... may be not in this particular case, but we ought to ensure correctness in general, I think.
Try this: assertThat("VIEW".toLowerCase(new Locale("TR"))).isEqualTo("view");
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.
While adding it, I did check the Iceberg code.
.toLowerCase()
is used in other places also. So, I followed it.
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.
Fixed for new code added by this PR.
We can have GH issue for existing code to track it.
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 did a quick scan of the Iceberg codebase for this, and I do a few places where .toLowerCase()
may be a concern:
-
TableIdentifier.toLoweCase()
is used only inCachingCatalog
internally, which is probably ok, since the lower case strings are not exposed to the outside. -
VectorizedSupport seems like it may be a problem, but I do not really know whether the lower case data is exposed and how.
-
IcebergRecordObjectInspector converts field names to lower case, and that seems to be affected by the locale problem as various case names are accepted as input parameters to its methods.
-
jQuery
code uses a lot oftoLowerCase()
, but I do not really know how it is supposed to be used.
@nastra : Do you think this is worth opening an issue? To the best of my knowledge this kind of case conversion can be problematic only in German and Turkish locales. The German locale affects only proper German language words (so it is less of a problem), but the Turkish locale can cause English words to be converted in unexpected ways. Does Iceberg support using its libraries in user-defined locales?
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.
it's probably a good idea to open an issue and raise awareness about this
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.
1ab630f
to
589e428
Compare
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.
LGTM overall. Sorry for a few late comments.
} | ||
|
||
// We try to drop the table. Simple retry after ref update. | ||
// We try to drop the content. Simple retry after ref update. | ||
try { | ||
commitRetry( | ||
String.format("Iceberg delete table %s", identifier), |
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 may be a view now, not just "table" (cf. line 554).
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.
good catch. Induced during rebase.
maybeThrowSpecializedException((NessieReferenceConflictException) ex); | ||
} catch (NessieConflictException | NessieNotFoundException | HttpClientException ex) { | ||
if (ex instanceof NessieConflictException || ex instanceof NessieNotFoundException) { | ||
failure = true; |
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 think it might be preferable to delegate determining the failure
flag to NessieUtil.handleExceptionsForCommits
. This logic should be the same between tables and views.
Perhaps handleExceptionsForCommits
could return an object with both the flag and the exception to be re-thrown. WDYT?
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.
That will be more complicated I guess.
I have simplified a bit now. Please take a look
NessieUtil.handleExceptionsForCommits(ex, client.refName(), Content.Type.ICEBERG_TABLE) | ||
.ifPresent( | ||
exception -> { | ||
throw exception; |
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 I follow the logic correctly, handleExceptionsForCommits
will always return something for the exception types caught in this case, so ifPresent()
is really confusing. Could the code be refactored to avoid unnecessary conditional execution?
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.
+1 on improving exception handling in the nessie code as I've raised this already before, because it's difficult to read & understand when certain things are thrown.
However, I would suggest to do this as an immediate follow-up after this PR is merged, as otherwise this makes it more difficult to review the changes being introduced for Views
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 fine with a follow-up.
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.
Slightly improved now ;)
throw NessieUtil.handleBadRequestForCommit(client, key, Content.Type.ICEBERG_VIEW).orElse(ex); | ||
} finally { | ||
if (failure) { | ||
io().deleteFile(newMetadataLocation); |
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 code appears to be shared with NessieTableOperations
. Could we refactor it to have the exception/failure/cleanup logic in one place?
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 tried before.
But one works on client.commitView
and one is client.commitTable
. So, it cannot be extracted to common code.
I did also try accepting a generic Runnable to execute. But it cannot throw the required exception. Hence, it has to be duplicated.
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.
We could define our own functional interface
with declared exceptions.
|
||
private void resetData() throws NessieConflictException, NessieNotFoundException { | ||
Branch defaultBranch = api.getDefaultBranch(); | ||
for (Reference r : api.getAllReferences().get().getReferences()) { |
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.
tangential: This code is repeated in many downstream tests... Perhaps we could make a helper utility in Nessie OSS 🤔
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 see the advantage of adding at Nessie side. But it can be added as Util for the test classes. But maybe as a follow up PR.
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.
fair enough.
NessieUtil.handleExceptionsForCommits(ex, client.refName(), Content.Type.ICEBERG_TABLE) | ||
.ifPresent( | ||
exception -> { | ||
throw exception; |
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 fine with a follow-up.
49f0f96
to
5981bad
Compare
NessieCatalog
withBaseMetastoreViewCatalog
.NessieUtil
for reusing between tables and views.ViewCatalogTests
to reuse for Nessie catalog.Fixes: #8696