@@ -743,7 +743,7 @@ static class WildcardMatchingQuery extends Query {
743743 private final Query firstPhaseQuery ;
744744 private final Predicate <String > secondPhaseMatcher ;
745745 private final String patternString ; // For toString
746- private final ValueFetcher valueFetcher ;
746+ private final Supplier < ValueFetcher > valueFetcherSupplier ;
747747 private final SearchLookup searchLookup ;
748748
749749 WildcardMatchingQuery (String fieldName , Query firstPhaseQuery , String patternString ) {
@@ -764,10 +764,10 @@ public WildcardMatchingQuery(
764764 this .patternString = Objects .requireNonNull (patternString );
765765 if (context != null ) {
766766 this .searchLookup = context .lookup ();
767- this .valueFetcher = fieldType .valueFetcher (context , context .lookup (), null );
767+ this .valueFetcherSupplier = () -> fieldType .valueFetcher (context , context .lookup (), null );
768768 } else {
769769 this .searchLookup = null ;
770- this .valueFetcher = null ;
770+ this .valueFetcherSupplier = null ;
771771 }
772772 }
773773
@@ -776,14 +776,14 @@ private WildcardMatchingQuery(
776776 Query firstPhaseQuery ,
777777 Predicate <String > secondPhaseMatcher ,
778778 String patternString ,
779- ValueFetcher valueFetcher ,
779+ Supplier < ValueFetcher > valueFetcherSupplier ,
780780 SearchLookup searchLookup
781781 ) {
782782 this .fieldName = fieldName ;
783783 this .firstPhaseQuery = firstPhaseQuery ;
784784 this .secondPhaseMatcher = secondPhaseMatcher ;
785785 this .patternString = patternString ;
786- this .valueFetcher = valueFetcher ;
786+ this .valueFetcherSupplier = valueFetcherSupplier ;
787787 this .searchLookup = searchLookup ;
788788 }
789789
@@ -821,7 +821,7 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
821821 rewriteFirstPhase ,
822822 secondPhaseMatcher ,
823823 patternString ,
824- valueFetcher ,
824+ valueFetcherSupplier ,
825825 searchLookup
826826 );
827827 }
@@ -844,6 +844,9 @@ public Scorer get(long leadCost) throws IOException {
844844 Scorer approximateScorer = firstPhaseSupplier .get (leadCost );
845845 DocIdSetIterator approximation = approximateScorer .iterator ();
846846 LeafSearchLookup leafSearchLookup = searchLookup .getLeafSearchLookup (context );
847+ // Create a new ValueFetcher per thread.
848+ // ValueFetcher.setNextReader is not thread safe.
849+ final ValueFetcher valueFetcher = valueFetcherSupplier .get ();
847850 valueFetcher .setNextReader (context );
848851
849852 TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator (approximation ) {
0 commit comments