Fix timeseries $geoWithin skipping buckets when control points share a latitude

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.0.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Integration
    • Fully Compatible
    • ALL
    • 200
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      InternalBucketGeoWithinMatchExpression constructs an S2LatLngRect from a timeseries bucket’s control.min and control.max geo fields to determine whether the bucket bounding box intersects the query region.

      The issue is that S2LatLngRect(lo, hi) requires lo.lat() <= hi.lat(), but this invariant can be violated because of floating-point precision loss in the GeoJSON → S2Point → S2LatLng round-trip. Latitude R1Interval becomes empty while the longitude S1Interval remains non-empty, causing the resulting S2LatLngRect to fail the is_valid() invariant.

      [j3] {"t":{"$date":"2026-05-19T01:35:15.572+00:00"},"s":"I",  "c":"INDEX",    "id":20440,   "ctx":"conn7","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"9494853c-4ad5-4ca3-8255-6ef5a30b615a"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
      [j3] {"t":{"$date":"2026-05-19T01:35:15.572+00:00"},"s":"I",  "c":"INDEX",    "id":20447,   "ctx":"conn7","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"9494853c-4ad5-4ca3-8255-6ef5a30b615a"}}}}
      [j3] {"t":{"$date":"2026-05-19T01:35:16.409+00:00"},"s":"F",  "c":"GEO",      "id":25001,   "ctx":"conn7","msg":"{message}","attr":{"message":"src/third_party/s2/s2latlngrect.h:270: Check failed: is_valid()[2.7630000, -2.5990000], [2.7630000, 2.5000000]"}}
      [j3] {"t":{"$date":"2026-05-19T01:35:16.409+00:00"},"s":"F",  "c":"ASSERT",   "id":23089,   "ctx":"conn7","msg":"Fatal assertion","attr":{"msgid":40048,"location":"src/third_party/s2/base/logging_mongo.cc:91:26:virtual s2_mongo::SeverityLogSink::~SeverityLogSink()"}}
      [j3] {"t":{"$date":"2026-05-19T01:35:16.410+00:00"},"s":"F",  "c":"ASSERT",   "id":23090,   "ctx":"conn7","msg":"\n\n***aborting after fassert() failure\n\n"}
      [j3] {"t":{"$date":"2026-05-19T01:35:16.410+00:00"},"s":"F",  "c":"CONTROL",  "id":6384300, "ctx":"conn7","msg":"Writing fatal message","attr":{"message":"Got signal: 6 (Aborted).\n"}}
      [j3] {"t":{"$date":"2026-05-19T01:35:16.992+00:00"},"s":"I",  "c":"CONTROL",  "id":31380,   "ctx":"conn7","msg":"BACKTRACE","attr":{"bt":{"backtrace":[{"a":"7F93B92740FA","b":"7F93B889C000","o":"9D80FA","s":"_ZN5mongo25printStructuredStackTraceEv","C":"mongo::printStructuredStackTrace()","s+":"D2"},{"a":"7F93B92232C0","b":"7F93B889C000","o":"9872C0","s":"_ZN5mongo12_GLOBAL__N_115printErrorBlockEv","C":"mongo::(anonymous namespace)::printErrorBlock()","s+":"C8"},{"a":"7F93B9222CD6","b":"7F93B889C000","o":"986CD6","s":"abruptQuit","s+":"CE"},{"a":"7F93B51C6CF0","b":"7F93B51B4000","o":"12CF0"},{"a":"7F93B3FD3ACF","b":"7F93B3F85000","o":"4EACF","s":"__GI_raise","s+":"10F"},{"a":"7F93B3FA6EA5","b":"7F93B3F85000","o":"21EA5","s":"__GI_abort","s+":"127"},{"a":"7F93B91D643A","b":"7F93B889C000","o":"93A43A","s":"_ZN5mongo12_GLOBAL__N_19callAbortEv","C":"mongo::(anonymous namespace)::callAbort()","s+":"AE"},{"a":"7F93B91D750C","b":"7F93B889C000","o":"93B50C","s":"_ZN5mongo14fassert_detail6failedENS0_5MsgIdENS_24WrappedStdSourceLocationE","C":"mongo::fassert_detail::failed(mongo::fassert_detail::MsgId, mongo::WrappedStdSourceLocation)","s+":"39C"},{"a":"7F9400EB0757","b":"7F9400D6A000","o":"146757","s":"_ZN8s2_mongo15SeverityLogSinkD2Ev","C":"s2_mongo::SeverityLogSink::~SeverityLogSink()","s+":"607"},{"a":"7F9400EB082E","b":"7F9400D6A000","o":"14682E","s":"_ZN8s2_mongo15SeverityLogSinkD0Ev","C":"s2_mongo::SeverityLogSink::~SeverityLogSink()","s+":"E"},{"a":"7F9400EAD0C7","b":"7F9400D6A000","o":"1430C7","s":"_ZN6s2_env10LogMessageD2Ev","C":"s2_env::LogMessage::~LogMessage()","s+":"77"},
      

      This was found by the timeseries_geodata_geonear_pbt property-based test. A reproducible case is a $geoNear aggregation on a timeseries collection where a bucket contains points with coordinates [-2.599, 2.763] and [2.500, 2.763].

      The fix is to update src/mongo/db/exec/matcher/matcher_geo.cpp so that latitude interval construction uses R1Interval::FromPointPair, which swaps endpoints if needed, while continuing to use the directed S1Interval constructor for longitude to preserve antimeridian-crossing semantics.

            Assignee:
            Aditya Deshpande
            Reporter:
            Aditya Deshpande
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: