Skip to content

Commit 7f2b60f

Browse files
authored
Stabilize PPL ITs on the analytics-engine route (array/map-path/datatype/basic) (opensearch-project#5562)
Analytics-engine route parity for four PPL IT classes; test-only. Uses the @RequiresCapability annotation + Capability registry (opensearch-project#5560) plus matching excludeTestsMatching entries. CalciteArrayFunctionIT: - Skip the array-index load on the AE route (multi-value 'numbers' field the parquet store rejects); no test queries it (all build arrays inline). - 16 higher-order lambda functions (transform/mvmap, reduce, filter, exists, forall) -> new ARRAY_HIGHER_ORDER_FUNC (no DataFusion lambda execution). CalcitePPLMapPathIT: - mvcombine lowers to ARRAY_AGG, unregistered on the analytics backend -> new MVCOMBINE_ARRAY_AGG. - addtotals crashes the DataFusion backend with a join panic -> new ADDTOTALS_JOIN_PANIC. CalciteDataTypeIT (guards on base DataTypeIT; build.gradle globs broadened to '*' so they cover the Calcite subclass): - test_nonnumeric_data_types / test_alias_data_type: nested/object/geo/alias types stripped (NESTED_FIELDS). - test_numeric_data_types: scaled_float reported as bigint not double -> new SCALED_FLOAT_TYPE. - testNumericFieldFromString: empty-string -> numeric coerces to null not 0 -> new STRING_TO_NUMERIC_COERCION. - testBooleanFieldFromNumberAcrossWildcardIndices: cross-index incompatible field types rejected -> new CROSS_INDEX_INCOMPATIBLE_TYPES. - testBooleanFieldFromString: seeds+deletes a doc; DELETE unsupported (DOC_MUTATION). CalcitePPLBasicIT.testRegexpFilter: REGEXP filter throws a backend NullPointerException on the AE route -> new REGEXP_FILTER. v2/Calcite route unchanged (all run, 0 skips). Signed-off-by: Kai Huang <ahkcs@amazon.com>
1 parent 9367c2a commit 7f2b60f

6 files changed

Lines changed: 220 additions & 2 deletions

File tree

integ-test/build.gradle

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,12 @@ task integTestRemote(type: RestIntegTestTask) {
10801080
excludeTestsMatching '*SystemFunctionIT.typeof_opensearch_types'
10811081
// alias_index_mapping: alias_col is type=alias; query is `where alias_col > 1`.
10821082
excludeTestsMatching '*DataTypeIT.test_alias_data_type'
1083+
// scaled_float reports bigint (not double); string->numeric coerces to null (not 0);
1084+
// cross-index incompatible field types are rejected; boolean-from-string test DELETEs.
1085+
excludeTestsMatching '*DataTypeIT.test_numeric_data_types'
1086+
excludeTestsMatching '*DataTypeIT.testNumericFieldFromString'
1087+
excludeTestsMatching '*DataTypeIT.testBooleanFieldFromNumberAcrossWildcardIndices'
1088+
excludeTestsMatching '*DataTypeIT.testBooleanFieldFromString'
10831089
// CalciteAliasFieldAggregationIT: raw-PUT alias index can't be created on the AE route
10841090
// and every test queries alias fields directly — whole class doomed.
10851091
excludeTestsMatching 'org.opensearch.sql.calcite.remote.CalciteAliasFieldAggregationIT'
@@ -1204,6 +1210,35 @@ task integTestRemote(type: RestIntegTestTask) {
12041210
// === Excludes: CalcitePPLAppendPipeCommandIT route divergence ===
12051211
// appendpipe drops the main pipeline's rows on AE (subpipe filter applied in place).
12061212
excludeTestsMatching '*CalcitePPLAppendPipeCommandIT.testDoubleAppendPipeWithFilter'
1213+
1214+
// === Excludes: CalciteArrayFunctionIT route divergences ===
1215+
// Higher-order array functions (transform/mvmap, reduce, filter, exists, forall) take a
1216+
// PPL lambda the AE backends can't execute ('No backend supports scalar function [...]').
1217+
excludeTestsMatching '*CalciteArrayFunctionIT.testForAll'
1218+
excludeTestsMatching '*CalciteArrayFunctionIT.testExists'
1219+
excludeTestsMatching '*CalciteArrayFunctionIT.testFilter'
1220+
excludeTestsMatching '*CalciteArrayFunctionIT.testTransform'
1221+
excludeTestsMatching '*CalciteArrayFunctionIT.testTransformForTwoInput'
1222+
excludeTestsMatching '*CalciteArrayFunctionIT.testTransformForWithDouble'
1223+
excludeTestsMatching '*CalciteArrayFunctionIT.testTransformForWithUDF'
1224+
excludeTestsMatching '*CalciteArrayFunctionIT.testReduce'
1225+
excludeTestsMatching '*CalciteArrayFunctionIT.testReduce2'
1226+
excludeTestsMatching '*CalciteArrayFunctionIT.testReduce3'
1227+
excludeTestsMatching '*CalciteArrayFunctionIT.testReduceWithUDF'
1228+
excludeTestsMatching '*CalciteArrayFunctionIT.testMvmap'
1229+
excludeTestsMatching '*CalciteArrayFunctionIT.testMvmapWithAddition'
1230+
excludeTestsMatching '*CalciteArrayFunctionIT.testMvmapWithEvalFieldReference'
1231+
excludeTestsMatching '*CalciteArrayFunctionIT.testMvmapWithNestedFunction'
1232+
excludeTestsMatching '*CalciteArrayFunctionIT.testMvmapWithOtherFieldReference'
1233+
1234+
// === Excludes: CalcitePPLMapPathIT route divergences ===
1235+
// mvcombine -> ARRAY_AGG (no such AggregateFunction enum); addtotals -> DataFusion join panic.
1236+
excludeTestsMatching '*CalcitePPLMapPathIT.testMvcombineOnMapPath'
1237+
excludeTestsMatching '*CalcitePPLMapPathIT.testAddtotalsOnMapPath'
1238+
1239+
// === Excludes: CalcitePPLBasicIT route divergence ===
1240+
// REGEXP filter throws a backend NullPointerException on the AE route.
1241+
excludeTestsMatching '*CalcitePPLBasicIT.testRegexpFilter'
12071242
}
12081243
}
12091244

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteArrayFunctionIT.java

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.sql.calcite.remote;
77

88
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_BANK;
9+
import static org.opensearch.sql.util.Capability.ARRAY_HIGHER_ORDER_FUNC;
910
import static org.opensearch.sql.util.MatcherUtils.*;
1011

1112
import java.io.IOException;
@@ -15,14 +16,19 @@
1516
import org.junit.jupiter.api.Test;
1617
import org.opensearch.client.ResponseException;
1718
import org.opensearch.sql.ppl.PPLIntegTestCase;
19+
import org.opensearch.sql.util.RequiresCapability;
1820

1921
public class CalciteArrayFunctionIT extends PPLIntegTestCase {
2022
@Override
2123
public void init() throws Exception {
2224
super.init();
2325
enableCalcite();
2426
loadIndex(Index.BANK);
25-
loadIndex(Index.ARRAY);
27+
// No test queries the array index (all build arrays inline via array()); its multi-value
28+
// numbers field can't be bulk-loaded into the parquet store, so skip it on the AE route.
29+
if (!isAnalyticsParquetIndicesEnabled()) {
30+
loadIndex(Index.ARRAY);
31+
}
2632
}
2733

2834
@Test
@@ -85,6 +91,11 @@ public void testArrayLength() throws IOException {
8591
}
8692

8793
@Test
94+
@RequiresCapability(
95+
value = ARRAY_HIGHER_ORDER_FUNC,
96+
note =
97+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
98+
+ " lambda.")
8899
public void testForAll() throws IOException {
89100
JSONObject actual =
90101
executeQuery(
@@ -99,6 +110,11 @@ public void testForAll() throws IOException {
99110
}
100111

101112
@Test
113+
@RequiresCapability(
114+
value = ARRAY_HIGHER_ORDER_FUNC,
115+
note =
116+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
117+
+ " lambda.")
102118
public void testExists() throws IOException {
103119
JSONObject actual =
104120
executeQuery(
@@ -113,6 +129,11 @@ public void testExists() throws IOException {
113129
}
114130

115131
@Test
132+
@RequiresCapability(
133+
value = ARRAY_HIGHER_ORDER_FUNC,
134+
note =
135+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
136+
+ " lambda.")
116137
public void testFilter() throws IOException {
117138
JSONObject actual =
118139
executeQuery(
@@ -127,6 +148,11 @@ public void testFilter() throws IOException {
127148
}
128149

129150
@Test
151+
@RequiresCapability(
152+
value = ARRAY_HIGHER_ORDER_FUNC,
153+
note =
154+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
155+
+ " lambda.")
130156
public void testTransform() throws IOException {
131157
JSONObject actual =
132158
executeQuery(
@@ -141,6 +167,11 @@ public void testTransform() throws IOException {
141167
}
142168

143169
@Test
170+
@RequiresCapability(
171+
value = ARRAY_HIGHER_ORDER_FUNC,
172+
note =
173+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
174+
+ " lambda.")
144175
public void testTransformForTwoInput() throws IOException {
145176
JSONObject actual =
146177
executeQuery(
@@ -155,6 +186,11 @@ public void testTransformForTwoInput() throws IOException {
155186
}
156187

157188
@Test
189+
@RequiresCapability(
190+
value = ARRAY_HIGHER_ORDER_FUNC,
191+
note =
192+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
193+
+ " lambda.")
158194
public void testTransformForWithDouble() throws IOException {
159195
JSONObject actual =
160196
executeQuery(
@@ -169,6 +205,11 @@ public void testTransformForWithDouble() throws IOException {
169205
}
170206

171207
@Test
208+
@RequiresCapability(
209+
value = ARRAY_HIGHER_ORDER_FUNC,
210+
note =
211+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
212+
+ " lambda.")
172213
public void testTransformForWithUDF() throws IOException {
173214
JSONObject actual =
174215
executeQuery(
@@ -185,6 +226,11 @@ public void testTransformForWithUDF() throws IOException {
185226
}
186227

187228
@Test
229+
@RequiresCapability(
230+
value = ARRAY_HIGHER_ORDER_FUNC,
231+
note =
232+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
233+
+ " lambda.")
188234
public void testReduce() throws IOException {
189235
JSONObject actual =
190236
executeQuery(
@@ -202,6 +248,11 @@ public void testReduce() throws IOException {
202248
}
203249

204250
@Test
251+
@RequiresCapability(
252+
value = ARRAY_HIGHER_ORDER_FUNC,
253+
note =
254+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
255+
+ " lambda.")
205256
public void testReduce2() throws IOException {
206257
JSONObject actual =
207258
executeQuery(
@@ -216,6 +267,11 @@ public void testReduce2() throws IOException {
216267
}
217268

218269
@Test
270+
@RequiresCapability(
271+
value = ARRAY_HIGHER_ORDER_FUNC,
272+
note =
273+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
274+
+ " lambda.")
219275
public void testReduce3() throws IOException {
220276
JSONObject actual =
221277
executeQuery(
@@ -231,6 +287,11 @@ public void testReduce3() throws IOException {
231287
}
232288

233289
@Test
290+
@RequiresCapability(
291+
value = ARRAY_HIGHER_ORDER_FUNC,
292+
note =
293+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
294+
+ " lambda.")
234295
public void testReduceWithUDF() throws IOException {
235296
JSONObject actual =
236297
executeQuery(
@@ -796,6 +857,11 @@ public void testSplitWithEmptyDelimiter() throws IOException {
796857
}
797858

798859
@Test
860+
@RequiresCapability(
861+
value = ARRAY_HIGHER_ORDER_FUNC,
862+
note =
863+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
864+
+ " lambda.")
799865
public void testMvmap() throws IOException {
800866
JSONObject actual =
801867
executeQuery(
@@ -809,6 +875,11 @@ public void testMvmap() throws IOException {
809875
}
810876

811877
@Test
878+
@RequiresCapability(
879+
value = ARRAY_HIGHER_ORDER_FUNC,
880+
note =
881+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
882+
+ " lambda.")
812883
public void testMvmapWithAddition() throws IOException {
813884
JSONObject actual =
814885
executeQuery(
@@ -822,6 +893,11 @@ public void testMvmapWithAddition() throws IOException {
822893
}
823894

824895
@Test
896+
@RequiresCapability(
897+
value = ARRAY_HIGHER_ORDER_FUNC,
898+
note =
899+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
900+
+ " lambda.")
825901
public void testMvmapWithNestedFunction() throws IOException {
826902
// Test mvmap with mvindex as first argument - extracts field name from nested function
827903
// Equivalent to Splunk: mvmap(mvindex(arr, 1, 3), arr * 10)
@@ -839,6 +915,11 @@ public void testMvmapWithNestedFunction() throws IOException {
839915
}
840916

841917
@Test
918+
@RequiresCapability(
919+
value = ARRAY_HIGHER_ORDER_FUNC,
920+
note =
921+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
922+
+ " lambda.")
842923
public void testMvmapWithOtherFieldReference() throws IOException {
843924
// Test mvmap with reference to another field in the expression
844925
// The first record in bank has age=32, so array(1,2,3) * 32 = [32, 64, 96]
@@ -854,6 +935,11 @@ public void testMvmapWithOtherFieldReference() throws IOException {
854935
}
855936

856937
@Test
938+
@RequiresCapability(
939+
value = ARRAY_HIGHER_ORDER_FUNC,
940+
note =
941+
"Higher-order array function (transform/mvmap/reduce/filter/exists/forall) takes a"
942+
+ " lambda.")
857943
public void testMvmapWithEvalFieldReference() throws IOException {
858944
// Test mvmap with reference to another field created by eval
859945
// array(1,2,3) * 10 = [10, 20, 30]

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLBasicIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static org.junit.Assume.assumeFalse;
99
import static org.opensearch.sql.legacy.TestUtils.isIndexExist;
1010
import static org.opensearch.sql.legacy.TestsConstants.*;
11+
import static org.opensearch.sql.util.Capability.REGEXP_FILTER;
1112
import static org.opensearch.sql.util.MatcherUtils.rows;
1213
import static org.opensearch.sql.util.MatcherUtils.schema;
1314
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
@@ -21,6 +22,7 @@
2122
import org.opensearch.client.ResponseException;
2223
import org.opensearch.sql.exception.SemanticCheckException;
2324
import org.opensearch.sql.ppl.PPLIntegTestCase;
25+
import org.opensearch.sql.util.RequiresCapability;
2426

2527
public class CalcitePPLBasicIT extends PPLIntegTestCase {
2628

@@ -154,6 +156,9 @@ public void testFilterQuery4() throws IOException {
154156
}
155157

156158
@Test
159+
@RequiresCapability(
160+
value = REGEXP_FILTER,
161+
note = "REGEXP filter throws a backend NullPointerException on the AE route.")
157162
public void testRegexpFilter() throws IOException {
158163
JSONObject actual = executeQuery("source=test | where name REGEXP 'he.*' | fields name, age");
159164
verifySchema(actual, schema("name", "string"), schema("age", "bigint"));

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLMapPathIT.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package org.opensearch.sql.calcite.remote;
77

8+
import static org.opensearch.sql.util.Capability.ADDTOTALS_JOIN_PANIC;
9+
import static org.opensearch.sql.util.Capability.MVCOMBINE_ARRAY_AGG;
810
import static org.opensearch.sql.util.MatcherUtils.rows;
911
import static org.opensearch.sql.util.MatcherUtils.schema;
1012
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
@@ -22,6 +24,7 @@
2224
import org.junit.jupiter.api.Test;
2325
import org.opensearch.client.Request;
2426
import org.opensearch.sql.ppl.PPLIntegTestCase;
27+
import org.opensearch.sql.util.RequiresCapability;
2528

2629
/**
2730
* Integration tests for PPL queries that reference MAP dotted paths (e.g. {@code doc.user.name}).
@@ -141,6 +144,9 @@ public void testFieldsExclusionOnMapPath() throws IOException {
141144
}
142145

143146
@Test
147+
@RequiresCapability(
148+
value = ADDTOTALS_JOIN_PANIC,
149+
note = "addtotals crashes the DataFusion backend with a join panic on the AE route.")
144150
public void testAddtotalsOnMapPath() throws IOException {
145151
JSONObject result =
146152
ppl(
@@ -163,6 +169,9 @@ public void testAddtotalsOnMapPath() throws IOException {
163169
}
164170

165171
@Test
172+
@RequiresCapability(
173+
value = MVCOMBINE_ARRAY_AGG,
174+
note = "mvcombine lowers to ARRAY_AGG, unregistered on the analytics backend.")
166175
public void testMvcombineOnMapPath() throws IOException {
167176
JSONObject result =
168177
ppl(

0 commit comments

Comments
 (0)