2424import org .elasticsearch .index .engine .TranslogOperationAsserter ;
2525import org .elasticsearch .index .engine .VersionConflictEngineException ;
2626import org .elasticsearch .index .get .GetResult ;
27+ import org .elasticsearch .index .get .ShardGetService ;
28+ import org .elasticsearch .index .mapper .InferenceMetadataFieldsMapper ;
2729import org .elasticsearch .index .mapper .RoutingFieldMapper ;
2830import org .elasticsearch .index .translog .Translog ;
2931import org .elasticsearch .search .fetch .subphase .FetchSourceContext ;
32+ import org .elasticsearch .search .lookup .SourceFilter ;
3033import org .elasticsearch .xcontent .XContentBuilder ;
3134import org .elasticsearch .xcontent .XContentFactory ;
3235import org .elasticsearch .xcontent .XContentParser ;
@@ -411,6 +414,16 @@ public void testGetFromTranslog() throws IOException {
411414 closeShards (primary );
412415 }
413416
417+ public void testShouldExcludeInferenceFieldsFromSource () {
418+ for (int i = 0 ; i < 100 ; i ++) {
419+ ExcludeInferenceFieldsTestScenario scenario = new ExcludeInferenceFieldsTestScenario ();
420+ assertThat (
421+ ShardGetService .shouldExcludeInferenceFieldsFromSource (scenario .fetchSourceContext ),
422+ equalTo (scenario .shouldExcludeInferenceFields ())
423+ );
424+ }
425+ }
426+
414427 Translog .Index toIndexOp (String source ) throws IOException {
415428 XContentParser parser = createParser (XContentType .JSON .xContent (), source );
416429 XContentBuilder builder = XContentFactory .jsonBuilder ();
@@ -425,4 +438,74 @@ Translog.Index toIndexOp(String source) throws IOException {
425438 IndexRequest .UNSET_AUTO_GENERATED_TIMESTAMP
426439 );
427440 }
441+
442+ private static class ExcludeInferenceFieldsTestScenario {
443+ private final FetchSourceContext fetchSourceContext ;
444+
445+ private ExcludeInferenceFieldsTestScenario () {
446+ this .fetchSourceContext = generateRandomFetchSourceContext ();
447+ }
448+
449+ private boolean shouldExcludeInferenceFields () {
450+ if (fetchSourceContext != null ) {
451+ if (fetchSourceContext .fetchSource () == false ) {
452+ return true ;
453+ }
454+
455+ SourceFilter filter = fetchSourceContext .filter ();
456+ if (filter != null ) {
457+ if (Arrays .asList (filter .getExcludes ()).contains (InferenceMetadataFieldsMapper .NAME )) {
458+ return true ;
459+ } else if (filter .getIncludes ().length > 0 ) {
460+ return Arrays .asList (filter .getIncludes ()).contains (InferenceMetadataFieldsMapper .NAME ) == false ;
461+ }
462+ }
463+
464+ Boolean excludeInferenceFieldsExplicit = fetchSourceContext .excludeInferenceFields ();
465+ if (excludeInferenceFieldsExplicit != null ) {
466+ return excludeInferenceFieldsExplicit ;
467+ }
468+ }
469+
470+ return true ;
471+ }
472+
473+ private static FetchSourceContext generateRandomFetchSourceContext () {
474+ FetchSourceContext fetchSourceContext = switch (randomIntBetween (0 , 4 )) {
475+ case 0 -> FetchSourceContext .FETCH_SOURCE ;
476+ case 1 -> FetchSourceContext .FETCH_ALL_SOURCE ;
477+ case 2 -> FetchSourceContext .FETCH_ALL_SOURCE_EXCLUDE_INFERENCE_FIELDS ;
478+ case 3 -> FetchSourceContext .DO_NOT_FETCH_SOURCE ;
479+ case 4 -> null ;
480+ default -> throw new IllegalStateException ("Unhandled randomized case" );
481+ };
482+
483+ if (fetchSourceContext != null && fetchSourceContext .fetchSource ()) {
484+ String [] includes = null ;
485+ String [] excludes = null ;
486+ if (randomBoolean ()) {
487+ // Randomly include a non-existent field to test explicit inclusion handling
488+ String field = randomBoolean () ? InferenceMetadataFieldsMapper .NAME : randomIdentifier ();
489+ includes = new String [] { field };
490+ }
491+ if (randomBoolean ()) {
492+ // Randomly exclude a non-existent field to test implicit inclusion handling
493+ String field = randomBoolean () ? InferenceMetadataFieldsMapper .NAME : randomIdentifier ();
494+ excludes = new String [] { field };
495+ }
496+
497+ if (includes != null || excludes != null ) {
498+ fetchSourceContext = FetchSourceContext .of (
499+ fetchSourceContext .fetchSource (),
500+ fetchSourceContext .excludeVectors (),
501+ fetchSourceContext .excludeInferenceFields (),
502+ includes ,
503+ excludes
504+ );
505+ }
506+ }
507+
508+ return fetchSourceContext ;
509+ }
510+ }
428511}
0 commit comments