fix(api): treat OpenSearch's flat_object as an alias for flattened - #86
Conversation
OpenSearch's flat_object field type indexes without expanding sub-fields, the same semantics as flattened, but under a different type name. xerj only recognized flattened, so any mapping using flat_object (as OpenSearch's own sample dashboards/UBI data do) was rejected as an unsupported field type and lost the flattened reconstruction/highlighting/ignore_above handling that comes with it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014PRCbyt7Y2HDyhG1tbQTeL
|
Reviewed for v1.0.0-rc.9. This is the only one of #86–#89 with no blocker — the alias is faithful to It only half-fixes the case it exists forThe commit names OpenSearch's sample dashboards/UBI data as the motivation. OpenSearch Dashboards discovers index-pattern fields through Only
Net effect: index creation now succeeds where it previously 400'd — a real improvement — but the field surfaces to the dashboard as To be fair: this is identical pre-existing behaviour for ES No test exercises any of the new armsThe diff is 17 insertions in one file and zero test changes; Cloning two of those fixtures with Smaller things
SuggestionAdd a Holding it out of rc.9 only because that release is already merged, tagged-pending and fully verified, and adding an untested change at the end for a partial fix means re-running the whole gate without gaining the thing the PR is for. |
…ject
Addresses maintainer review findings on the flat_object alias PR:
- The main gap: OpenSearch Dashboards discovers index-pattern fields
via `_field_caps`, not `GET _mapping` — and the alias never reached
it. `flattened`/`flat_object` both collapse to the generic native
`FieldType::Object` (xerj has no dedicated native variant for
either), and `_field_caps`/`global_field_caps`/`GET
/{index}/_mapping/field/{field}` all derived their reported type
purely from that native type, so index creation succeeded but the
field surfaced to any client as a plain `object` — `GET _mapping`
alone round-tripped the real declared type, since it returns the
stored mapping JSON verbatim. Fixed with `declared_flattened_type`,
which looks up a field's real declared type in the stored mapping
and overrides the generic `object` string only when it's actually
`flattened`/`flat_object` — every other field keeps deriving from
the native schema exactly as before, so a dynamically-inferred field
with no stored-mapping entry is unaffected.
- `is_supported_field_type` is shared between the mapping-properties
validation path and the runtime-fields validation path; widening it
to accept `flat_object` leaked into the runtime-fields path too,
where real ES doesn't allow `flattened`/`flat_object` at all (runtime
fields are restricted to a small scalar/composite set). Added an
explicit exclusion in `validate_runtime_fields` for both names.
- Added a YAML fixture (cloned from `search/340_flattened.yml` and
`search/600_flattened_ignore_above.yml`) covering the exists query,
fields-option/synthetic-source reconstruction, and ignore_above
pruning paths with `type: flat_object` — the original PR's six
changed match arms had zero coverage, all six existing `flattened`
fixtures had no `flat_object` counterpart. Ran it against a live
built instance to confirm (a `field_caps` case had to be dropped —
the project's YAML test runner doesn't implement that action verb at
all, unrelated to this fix; covered the field_caps behavior with a
proper Rust end-to-end test instead, going through the real HTTP
route rather than a unit-level check).
Not addressed here: the commit message on the original PR describes
highlighting handling that isn't actually in the diff (an inaccuracy
in the message itself, not the code — noted in the PR thread rather
than rewriting a pushed, already-reviewed commit), and I couldn't
conclusively pin down which one of the six original match arms was
flagged as unreachable within reasonable effort — each one I traced
appeared to be on a live path, but the surrounding function is ~28k
lines and I didn't have a precise line reference to work from that
still matched the current file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014PRCbyt7Y2HDyhG1tbQTeL
|
Thanks — the
Two things I did not resolve, flagging rather than guessing:
Full suite green: 🤖 Generated with Claude Code |
|
Housekeeping, not a review comment. We've just added a Contributor License Agreement to the project (#93). Until now contributions here were covered only by Apache-2.0 §5's inbound=outbound clause, which gives no explicit patent grant — worth tightening for a project this size. Once #93 merges, a
That PR is the signature — it comes from your own account, so the commit history is the record. To be explicit about something: we did not add anyone to the signed list on their behalf, including you. That file asserts a person has signed, and that's not ours to assert for someone else — hence the ask rather than a quiet edit. Sorry for the extra step on work that's already in flight. Thanks for the contributions. |
Summary
flat_objectfield type indexes without expanding sub-fields — the same semantics asflattened, just a different type name.flattened, so any mapping usingflat_object(as OpenSearch's own sample dashboards/UBI sample data do) was rejected as an unsupported field type, and lost the flattened reconstruction/highlighting/ignore_abovehandling that comes with it.flattenedspecial case ines_compat.rsnow also treatsflat_objectas an alias.Test plan
cargo build -p xerj-apicargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo test -p xerj-api --lib(94 passed)flat_object) — no more "unsupported field type" rejection.🤖 Generated with Claude Code
https://claude.ai/code/session_014PRCbyt7Y2HDyhG1tbQTeL