-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Implement equals/hashcode for named DocValueFormat inner classes #6357
Implement equals/hashcode for named DocValueFormat inner classes #6357
Conversation
ac2a020
to
fe01144
Compare
Gradle Check (Jenkins) Run Completed with:
|
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj.getClass().equals(this.getClass()) == 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.
Could you please point out where the parser participates in equals
/ hashCode
path? We are talking about DateTime
that implements DocValueFormat
, rigth?
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 ran across this when attempting to compare the equivalence of an InternalDateHistogram
instance that had been serialized and deserialized.
The equals
method of the InternalDateHistogram
fails on the format
field (DocValueFormat$DateTime
), which contains a JavaDateMathParser
instance in the parser
field. The other fields on the DateTime
class (formatter
, timezone
, resolution
) do successfully equate, due to both JavaDateFormatter
and ZoneOffset
implementing equals
, and DateFieldMapper.Resolution
being an enum.
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 ran across this when attempting to compare the equivalence of an InternalDateHistogram instance that had been serialized and deserialized.
This is not in scope of the OpenSearch, right? The parser class is just an utility class and is not supposed to be used for equivalence or anything like that.
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.
Today you cannot serialize an InternalDateHistogram
using the provided writeTo
method, and re-hydrate that back into an InternalDateHistogram
using the InternalAggregations.readFrom
and pass equivalence due to this object reference. I would expect an item that had been serialize/deserialized to maintain equivalence, unless this is not something that is intended to be supported?
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 parser is synthesized from formatter: it is not serialized and consequently, not deserialized (there are no reasons to do that, parser is a typical transient property).
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, this is the issue I'm running into. Because it's not serialized and instead is derived from the formatter
it breaks the ability to compare instances of any InternalAggregation
that has a DateTime
.
Perhaps a better approach on this would be to override the equals()
/hashcode
of DateTime
and exclude the parser
field, since it is directly derived from the formatter
. Since DateTime
implements a Writeable
it would make more sense that this should be able to maintain equivalence across serialization.
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.
AFAIU the comparison logic you are using seems to be relying on per-field comparison and not the equals
(since it would have failed even before this point). In this case, the parser
should be excluded or, alternatively, you could rely on toString()
comparison. I don't think this is an issue in OpenSearch, there are no requirements / promises / use cases to have such strict equivalence guarantees, especially for utility classes like parsers.
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.
Perhaps a higher-level example would better illustrate the issue:
public void testEquivalence() {
DateFormatter formatter = DateFormatter.forPattern("epoch_second");
ZoneOffset zoneOffset = ZoneOffset.ofHours(1);
Resolution resolution = Resolution.MILLISECONDS;
DocValueFormat.DateTime dateFormat1 = new DocValueFormat.DateTime(formatter, zoneOffset, resolution);
DocValueFormat.DateTime dateFormat2 = new DocValueFormat.DateTime(formatter, zoneOffset, resolution);
assertEquals(dateFormat1, dateFormat2);
}
java.lang.AssertionError: expected: org.opensearch.search.DocValueFormat$DateTime<DocValueFormat.DateTime(format[epoch_second] locale[], +01:00, MILLISECONDS)> but was: org.opensearch.search.DocValueFormat$DateTime<DocValueFormat.DateTime(format[epoch_second] locale[], +01:00, MILLISECONDS)>
Expected :org.opensearch.search.DocValueFormat$DateTime<DocValueFormat.DateTime(format[epoch_second] locale[], +01:00, MILLISECONDS)>
Actual :org.opensearch.search.DocValueFormat$DateTime<DocValueFormat.DateTime(format[epoch_second] locale[], +01:00, MILLISECONDS)>
I do think after this conversation though, that this is probably better resolved in the DocValueFormat.DateTime
class instead of the JavaDateMathParser
, otherwise this above example would still fail due to the fact it uses a RoundupParser
.
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 only DocValueFormat.DateTime
but DocValueFormat
in general
Gradle Check (Jenkins) Run Completed with:
|
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more @@ Coverage Diff @@
## main #6357 +/- ##
============================================
+ Coverage 70.58% 70.71% +0.12%
- Complexity 58841 59041 +200
============================================
Files 4799 4799
Lines 282421 282428 +7
Branches 40717 40720 +3
============================================
+ Hits 199341 199711 +370
+ Misses 66584 66315 -269
+ Partials 16496 16402 -94
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
@bryanlb What would you like to do with this? |
@bryanlb Can you share more details about what you're trying to do at a higher level that led you to need to do this? |
@andrross sure! I have a slightly unique case where I'm importing the server package as a dependency, and then using the I only ran into this issue when attempting to verify that serializing an |
@bryanlb So are you using the OpenSearch server as a library in a separate (non-OpenSearch) application? It's always interesting to hear unique use cases :) I will caution that there are no stability guarantees with these internal classes so you may frequently encounter breaking changes. That's a fair point about not correctly implementing the contract defined by the |
@andrross Just to give some context on the issue at large, the
It think this is indeed a problem (may be uncovered in unusual way by @bryanlb) but we need to fix. |
@bryanlb Either way is fine. Just make sure you update the title and commit message if you continue to use this PR. |
fe01144
to
988ba10
Compare
Gradle Check (Jenkins) Run Completed with:
|
@bryanlb LGTM, could you please add the entry to CHANGELOG? thank you |
Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com>
988ba10
to
818f1a7
Compare
Gradle Check (Jenkins) Run Completed with:
|
The backport to
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add ../.worktrees/backport-2.x 2.x
# Navigate to the new working tree
pushd ../.worktrees/backport-2.x
# Create a new branch
git switch --create backport/backport-6357-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 5a7fd4f4c0efc1f300b05a250f484517426fb2e4
# Push it to GitHub
git push --set-upstream origin backport/backport-6357-to-2.x
# Go back to the original working tree
popd
# Delete the working tree
git worktree remove ../.worktrees/backport-2.x Then, create a pull request where the |
The backport to
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add ../.worktrees/backport-2.x 2.x
# Navigate to the new working tree
pushd ../.worktrees/backport-2.x
# Create a new branch
git switch --create backport/backport-6357-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 5a7fd4f4c0efc1f300b05a250f484517426fb2e4
# Push it to GitHub
git push --set-upstream origin backport/backport-6357-to-2.x
# Go back to the original working tree
popd
# Delete the working tree
git worktree remove ../.worktrees/backport-2.x Then, create a pull request where the |
…nsearch-project#6357) Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com> (cherry picked from commit 5a7fd4f)
Backport: #6584 |
…nsearch-project#6357) Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com> (cherry picked from commit 5a7fd4f) Signed-off-by: Kunal Kotwani <kkotwani@amazon.com>
* Implement equals/hashcode for named DocValueFormat inner classes (#6357) Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com> (cherry picked from commit 5a7fd4f) Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> * Fix compiler warning and base blob path case (#6558) Signed-off-by: Samuel Herman <sherman8915@gmail.com> Co-authored-by: Samuel Herman <samuelherman@Samuels-MBP.MG8702> (cherry picked from commit 8c0e5d0) Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> --------- Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com> Signed-off-by: Kunal Kotwani <kkotwani@amazon.com> Signed-off-by: Samuel Herman <sherman8915@gmail.com> Co-authored-by: Bryan Burkholder <771133+bryanlb@users.noreply.github.com> Co-authored-by: samuel-oci <97131656+samuel-oci@users.noreply.github.com> Co-authored-by: Samuel Herman <samuelherman@Samuels-MBP.MG8702>
…nsearch-project#6357) Signed-off-by: Bryan Burkholder <bburkholder@slack-corp.com> Signed-off-by: Mingshi Liu <mingshl@amazon.com>
Description
Implements
equals
andhashCode
methods for the named inner classDocValueFormat.DateTime
.Per the contract as described in the
Writeable
interface, any class implementingequals
/hashcode
must ensure that a copy made be serializing and deserializing must be equal. AsInternalDateHistogram
/InternalHistogram
implementequals
/hashcode
and areWritable
classes, this requires thatDateTime
also implementequals
andhashcode
, as theDateMathParser
will otherwise cause it to fail equivalence.Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.