Skip to content

wrong-results: CIDR term query on an ip field matches in the memtable but returns 0 after flush (segment path lacks the CIDR fallback) #782

Description

@xerj-org

A term query with CIDR notation on an ip field matches docs in the memtable but returns zero after they flush to a segment — a silent flush-divergence (same query, different results before/after flush), the #413/#423 pattern. range on the CIDR bounds works on both paths, so the data is fine; only the CIDR term breaks on the segment.

Reproduced (current main / rc.70, own node, non-9200)

Index ip-mapped addr with 192.168.1.5, .200, .0, .255, 10.0.0.1, 192.168.2.5, then a fresh 192.168.1.77.

# memtable (fresh doc, not force-merged):
term addr=192.168.1.0/24   -> matches 192.168.1.77   ✅
# after _flush + _forcemerge:
term addr=192.168.1.0/24   -> []   ❌  (should be all 192.168.1.x)
# range still works on both:
range addr gte 192.168.1.0 lte 192.168.1.255 -> all 192.168.1.x   ✅

Also 0 after flush for /16, /25, /32. Exact term addr=192.168.1.5 works (in dict).

Cause

The memtable fast path try_doc_values_query (index.rs:35183) and the mem-bool path (35116) explicitly BAIL on a /-containing value (return None) → fall back to the source-scan matcher doc_matches_query, whose Term arm handles CIDR via ip_matches_cidr (index.rs:36041/40495). The segment term path does an exact term-dictionary lookup for the literal "192.168.1.0/24", finds nothing (the dict holds exact IPs), and returns 0 without the same CIDR fallback. ES answers CIDR term on an ip field as the subnet range.

Fix direction (two options, both decision-free)

  1. Rewrite a Term{ip_field, "a.b.c.d/n"} into Range{gte: network, lte: broadcast} at query build/normalization where the schema is available — range already works on both memtable and segment, so this fixes it uniformly.
  2. Make the segment term path route a CIDR value on an ip field to the source-scan doc_matches_query/ip_matches_cidr fallback, mirroring what the memtable fast paths already do by bailing.

Found via a proactive probe. Will take (1) or (2) with a fail-before segment test (memtable matches, segment 0) once the exact segment term-resolution site is pinned.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions