Skip to content

Commit c34b869

Browse files
committed
[analytics-engine] Strip AE-unsupported fields from test datasets at load
The analytics-engine (DataFusion) backend cannot read nested, geo_point, geo_shape, binary, or alias fields. Rather than maintain per-index _ae dataset variants, strip those fields uniformly at load time on the AE route: - createIndexByRestClient recursively removes unsupported-typed properties from the mapping (including object sub-properties) and reports the top-level fields dropped. - loadIndex passes that set to a new loadDataByRestClient overload, which strips the matching keys from each bulk source doc so mapping and data agree. Gated on tests.analytics.parquet_indices; byte-for-byte no-op off the AE route. Replaces the earlier filename-_ae hook + hand-authored variant files. Signed-off-by: Eric Wei <mengwei.eric@gmail.com>
1 parent f7fb3d0 commit c34b869

15 files changed

Lines changed: 239 additions & 317 deletions
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.legacy;
7+
8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertFalse;
10+
import static org.junit.Assert.assertTrue;
11+
12+
import java.util.Set;
13+
import org.json.JSONObject;
14+
import org.junit.After;
15+
import org.junit.Test;
16+
import org.opensearch.sql.legacy.TestUtils.AnalyticsIndexConfig;
17+
18+
/**
19+
* Pure-logic coverage for the analytics-engine field strip (no filesystem / cluster). Verifies that
20+
* nested/geo_point/geo_shape/binary/alias fields are removed from mappings and bulk data on the AE
21+
* route, and that everything is a no-op when the route is off.
22+
*/
23+
public class AnalyticsFieldStripTests {
24+
25+
@After
26+
public void clearFlag() {
27+
System.clearProperty(AnalyticsIndexConfig.ENABLED_PROP);
28+
}
29+
30+
private void enable() {
31+
System.setProperty(AnalyticsIndexConfig.ENABLED_PROP, "true");
32+
}
33+
34+
private static final String MAPPING =
35+
"{\"mappings\":{\"properties\":{"
36+
+ "\"keep_text\":{\"type\":\"text\"},"
37+
+ "\"nested_value\":{\"type\":\"nested\"},"
38+
+ "\"geo_point_value\":{\"type\":\"geo_point\"},"
39+
+ "\"geo_shape_value\":{\"type\":\"geo_shape\"},"
40+
+ "\"binary_value\":{\"type\":\"binary\"},"
41+
+ "\"alias_value\":{\"type\":\"alias\",\"path\":\"keep_text\"},"
42+
+ "\"obj\":{\"properties\":{"
43+
+ " \"keep_inner\":{\"type\":\"keyword\"},"
44+
+ " \"inner_geo\":{\"type\":\"geo_point\"}}}"
45+
+ "}}}";
46+
47+
@Test
48+
public void mappingStrip_removesUnsupportedRecursively_andReportsTopLevel() {
49+
enable();
50+
JSONObject json = new JSONObject(MAPPING);
51+
Set<String> dropped = AnalyticsIndexConfig.stripUnsupportedMappingFields(json);
52+
53+
assertEquals(
54+
Set.of("nested_value", "geo_point_value", "geo_shape_value", "binary_value", "alias_value"),
55+
dropped);
56+
57+
JSONObject props = json.getJSONObject("mappings").getJSONObject("properties");
58+
assertTrue("supported scalar kept", props.has("keep_text"));
59+
assertFalse(props.has("nested_value"));
60+
assertFalse(props.has("geo_point_value"));
61+
assertFalse(props.has("geo_shape_value"));
62+
assertFalse(props.has("binary_value"));
63+
assertFalse(props.has("alias_value"));
64+
65+
// object field kept, but its unsupported sub-property stripped recursively
66+
assertTrue(props.has("obj"));
67+
JSONObject inner = props.getJSONObject("obj").getJSONObject("properties");
68+
assertTrue(inner.has("keep_inner"));
69+
assertFalse("nested geo_point inside object dropped", inner.has("inner_geo"));
70+
}
71+
72+
@Test
73+
public void mappingStrip_noopWhenDisabled() {
74+
JSONObject json = new JSONObject(MAPPING);
75+
Set<String> dropped = AnalyticsIndexConfig.stripUnsupportedMappingFields(json);
76+
assertTrue(dropped.isEmpty());
77+
assertTrue(json.getJSONObject("mappings").getJSONObject("properties").has("nested_value"));
78+
}
79+
80+
@Test
81+
public void bulkStrip_removesDroppedKeysFromSourceLinesOnly() {
82+
enable();
83+
String bulk =
84+
"{\"index\":{\"_id\":\"1\"}}\n"
85+
+ "{\"keep_text\":\"x\",\"geo_point_value\":{\"lat\":1,\"lon\":2},\"binary_value\":\"AA==\"}\n"
86+
+ "{\"index\":{\"_id\":\"2\"}}\n"
87+
+ "{\"keep_text\":\"y\",\"nested_value\":[{\"a\":1}]}\n";
88+
String out =
89+
AnalyticsIndexConfig.stripBulkFields(
90+
bulk, Set.of("geo_point_value", "binary_value", "nested_value"));
91+
92+
String[] lines = out.split("\n");
93+
// action lines untouched
94+
assertTrue(lines[0].contains("\"index\""));
95+
assertTrue(lines[2].contains("\"index\""));
96+
// source lines stripped, supported field retained
97+
JSONObject doc1 = new JSONObject(lines[1]);
98+
assertTrue(doc1.has("keep_text"));
99+
assertFalse(doc1.has("geo_point_value"));
100+
assertFalse(doc1.has("binary_value"));
101+
JSONObject doc2 = new JSONObject(lines[3]);
102+
assertTrue(doc2.has("keep_text"));
103+
assertFalse(doc2.has("nested_value"));
104+
}
105+
106+
@Test
107+
public void bulkStrip_noopWhenDisabledOrEmptyDropSet() {
108+
String bulk = "{\"index\":{}}\n{\"geo_point_value\":{\"lat\":1}}\n";
109+
// disabled -> unchanged even with a drop set
110+
assertEquals(bulk, AnalyticsIndexConfig.stripBulkFields(bulk, Set.of("geo_point_value")));
111+
// enabled but empty drop set -> unchanged
112+
enable();
113+
assertEquals(bulk, AnalyticsIndexConfig.stripBulkFields(bulk, Set.of()));
114+
}
115+
}

integ-test/src/test/java/org/opensearch/sql/legacy/AnalyticsIndexConfigVariantTests.java

Lines changed: 0 additions & 81 deletions
This file was deleted.

integ-test/src/test/java/org/opensearch/sql/legacy/SQLIntegTestCase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ protected synchronized void loadIndex(Index index, RestClient client) throws IOE
214214

215215
if (!isIndexExist(client, indexName)) {
216216
createIndexByRestClient(client, indexName, mapping);
217-
loadDataByRestClient(client, indexName, dataSet);
217+
// On the analytics-engine route, unsupported-typed fields are stripped from the mapping; drop
218+
// the same keys from the bulk data so the two agree. Empty (no-op) off the AE route.
219+
loadDataByRestClient(client, indexName, dataSet, analyticsDroppedFields(mapping));
218220
}
219221
}
220222

0 commit comments

Comments
 (0)