diff --git a/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/4342.yml b/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/4342.yml new file mode 100644 index 00000000000..a3189e7588a --- /dev/null +++ b/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/4342.yml @@ -0,0 +1,55 @@ +setup: + - do: + query.settings: + body: + transient: + plugins.calcite.enabled : true + +--- +teardown: + - do: + query.settings: + body: + transient: + plugins.calcite.enabled : false + +--- +"No index found with given index pattern should throw IndexNotFoundException": + - skip: + features: + - headers + - allowed_warnings + - do: + indices.create: + index: log-test + body: + mappings: + properties: + "@timestamp": + type: date + + - do: + bulk: + index: log-test + refresh: true + body: + - '{"index": {}}' + - '{ "@timestamp" : "2025-09-04T16:15:00.000Z" }' + + - do: + headers: + Content-Type: 'application/json' + ppl: + body: + query: source=log-* | fields @timestamp + + - match: { total: 1 } + - length: { datarows: 1 } + + - do: + catch: missing # without the patch #4342, it throws 'bad_request' rather 'missing' + headers: + Content-Type: 'application/json' + ppl: + body: + query: source=log-abc* | fields @timestamp diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java index 9f3f114e676..83e913bf425 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java @@ -89,6 +89,9 @@ public Map getIndexMappings(String... indexExpression) { try { GetMappingsResponse mappingsResponse = client.admin().indices().prepareGetMappings(indexExpression).setLocal(true).get(); + if (mappingsResponse.mappings().isEmpty()) { + throw new IndexNotFoundException(indexExpression[0]); + } return mappingsResponse.mappings().entrySet().stream() .collect( Collectors.toUnmodifiableMap( diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchRestClient.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchRestClient.java index a65aa1997a8..2225a35ad54 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchRestClient.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchRestClient.java @@ -29,6 +29,7 @@ import org.opensearch.client.indices.GetMappingsResponse; import org.opensearch.cluster.metadata.AliasMetadata; import org.opensearch.common.settings.Settings; +import org.opensearch.index.IndexNotFoundException; import org.opensearch.sql.opensearch.mapping.IndexMapping; import org.opensearch.sql.opensearch.request.OpenSearchRequest; import org.opensearch.sql.opensearch.request.OpenSearchScrollRequest; @@ -71,6 +72,9 @@ public Map getIndexMappings(String... indexExpression) { GetMappingsRequest request = new GetMappingsRequest().indices(indexExpression); try { GetMappingsResponse response = client.indices().getMapping(request, RequestOptions.DEFAULT); + if (response.mappings().isEmpty()) { + throw new IndexNotFoundException(indexExpression[0]); + } return response.mappings().entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> new IndexMapping(e.getValue()))); } catch (IOException e) { diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java index 6e8cb789b42..948ac4854c0 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClientTest.java @@ -241,6 +241,12 @@ void get_index_mappings_with_IOException() { assertThrows(IllegalStateException.class, () -> client.getIndexMappings(indexName)); } + @Test + void get_index_mappings_with_index_patterns() { + mockNodeClientIndicesMappings("", null); + assertThrows(IndexNotFoundException.class, () -> client.getIndexMappings("test*")); + } + @Test void get_index_mappings_with_non_exist_index() { when(nodeClient.admin().indices().prepareGetMappings(any()).setLocal(anyBoolean()).get()) @@ -494,7 +500,9 @@ public void mockNodeClientIndicesMappings(String indexName, String mappings) { .thenReturn(mockResponse); try { Map metadata; - if (mappings.isEmpty()) { + if (mappings == null) { + metadata = Map.of(); + } else if (mappings.isEmpty()) { when(emptyMapping.getSourceAsMap()).thenReturn(Map.of()); metadata = Map.of(indexName, emptyMapping); } else { diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java index 4991fbbbdfd..6be02c9d6f1 100644 --- a/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java +++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/client/OpenSearchRestClientTest.java @@ -62,6 +62,7 @@ import org.opensearch.core.xcontent.DeprecationHandler; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.index.IndexNotFoundException; import org.opensearch.search.SearchHit; import org.opensearch.search.SearchHits; import org.opensearch.search.builder.SearchSourceBuilder; @@ -225,6 +226,15 @@ void get_index_mappings() throws IOException { OpenSearchTextType.of(MappingType.Long), parsedTypes.get("manager.salary"))); } + @Test + void get_index_mappings_with_index_patterns() throws IOException { + GetMappingsResponse response = mock(GetMappingsResponse.class); + when(response.mappings()).thenReturn(Map.of()); + when(restClient.indices().getMapping(any(GetMappingsRequest.class), any())) + .thenReturn(response); + assertThrows(IndexNotFoundException.class, () -> client.getIndexMappings("test*")); + } + @Test void get_index_mappings_with_IOException() throws IOException { when(restClient.indices().getMapping(any(GetMappingsRequest.class), any()))