Support flat_object field type in PPL projection - #5715
Draft
RyanL1997 wants to merge 1 commit into
Draft
Conversation
flat_object fields were dropped by OpenSearchDataType#parseMapping, which normalizes the mapping type to "flatobject", fails the MappingType lookup and executes a bare return. The field never reached the type environment, so it was absent from DESCRIBE and from query results, and any reference to it failed symbol resolution. Register flat_object as a STRUCT-backed MappingType. The existing struct machinery then applies unchanged: OpenSearchExprValueFactory routes it to parseStruct, and the Calcite type factory maps STRUCT to MAP(VARCHAR, ANY). Route it through the Object/Nested arm of of() rather than the default arm, so that it receives a fresh instance with a mutable property map. The default arm hands out the cached singleton whose properties field is an ImmutableMap, which fails cross-index merging in DESCRIBE. OpenSearchAliasType now also rejects an alias pointing at a flat_object, which would otherwise yield a field that DESCRIBE lists but SOURCE cannot select. This covers querying the field. Searching sub-fields is not addressed: subfield names are absent from the index mapping, so a flat_object contributes exactly one column. Nested values are returned as JSON text and paths deeper than one level resolve to NULL; both are pinned by tests and documented. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Jialiang Liang <jiallian@amazon.com>
Contributor
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
flat_objectfields are currently invisible to PPL — not merely unsupported.OpenSearchDataType#parseMappingnormalizes the mapping type withtype.replace("_", "")→"flatobject", failsEnumUtils.isValidEnumIgnoreCase, and executes a barereturn:The field therefore never reaches
traverseAndFlatten, so it is absent from the Calcite row type, fromOpenSearchExprValueFactory's type mapping, and fromDESCRIBE. Users see the field silently disappear from results, and any reference to it fails symbol resolution.Change: register
FlatObject("flat_object", ExprCoreType.STRUCT)inMappingType. Because@EqualsAndHashCodeexcludesmappingType, the existing struct machinery then applies with no further edits —OpenSearchExprValueFactoryroutes it toparseStruct, andOpenSearchTypeFactorymapsSTRUCTtoMAP(VARCHAR, ANY). The value factory is untouched.Two supporting changes:
flat_objectis routed through theObject/Nestedarm ofof()rather than thedefault:arm. The default arm hands out the cached singleton whosepropertiesfield is the class-levelImmutableMap, which fails cross-index merging inDESCRIBE(DeepMergeRule→LatestRule.put→UnsupportedOperationException). The Object arm yields a fresh instance with a mutableLinkedHashMap.OpenSearchAliasType.objectFieldTypesnow includesFlatObject, soalias -> flat_objectis rejected instead of producing a field thatDESCRIBElists butSOURCEcannot select.Behavior change
Measured at the schema layer with the same mapping, before and after:
User-visible, for
{"flat": {"s": "x", "n": 7, "a": {"b": 1}}}:source=idx{s=x, n=7, a={"b":1}}describe idxflat | structfields flat.sxfields flat.n7(_sourcetype preserved)where flat.s = 'x'fields flat.a{"b":1}— JSON text, not a structfields flat.a.bNULLScope
This PR covers querying the field. It does not implement searching sub-fields.
Subfield names are not present in the index mapping — OpenSearch resolves them lazily per query via
FlatObjectFieldType.keyedFieldType, and_field_capsdoes not expose them either. Since row types are built eagerly fromIndexMapping→parseMapping→traverseAndFlatten, aflat_objectcontributes exactly one column, and no plan-time hook can produceflat.aas a schema column.Two known limitations follow, and both are pinned by tests so any future change is deliberate:
OpenSearchExprValueFactory#parseContenthas no object branch and falls through tonew ExprStringValue(content.objectValue().toString()). TheContentinterface has noisObject()predicate, so a recursive branch cannot be written without extendingContentand both implementations. Related: [FEATURE] Support creating typed arrays & structs with Calcite #3751.NULL.QualifiedNameResolver#resolveFieldAccessjoins the remaining parts into a singleITEMkey ('a.b'), which cannot match a nested tuple.Also out of scope, and documented rather than worked around:
FlatObjectFieldType.isAggregatable()returnsfalseupstream (OpenSearch#14225 is open). This is an external limit, not a gap in this plugin.SqlKind.ITEMis whitelisted inPredicateAnalyzer.supportedRexCallbut has no case invisitCall's switch. Filters onflat.*currently run on the coordinator.Note on the DESCRIBE type name
PPL reports
structand SQL reportsflat_object, becauseOpenSearchDescribeIndexRequestuseslangSpec.typeName(getExprType())for PPL andlegacyTypeName()for SQL. This mirrors the existing contract forobjectfields and is deliberately unchanged here. Happy to revisit if reviewers would ratherDESCRIBEdistinguishflat_object, since the query semantics do differ.Testing
integ-test/.../rest-api-spec/test/issues/1604.yml— 5 cases covering projection with Calcite enabled and disabled, subfield addressability,DESCRIBE, and the two pinned limitations.tests=5 skipped=0 failures=0 errors=0.d9d15b1b3(Migrate to Jackson 3.x APIs) and re-verified, since that commit touchesOpenSearchJsonContent,ObjectContentandOpenSearchExprValueFactory— the decode path these tests assert on.Related Issues
Addresses item 1 of #1604 ("Support querying such fields, for example in
select *query"). Item 2 ("Support search for sub-fields") is out of scope — see Scope above.Addresses the primary complaint in #3067 (
flat_objectfields missing from query results).Part of #3695.
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.