fix: Gracefully handle malformed documents in result scanning - #5618
Conversation
Signed-off-by: Simeon Widdis <sawiddis@amazon.com>
Signed-off-by: Simeon Widdis <sawiddis@amazon.com>
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
…arch-project#5618) Signed-off-by: Simeon Widdis <sawiddis@amazon.com>
…ch-project#5685) On the Calcite path, `dedup` pushes down as a composite aggregation whose surviving row is fetched via top_hits and decoded from the nested _source. When a wildcard spans indices that disagree on whether a path is an object or a scalar, the merged mapping types the path as an object (STRUCT) while some documents store a scalar there. Decoding that scalar as a struct threw `java.sql.SQLException: ... class java.lang.String cannot be cast to class java.util.Map`, failing the whole query (100% on the reporting customer's `source=logs-pr172502-*`). Guard the STRUCT branch of OpenSearchExprValueFactory.parse to degrade a scalar-under-object value to null, completing the graceful handling opensearch-project#5618 added for the geo_point and scalar branches. The catch is scoped to ClassCastException because this branch is also the whole-document parse entry point and each nested object level is wrapped independently, so a broader catch would swallow legitimate errors raised deeper in the recursion. Adds a factory unit regression plus two CalcitePPLDedupIT cases (object-vs- scalar and the mirror scalar-vs-object, the latter guarding opensearch-project#5618). Signed-off-by: Kai Huang <ahkcs@amazon.com>
…ch-project#5685) On the Calcite path, `dedup` pushes down as a composite aggregation whose surviving row is fetched via top_hits and decoded from the nested _source. When a wildcard spans indices that disagree on whether a path is an object or a scalar, the merged mapping types the path as an object (STRUCT) while some documents store a scalar there. Decoding that scalar as a struct threw `java.sql.SQLException: ... class java.lang.String cannot be cast to class java.util.Map`, failing the whole query (100% on the reporting customer's `source=logs-pr172502-*`). Guard the STRUCT branch of OpenSearchExprValueFactory.parse to degrade a scalar-under-object value to null, completing the graceful handling opensearch-project#5618 added for the geo_point and scalar branches. The catch is scoped to ClassCastException because this branch is also the whole-document parse entry point and each nested object level is wrapped independently, so a broader catch would swallow legitimate errors raised deeper in the recursion. Adds a factory unit regression and a yamlRestTest (issues/5685.yml) covering the object-vs-scalar conflict and its mirror (scalar-vs-object, guarding opensearch-project#5618). Signed-off-by: Kai Huang <ahkcs@amazon.com>
…ch-project#5685) On the Calcite path, `dedup` pushes down as a composite aggregation whose surviving row is fetched via top_hits and decoded from the nested _source. When a wildcard spans indices that disagree on whether a path is an object or a scalar, the merged mapping types the path as an object (STRUCT) while some documents store a scalar there. Decoding that scalar as a struct threw `java.sql.SQLException: ... class java.lang.String cannot be cast to class java.util.Map`, failing the whole query (100% on the reporting customer's `source=logs-pr172502-*`). Guard the STRUCT branch of OpenSearchExprValueFactory.parse to degrade a scalar-under-object value to null, completing the graceful handling opensearch-project#5618 added for the geo_point and scalar branches. The catch is scoped to ClassCastException because this branch is also the whole-document parse entry point and each nested object level is wrapped independently, so a broader catch would swallow legitimate errors raised deeper in the recursion. Adds a factory unit regression and a yamlRestTest (issues/5685.yml) covering the object-vs-scalar conflict and its mirror (scalar-vs-object, guarding opensearch-project#5618). Signed-off-by: Kai Huang <ahkcs@amazon.com>
…5732) On the Calcite path, `dedup` pushes down as a composite aggregation whose surviving row is fetched via top_hits and decoded from the nested _source. When a wildcard spans indices that disagree on whether a path is an object or a scalar, the merged mapping types the path as an object (STRUCT) while some documents store a scalar there. Decoding that scalar as a struct threw `java.sql.SQLException: ... class java.lang.String cannot be cast to class java.util.Map`, failing the whole query (100% on the reporting customer's `source=logs-pr172502-*`). Guard the STRUCT branch of OpenSearchExprValueFactory.parse to degrade a scalar-under-object value to null, completing the graceful handling #5618 added for the geo_point and scalar branches. The catch is scoped to ClassCastException because this branch is also the whole-document parse entry point and each nested object level is wrapped independently, so a broader catch would swallow legitimate errors raised deeper in the recursion. Adds a factory unit regression and a yamlRestTest (issues/5685.yml) covering the object-vs-scalar conflict and its mirror (scalar-vs-object, guarding #5618). Signed-off-by: Kai Huang <ahkcs@amazon.com>
Description
In general, documents are validated by OpenSearch according to the mapping types at index time. However, this behavior can be bypassed via the
index.mapping.ignore_malformedsetting, which lets you index arbitrary data regardless of the mapping. This causes PPL to crash any time it encounters these documents.This PR adds a lot of handling around malformed documents, both at a per-field level (6 individual bad cases involving timestamp, geo, IP, and others) and at an overall level (if a document causes some sort of cascading failure not handled by the prev checks, then we log & skip).
Notes/future work:
Exceptions for field parsing, kinda aggressive but I think for our purposes it's always better to fail one field over failing a doc.Additionally tested:
where malformed_field is nullandis not nullin queries will work as expected.Related Issues
Internal ticket.
Check List
--signoffor-s.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.