[BUG] spath and seven json functions return 500 or a wrong 200 on a field type they do not support
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 50/100
Direzione di ricerca
Start with SPath.java and the JSON function implementations in core/src/main/java/org/opensearch/sql/expression/function/jsonUDF, especially JsonExtractFunctionImpl.java, then compare their operand metadata and return types with json_extract_all and json_array_length. Use the listed PPL queries and field mappings to check that unsupported operand types produce HTTP 400 errors with type details and that valid string inputs still work. Also verify json returns a string result for numeric and boolean inputs.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Query Information
PPL Command/Query:
source=spx | spath input=n a
n is a long field.
Expected Result: HTTP 400 naming the expected and actual type. spath input=n on the same field, with no path, already returns a 400 that names the type, JSON_EXTRACT_ALL function expects {[STRING]}, but got [LONG].
Actual Result: HTTP 500.
{
"error": {
"context": {
"stage": "executing",
"stage_description": "Running the query"
},
"reason": "class java.lang.Long cannot be cast to class java.lang.String (java.lang.Long and java.lang.String are in module java.base of loader 'bootstrap')",
"details": "class java.lang.Long cannot be cast to class java.lang.String (java.lang.Long and java.lang.String are in module java.base of loader 'bootstrap')",
"location": ["while running the query"],
"code": "UNKNOWN",
"type": "ClassCastException"
},
"status": 500
}
spath with a path runs json_extract, one of seven json functions with no operand type check.
Each column is its own index with one document, where f is mapped to the column's type. f holds the JSON string {"a": "x"} for keyword, 5 for long, 1.5 for double, true for boolean, 1.2.3.4 for ip, {"a": "x"} for object and flat_object, and [{"a": "x"}] for nested.
| Command | keyword |
long |
double |
boolean |
ip |
object |
flat_object |
nested |
|---|---|---|---|---|---|---|---|---|
spath input=f a |
200 | 500 | 500 | 500 | 500 | 500 | 500 | 500 |
json_extract(f, 'a') |
200 | 500 | 500 | 500 | 500 | 500 | 500 | 500 |
json_set(f, 'a', '1') |
200 | 500 | 500 | 500 | 500 | 500 | 500 | 500 |
json_append(f, 'a', '1') |
200 | 500 | 500 | 500 | 500 | 500 | 500 | 500 |
json_extend(f, 'a', '1') |
200 | 500 | 500 | 500 | 500 | 500 | 500 | 500 |
json_keys(f) |
200 | 200, null |
200, null |
200, null |
500 | 500 | 500 | 500 |
json_delete(f, 'a') |
200 | 200, "5" |
200, "1.5" |
200, "true" |
500 | 500 | 500 | 500 |
json(f) |
200 | 500 | 500 | 500 | 200, null |
200, null |
200, null |
200, null |
spath input=f, for comparison |
200 | 400 | 400 | 400 | 400 | 400 | 400 | 400 |
json_array_length(f), for comparison |
200 | 400 | 400 | 400 | 400 | 400 | 400 | 400 |
Every 500 in the first five rows is a ClassCastException to String. The 500s from json_keys and json_delete are CalciteException Invalid input for JSON_KEYS and Invalid input for JSON_REMOVE. The 500s from json are the reverse cast, such as class java.lang.String cannot be cast to class java.lang.Long on long.
With plugins.calcite.pushdown.enabled=false the query still returns HTTP 500 with the same cast, reported as a RuntimeException whose message carries an SQLException prefix. With pushdown on, _explain shows JSON_EXTRACT in an EnumerableCalc above the index scan, and the pushed request only fetches f from _source, so OpenSearch core is not involved.
Node log for source=spx | spath input=n a
[ERROR][o.o.s.p.r.RestPPLQueryAction] Error happened during query handling (status INTERNAL_SERVER_ERROR)
org.opensearch.sql.common.error.ErrorReport: class java.lang.Long cannot be cast to class java.lang.String (java.lang.Long and java.lang.String are in module java.base of loader 'bootstrap')
at org.opensearch.sql.executor.QueryService.executeCalcitePlan(QueryService.java:277)
Caused by: java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.String (java.lang.Long and java.lang.String are in module java.base of loader 'bootstrap')
at org.opensearch.sql.expression.function.jsonUDF.JsonExtractFunctionImpl.eval(JsonExtractFunctionImpl.java:64)
at org.opensearch.sql.opensearch.executor.OpenSearchExecutionEngine.buildResultSet(OpenSearchExecutionEngine.java:442)
at org.opensearch.sql.opensearch.executor.OpenSearchExecutionEngine.lambda$execute$6(OpenSearchExecutionEngine.java:338)
Dataset Information
Dataset/Schema Type
- OpenTelemetry (OTEL)
- Simple Schema for Observability (SS4O)
- Open Cybersecurity Schema Framework (OCSF)
- Custom (details below)
Index Mapping
PUT spx { "mappings": { "properties": { "host": { "type": "keyword" }, "n": { "type": "long" }, "j": { "type": "keyword" } } } }
Sample Data
POST spx/_doc/1?refresh=true { "host": "a", "n": 5, "j": "{\"a\": \"x\"}" }
Bug Description
Issue Summary
spath with a path is rewritten to json_extract in SPath. JsonExtractFunctionImpl.getOperandMetadata() returns null, so JSON_EXTRACT accepts any argument, and eval casts the first one with String jsonStr = (String) args[0];. json_set, json_append and json_extend also have null metadata and make the same cast. json_keys, json_delete and json have null metadata and call args[0].toString() instead. The result type of json is wrong as well. ReturnTypes.ARG0_FORCE_NULLABLE types it as the input type while eval returns a string, so a number or boolean input throws the reverse cast.
spath without a path runs json_extract_all, which declares a STRING operand checker, as json_array_length does. Both reject a non-string at analysis with an ExpressionEvaluationException, which SyncErrorReportRenderer.isClientError maps to 400. isClientError lists neither ClassCastException nor CalciteException, so the unchecked functions return 500.
Steps to Reproduce
curl -s -XPUT "localhost:9200/spx" -H 'Content-Type: application/json' \
-d '{"mappings":{"properties":{"host":{"type":"keyword"},"n":{"type":"long"},"j":{"type":"keyword"}}}}'
curl -s -XPOST "localhost:9200/spx/_doc/1?refresh=true" -H 'Content-Type: application/json' \
-d '{"host":"a","n":5,"j":"{\"a\": \"x\"}"}'
# 1. spath with a path on a long returns HTTP 500 ClassCastException
curl -s -XPOST "localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' \
-d '{"query":"source=spx | spath input=n a"}' -w '\nHTTP %{http_code}\n'
# 2. json_extract on the same field returns the same HTTP 500
curl -s -XPOST "localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' \
-d '{"query":"source=spx | eval x = json_extract(n, '\''a'\'') | fields x"}' -w '\nHTTP %{http_code}\n'
# 3. spath without a path on the same field is checked and returns HTTP 400
curl -s -XPOST "localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' \
-d '{"query":"source=spx | spath input=n | fields host"}' -w '\nHTTP %{http_code}\n'
# 4. spath with a path on the JSON string returns HTTP 200
curl -s -XPOST "localhost:9200/_plugins/_ppl" -H 'Content-Type: application/json' \
-d '{"query":"source=spx | spath input=j a | fields a"}' -w '\nHTTP %{http_code}\n'
Impact
spath pointed at a field mapped as a number or an object, such as an OTel attributes object, returns a 500 naming two Java classes instead of the type it needs. json_keys and json_delete on a number return a 200 that looks like a result.
Environment Information
OpenSearch Version: main at f36c99f84, 3.10.0-SNAPSHOT, one node, with the defaults plugins.calcite.enabled=true, plugins.calcite.pushdown.enabled=true and plugins.calcite.fallback.allowed=false.
- Lingua principale
- Java
- Stelle
- 175
- Fork
- 232
- 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 9 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
-
[RFC] Widen numeric mapping conflicts across indices to one deterministic typeForse già presa @cnoramut l’ha presa 1 giorno fa. Apertauntriaged
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
opensearch-project/sql#5901 · 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
Tutte le issue di opensearch-project/sql
Issue simili
-
enhancement feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
rsp777/service-pulse-app#28 ·
-
human-required sync-failed
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
Azure/osdu-spi-file#63 ·
I maintainer di solito rispondono entro 1 giorno
-
area/ysql kind/enhancement priority/medium status/awaiting-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
yugabyte/yugabyte-db#35578 ·
I maintainer di solito rispondono entro 1 giorno
-
frontend quick win
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
CodeForPhilly/benefit-decision-toolkit#571 ·
I maintainer di solito rispondono entro 1 giorno
-
approved
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
checkstyle/checkstyle#22129 ·
I maintainer di solito rispondono entro 1 giorno