Skip to content

Fix equality for GEO responses without coordinates - #4742

Merged
ggivo merged 4 commits into
redis:masterfrom
jakezwang:fix/geo-response-null-coordinate
Sep 25, 2026
Merged

ggivo merged 4 commits into
redis:masterfrom
jakezwang:fix/geo-response-null-coordinate

Conversation

@jakezwang

@jakezwang jakezwang commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Comparing separate GeoRadiusResponse instances throws NullPointerException when WITHCOORD was omitted. Use Objects.equals for the optional coordinate, preserving equality and hash-code behavior when coordinates are present.

Unit tests cover equality, unequal members, mixed coordinate presence, hash-based lookup, and responses built with WITHDIST/WITHHASH.

Discovery and reproduction

This edge case was explored outside a production application. A reproducer against an actual Redis server is documented in #4746.

The integration regression now lives in GeoCommandsTestBase, as requested, so it runs through both RedisClientGeoCommandsTest and ClusterGeoCommandsTest, using their existing protocol parameterization. It issues repeated GEOSEARCH commands with WITHDIST and WITHHASH but without WITHCOORD, and checks list equality and HashSet membership. The test uses the shared unique-key registry for cleanup. The release-note entry has been removed as requested.

Testing

After merging current master, JDK 8 + Redis 8.10.2: 86 tests passed, zero failures and zero skips across GeoRadiusResponseTest, RedisClientGeoCommandsTest, and ClusterGeoCommandsTest, using an isolated standalone server and a real three-node cluster. The original server-backed reproducer failed with NullPointerException on the unpatched implementation.

Closes #4746


Note

Low Risk
Small contract fix in a response DTO’s equals implementation, with focused unit and integration tests; no auth, persistence, or API surface changes.

Overview
Fixes GeoRadiusResponse.equals so comparing two responses no longer throws when WITHCOORD was not requested. The optional coordinate field is compared with Objects.equals instead of calling equals on a possibly null reference; behavior when coordinates are present is unchanged and hashCode already used Objects.hashCode.

Adds GeoRadiusResponseTest for null-coordinate equality, differing members, mixed coordinate presence, and builder-produced WITHDIST/WITHHASH replies. Adds an integration case on GeoCommandsTestBase that runs repeated GEOSEARCH with distance and hash but without coordinates and asserts list equality, matching hash codes, and HashSet membership (covers client and cluster geo test subclasses).

Reviewed by Cursor Bugbot for commit e0be1ce. Bugbot is set up for automated code reviews on this repo. Configure here.

@ggivo

ggivo commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

@jakezwang
Before we review the fix, please open an issue describing the problem from the user's perspective. Include:

  • The concrete scenario: what are you trying to do and what goes wrong
  • A minimal reproducer — code or commands that trigger the issue against an actual Redis server
  • Expected vs actual output

Without a reproducer, we cannot verify the fix end-to-end or confirm the scenario is actually resolved.

@ggivo ggivo added the waiting-for-feedback We need additional information before we can continue label Sep 23, 2026
Signed-off-by: Jake Wang <jake.wang@argonlabs.tech>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 64573d2. Configure here.

@ParameterizedTest
@EnumSource(RedisProtocol.class)
public void compareRepeatedSearchesWithoutCoordinates(RedisProtocol protocol) {
EndpointConfig endpoint = Endpoints.getRedisEndpoint("redis2");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IT uses unknown Redis endpoint

Medium Severity

The new GeoRadiusResponseIT looks up endpoint redis2, which is not defined in endpoints.json. Endpoints.getRedisEndpoint then throws TestAbortedException, so the parameterized cases abort instead of exercising geosearch without WITHCOORD. The Redis round-trip coverage described in the PR never runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 64573d2. Configure here.

@jakezwang

Copy link
Copy Markdown
Contributor Author

This was independently discovered, not a production incident. I have now reproduced it against a real Redis 8.10.2 server with JDK 8 using GEOSEARCH WITHDIST WITHHASH without WITHCOORD. Two identical queries return responses with null coordinates; comparing their lists or doing a HashSet lookup throws NullPointerException on unpatched master. The new GeoRadiusResponseIT covers RESP2 and RESP3 and passes with the fix; the four unit tests also pass. The branch is updated to current master. Reproducer issue: #4746

@ggivo ggivo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
Two minor notes before merging: drop the release notes entry (NPE fix, no user action needed), and move the integration test into GeoCommandsTestBase alongside the other geo tests.

Comment thread docs/release-notes/8.1.0.md Outdated
Comment thread src/test/java/redis/clients/jedis/misc/GeoRadiusResponseIT.java Outdated
@ggivo ggivo removed the waiting-for-feedback We need additional information before we can continue label Sep 24, 2026
Signed-off-by: Jake Wang <jake.wang@argonlabs.tech>
@ggivo
ggivo merged commit b75c784 into redis:master Sep 25, 2026
19 of 21 checks passed
@ggivo ggivo added the bug label Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GeoRadiusResponse.equals throws for repeated GEOSEARCH results without WITHCOORD

2 participants