[RFC] Widen numeric mapping conflicts across indices to one deterministic type
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
Read MergeRuleHelper.java and LatestRule.java to see how mapping conflicts are currently resolved, then review the proposed widening table and WideningTypeRule.java. The implementation discussion estimates about 80 lines for NumericWideningRule, but linked PR #5902 is already open. Done means numeric conflicts merge deterministically across index read orders while respecting the stated exclusions and behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem Statement
When the indices behind one source such as source=logs-* map the same field to two different number types, the plugin keeps the type of whichever index the merge reads last and decodes every document under it. Which index wins depends on the index names and can change between nodes and after a restart. Under the wrong winner a value changes or disappears with HTTP 200. A long 5000000000 read as integer overflows and comes back as 705032704, and a double 1.5 read as bigint comes back as null. A rollover that changes one field from integer to long is enough to trigger it.
#5828 reports the changed and null values, #5811 the 500 from a group-by on such a field, and #5610 asks for a conflict policy. A number against a string type, such as keyword against long, and conflicts that involve date or other special types will be proposed in separate RFCs.
Current State
MergeRuleHelper sends every conflict between two number types to LatestRule, and since #5618 a value that fails to decode under the winning type becomes null.
A type sweep of main at 00262797c ran all 28 pairs of the eight number types, byte, short, integer, long, half_float, float, scaled_float and double, in both read orders, through about 100 PPL templates. In 26 of the 28 pairs the merged type depends on the index names, 16 return a null in fields, and 16 return a 500 that neither type returns alone.
Scope
This RFC covers a field mapped as two or more number types across the indices of one source.
- Every engine - PPL on Calcite, PPL on the V2 engine and SQL share one mapping merge, so all three get the merged type.
- Number types only - The guarantee holds when every index maps the field as a number.
Out of scope:
- A number in some indices and a string in others - Mixed datatypes such as
long,keywordandintegerwill be a follow-up on a number against a string type. alias- An alias that points at a number field has no mapping type of its own, so it still reachesLatestRule, and when it meets a concrete number field the losing index's values can read as null.unsigned_long- The plugin does not support the type, so the merge never sees it. Support was requested in #1413 and closed as not planned.- Untested routes - Cross-cluster sources and the analytics engine route have not been tested.
Long-Term Goals
- A field mapped as different number types gets one merged type, whatever order the indices are read in.
- The merged type holds every value of every index, apart from a
longbeyond 2^53 next to a floating point type. A pushedfloataggregate may print more digits of the same stored value. - Every command either runs on the merged type or returns the same 4xx it returns on a single field of that type. A number conflict never causes a 5xx.
Proposal
A new NumericWideningRule sits ahead of LatestRule and merges number types to the widest one. The merged type depends only on which number types the indices hold, whatever the number of indices.
| Number types across the indices | Merged type |
|---|---|
integer types only, from byte, short, integer and long |
the widest of them |
half_float and float only |
float |
floating point types only, with scaled_float or double among them |
double |
| at least one integer type and at least one floating point type | double |
The ordering follows core's WideningTypeRule with one change. An integer with a floating point type merges to double, where WideningTypeRule picks float. A float holds integers exactly only up to 2^24, so 16777217 would read 16777216.0. The rule keeps its own copy, because V2 uses WideningTypeRule to pick function signatures.
The merged type decides how arithmetic behaves.
- An integer with a floating point type gives
double, sof / 2on3gives1.5.mainalready does this when the floating point index wins. - Integer types only give an integer type, so
f / 2on3still gives1under the defaultplugins.ppl.syntax.legacy.preferred. floor(f / 2)gives integer division on adoublefield.
Integer with float, measured under each merged type
An integer index holding 16777217 and a float index holding 0.1, under three sets of index names each.
| Merged type | fields f |
stats min(f), max(f) |
|---|---|---|
float, on main when float wins |
0.1, 16777216.0 |
0.1, 16777216.0 |
int, on main when integer wins |
null, 16777217 |
0, 16777217 |
double, with the rule |
0.1, 16777217.0 |
0.10000000149011612, 16777217.0 |
Approach
Pushdown with a merged type
The merged type decides how the plugin decodes values and plans the query, while each shard reads a pushed field under its own mapping, so a byte shard returns Integer, a long shard Long and a double shard Double. A pushed operation whose reduce compares those values across shards can fail whatever the merged type is. Raw _search requests show which ones.
Raw _search per pair, the composite terms and top_hits sort fail when the shards return different Java types
| Pair | plain sort | terms |
composite terms |
max |
top_hits sort |
|---|---|---|---|---|---|
integer with long |
200 | 200 | 200 | 200 | 500, passes with numeric_type: long |
integer with double |
200 | 200 | 500 | 200 | 500, passes with numeric_type: double |
long with double |
200 | 200 | 500 | 200 | 500, passes with numeric_type: double |
float with double |
200 | 200 | 200 | 200 | 500, passes with numeric_type: double |
Two kinds of PPL query reach the failing cells, and both already fail on main without the rule.
- #5811
- #5897
Ten other commands, among them fields, sort, where, stats and top, matched pushdown off on four pairs, on a source of all eight number types and on a source of the four integer types.
Costs
- An integer row next to a floating point type renders as a double, so
3reads3.0. This is the most common case, since dynamic mapping maps a JSON integer tolongand a JSON decimal tofloat. - A pushed
stats minover afloatindex prints0.1as0.10000000149011612, the stored float's exact value, when another index maps the field as a wider number. - A
longbeyond 2^53 next to a floating point type rounds when read, in a group key and in a distinct count. A pushedwhere f = 9007199254740993still matches only that document. half_floatwithfloatandscaled_floatwithdoublechange nothing, since PPL already reads them asfloatanddouble.
Alternative
- Merge every number conflict to
double. One rule with no ordering. It turns integer-only conflicts such asintegerwithlongintodoubletoo, so those rows read3.0and alongabove 2^53 rounds, where widening tolongloses nothing. - Widen an integer with
floattofloat, as core'sWideningTypeRuledoes. It keeps thefloatname, and it changes every integer above 2^24, so16777217reads16777216.0. - Merge number conflicts to string. Every value keeps its stored text exactly, but the field stops being a number, so
sort,maxandminorder the values as text andpercentilerejects them, even though a number type can hold every value. - Decode each document with its own index's mapping. It fixes the decode without choosing a winner, and it still needs a merged type for the schema and for pushdown. It changes the hit path, the aggregation parsers and the
top_hitsparser.
Implementation Discussion
- The policy is one PR,
NumericWideningRule, about 80 lines of main code. - Two existing bugs become simpler to fix once it lands, and each follows as its own fix.
- #5811 can read a field merged from integer and floating point types through a script that returns a double, since the merged type is then always
double, where onmainit may be an integer and the script would truncate the floating point values. - #5897 can also set
numeric_typeon thededupsort from the merged type
- #5811 can read a field merged from integer and floating point types through a script that returns a double, since the merged type is then always
- Lingua principale
- Java
- Stelle
- 175
- Fork
- 233
- Merge medio
- 3g 3h
- PR unite (30g)
- 42
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di opensearch-project/sql
-
[Enhancement] Make the flat_object read depth cap configurable instead of a constantForse già presa @RyanL1997 l’ha presa 10 giorni fa. Apertaenhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
opensearch-project/sql#5842 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] PromQL queries fail with InvalidTypeIdException when metric has a label named "type"Forse già presa @nagendramohan l’ha presa 72 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
opensearch-project/sql#5684 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[DOC] Calcite settings documentation missing examplesForse già presa @AzazelSensei l’ha presa 29 giorni fa. Apertadocumentation PPL
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
opensearch-project/sql#4806 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug PPL
Difficoltà 3/5 1-2 giorni Idoneità per principianti 66/100
opensearch-project/sql#5900 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] spath and seven json functions return 500 or a wrong 200 on a field type they do not supportApertabug PPL
Difficoltà 4/5 3-5 giorni Idoneità per principianti 50/100
opensearch-project/sql#5899 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di opensearch-project/sql
Issue simili
-
status: needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
JabRef/jabref#17546 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
hiero-ledger/hiero-sdk-java#3010 ·
I maintainer di solito rispondono entro 1 giorno
-
Optimize consumer version heatmap aggregation to avoid repeated scansForse già presa @praykaria31 l’ha presa oggi. Apertatype/enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Apicurio/apicurio-registry#10662 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
a:false-positive
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
I maintainer di solito rispondono entro 1 giorno
-
status: waiting-for-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
spring-projects/spring-boot#52347 ·
I maintainer di solito rispondono entro 2 giorni