-
Notifications
You must be signed in to change notification settings - Fork 338
[Core, Bug] CreateEntitiesIfNotExist/CreatePrincipal not return the same entity persisted. #3219
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
Conversation
CHANGELOG.md
Outdated
| - Added checksum to helm deployment so that it will restart when the configmap has changed. | ||
| - Generic Table is no longer in beta and is generally-available. | ||
| - Added Windows support for Python client | ||
| - Ensure createEntitiesIfNotExist and createPrincipal return the entity actually persisted. |
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 the fix is specific to TransactionalMetaStoreManagerImpl or applies to all implementations? (my impression is the former, but this message is generic) 🤔
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.
IMHO, this fix does not affect Polaris end users, so it does not have to be mentioned in CHANGELOG (but it's ok to mention).
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 the effects of this fix are visible in REST APIs, I'd propose to reformulate the change log entry in terms of REST API.
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 affects CreateEntitiesIfNotExist in TransactionalMetaStoreManagerImpl and createPrincipal in all implementations. But yeah, this should not affect any user-facing feature/experience now. Removed the CHANGELOG line
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.
Thx, @HonahX !
As for TransactionalMetaStoreManagerImpl, I believe it is not in the JDBC persistence call paths, so I'll defer to @dennishuo for actual code review 🙂
singhpk234
left a comment
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 too, thanks @HonahX for the fix !
adnanhemani
left a comment
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.
Changes in AtomicOperationMetaStoreManager and tests LGTM 👍
I'll defer to @dennishuo for TransactionalMetaStoreManagerImpl review.
dennishuo
left a comment
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, good find! Looks like this was perhaps a regression actually inadvertently introduced in 9ff2ca1#diff-4518e9ca1448a8d56b5ddf35523289a6f70a9d2c1bfb91c62105b6199bcb8788 where prepareToPersistNewEntity in BasePolarisMetaStoreManager was changed from
// this is the first change
// TODO: Make immutable; make sure no caller depends on the input entity actually
// being changed.
entity.setLastUpdateTimestamp(entity.getCreateTimestamp());
// set all other timestamps to 0
entity.setDropTimestamp(0);
entity.setPurgeTimestamp(0);
entity.setToPurgeTimestamp(0);
return entity;
to
PolarisBaseEntity.Builder entityBuilder = new PolarisBaseEntity.Builder(entity);
entityBuilder.lastUpdateTimestamp(entity.getCreateTimestamp());
entityBuilder.dropTimestamp(0);
entityBuilder.purgeTimestamp(0);
entityBuilder.toPurgeTimestamp(0);
return entityBuilder.build();
I think the TODO was trying to warn against exactly this situation, but it can sometimes be hard to tell when an accidental dependency on the entity being changed sneaks in somewhere. We might want to do another check based on all the warning-TODOs removed there to make sure nothing else is subtly broken (I guess the main manifestation would just be that response payloads may be missing some fields that callers might not have been using if they haven't complained).
|
Thanks @dimas-b @singhpk234 @adnanhemani @dennishuo for reviewing! Merging |
In TransactionalMetaStoreManagerImpl.createEntitiesIfNotExist, we currently directly return the entity received in the arg if the entity does not exist:
polaris/polaris-core/src/main/java/org/apache/polaris/core/persistence/transactional/TransactionalMetaStoreManagerImpl.java
Lines 1087 to 1091 in be3c88b
However, the
persistNewEntityabove will update some field includinglastUpdatedTimestampbefore writing the entitypolaris/polaris-core/src/main/java/org/apache/polaris/core/persistence/BaseMetaStoreManager.java
Lines 108 to 111 in be3c88b
As a result, the entity included in the
EntityResultis not the same as the actual entity persisted.The similar issue also happened in
CreatePrincipalfor both atomic and transactional metastore manager.How to reproduce
The
principalEntityreturned fromcreatePrincipalwill havelastUpdatedTimestampequals0but thefetchedEntitywill have that equals100. (the actual version persisted)Fix
The PR fixes the issue by letting
persistEntityreturn the entity persisted and include that in the EntityResult. The PR also include new unit tests to verify the behaviorChecklist
CHANGELOG.md(if needed)site/content/in-dev/unreleased(if needed)