Registers EQUAL/NOTEQUAL overloads for [ARRAY<T>, scalar] argument
pairs, ahead of the scalar overloads so they win resolution for
multi-valued fields. `=` rewrites to Calcite ARRAY_CONTAINS (element
equality); `!=` to NOT(ARRAY_CONTAINS(...)).
This gives PPL the same semantics a Lucene term query has on a
multi-valued field: a document matches when ANY value equals the term.
Columnar engines (e.g. the OpenSearch composite engine's Parquet
format, where a field mapped `multi_value: true` is stored as a LIST
column and surfaces as ARRAY in the Calcite schema) previously
rejected the comparison outright: "EQUAL function expects
{[IP,IP],[COMPARABLE_TYPE,COMPARABLE_TYPE]}, but got [ARRAY,STRING]".
The new ARRAY_ELEMENT_COMPARABLE type checker matches only when arg0
is ARRAY, arg1 is NOT an array (array-to-array equality stays
unsupported rather than silently meaning overlap), and the element
type is comparable with the value under the same rules scalar
comparisons use (PPLComparableTypeChecker.isComparable, widened from
private to package-private rather than duplicated).
Signed-off-by: Bukhtawar Khan <bukhtawa@amazon.com>
Description
Registers
EQUAL/NOTEQUALoverloads for[ARRAY<T>, scalar]argument pairs inPPLFuncImpTable:tags = 'x'on an ARRAY-typed column now resolves to Calcite'sARRAY_CONTAINS(tags, 'x')(element equality), and!=toNOT(ARRAY_CONTAINS(...)).Why. This gives PPL the same semantics a Lucene term query has on a multi-valued field: a document matches when any value equals the term. Columnar storage engines surface multi-valued fields as ARRAY-typed columns — e.g. the OpenSearch composite engine's Parquet format, where a keyword field mapped
multi_value: trueis stored as aLIST<element>column (opensearch-project/OpenSearch#22685). Previously the analyzer rejected the comparison outright:Design notes.
[ARRAY, scalar]pair resolves to contains; all scalar comparisons are untouched.ARRAY_ELEMENT_COMPARABLEtype checker matches only when arg0 is ARRAY, arg1 is not an ARRAY (array-to-array equality stays unsupported rather than silently meaning overlap), and the element type is comparable with the value under the same rules scalar comparisons use —PPLComparableTypeChecker.isComparable, widened from private to package-private rather than duplicated.ARRAY_CONTAINSis element equality, not regex —mvfind(unanchored regex) is not a substitute for term equality.array_has; the Calcite Enumerable path uses Calcite's ownARRAY_CONTAINSimplementation.Verification. Unit test asserts
resolve(EQUAL, ARRAY<VARCHAR> ref, 'alpha')producesARRAY_CONTAINS($0, 'alpha'). Verified end-to-end against a live OpenSearch composite-engine cluster (Parquet LIST column → PPLwhere tags = 'alpha'→ DataFusionarray_has): contains-match, exact element equality (no substring match), and!=as NOT(contains) with three-valued-logic null exclusion. The consuming integration test lives in the OpenSearch PR above (MultiValueFieldIT.testEqualsOnMultiValueColumnMeansContains) and is muted there until this change ships in the published snapshot.Related Issues
Companion to opensearch-project/OpenSearch#22685 (multi-value keyword fields in the composite engine).
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.