@@ -773,7 +773,7 @@ static class WildcardMatchingQuery extends Query {
773773 private final Query firstPhaseQuery ;
774774 private final Predicate <String > secondPhaseMatcher ;
775775 private final String patternString ; // For toString
776- private final ValueFetcher valueFetcher ;
776+ private final Supplier < ValueFetcher > valueFetcherSupplier ;
777777 private final SearchLookup searchLookup ;
778778
779779 WildcardMatchingQuery (String fieldName , Query firstPhaseQuery , String patternString ) {
@@ -794,10 +794,10 @@ public WildcardMatchingQuery(
794794 this .patternString = Objects .requireNonNull (patternString );
795795 if (context != null ) {
796796 this .searchLookup = context .lookup ();
797- this .valueFetcher = fieldType .valueFetcher (context , context .lookup (), null );
797+ this .valueFetcherSupplier = () -> fieldType .valueFetcher (context , context .lookup (), null );
798798 } else {
799799 this .searchLookup = null ;
800- this .valueFetcher = null ;
800+ this .valueFetcherSupplier = null ;
801801 }
802802 }
803803
@@ -806,14 +806,14 @@ private WildcardMatchingQuery(
806806 Query firstPhaseQuery ,
807807 Predicate <String > secondPhaseMatcher ,
808808 String patternString ,
809- ValueFetcher valueFetcher ,
809+ Supplier < ValueFetcher > valueFetcherSupplier ,
810810 SearchLookup searchLookup
811811 ) {
812812 this .fieldName = fieldName ;
813813 this .firstPhaseQuery = firstPhaseQuery ;
814814 this .secondPhaseMatcher = secondPhaseMatcher ;
815815 this .patternString = patternString ;
816- this .valueFetcher = valueFetcher ;
816+ this .valueFetcherSupplier = valueFetcherSupplier ;
817817 this .searchLookup = searchLookup ;
818818 }
819819
@@ -851,7 +851,7 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
851851 rewriteFirstPhase ,
852852 secondPhaseMatcher ,
853853 patternString ,
854- valueFetcher ,
854+ valueFetcherSupplier ,
855855 searchLookup
856856 );
857857 }
@@ -884,6 +884,9 @@ public Scorer get(long leadCost) throws IOException {
884884 Scorer approximateScorer = firstPhaseSupplier .get (leadCost );
885885 DocIdSetIterator approximation = approximateScorer .iterator ();
886886 LeafSearchLookup leafSearchLookup = searchLookup .getLeafSearchLookup (context );
887+ // Create a new ValueFetcher per thread.
888+ // ValueFetcher.setNextReader is not thread safe.
889+ final ValueFetcher valueFetcher = valueFetcherSupplier .get ();
887890 valueFetcher .setNextReader (context );
888891
889892 TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator (approximation ) {
0 commit comments