3939 */ 
4040public  abstract  class  QueryList  {
4141    protected  final  Block  block ;
42+     protected  final  boolean  onlySingleValues ;
4243
43-     protected  QueryList (Block  block ) {
44+     protected  QueryList (Block  block ,  boolean   onlySingleValues ) {
4445        this .block  = block ;
46+         this .onlySingleValues  = onlySingleValues ;
4547    }
4648
4749    /** 
@@ -51,6 +53,12 @@ int getPositionCount() {
5153        return  block .getPositionCount ();
5254    }
5355
56+     /** 
57+      * Returns a copy of this query list that only returns queries for single-valued positions. 
58+      * That is, it returns `null` queries for either multivalued or null positions. 
59+      */ 
60+     public  abstract  QueryList  onlySingleValues ();
61+ 
5462    /** 
5563     * Returns the query at the given position. 
5664     */ 
@@ -93,7 +101,7 @@ public static QueryList rawTermQueryList(MappedFieldType field, SearchExecutionC
93101            case  COMPOSITE  -> throw  new  IllegalArgumentException ("can't read values from [composite] block" );
94102            case  UNKNOWN  -> throw  new  IllegalArgumentException ("can't read values from ["  + block  + "]" );
95103        };
96-         return  new  TermQueryList (field , searchExecutionContext , block , blockToJavaObject );
104+         return  new  TermQueryList (field , searchExecutionContext , block , false ,  blockToJavaObject );
97105    }
98106
99107    /** 
@@ -103,7 +111,7 @@ public static QueryList rawTermQueryList(MappedFieldType field, SearchExecutionC
103111    public  static  QueryList  ipTermQueryList (MappedFieldType  field , SearchExecutionContext  searchExecutionContext , BytesRefBlock  block ) {
104112        BytesRef  scratch  = new  BytesRef ();
105113        byte [] ipBytes  = new  byte [InetAddressPoint .BYTES ];
106-         return  new  TermQueryList (field , searchExecutionContext , block , offset  -> {
114+         return  new  TermQueryList (field , searchExecutionContext , block , false ,  offset  -> {
107115            final  var  bytes  = block .getBytesRef (offset , scratch );
108116            if  (ipBytes .length  != bytes .length ) {
109117                // Lucene only support 16-byte IP addresses, even IPv4 is encoded in 16 bytes 
@@ -123,6 +131,7 @@ public static QueryList dateTermQueryList(MappedFieldType field, SearchExecution
123131            field ,
124132            searchExecutionContext ,
125133            block ,
134+             false ,
126135            field  instanceof  RangeFieldMapper .RangeFieldType  rangeFieldType 
127136                ? offset  -> rangeFieldType .dateTimeFormatter ().formatMillis (block .getLong (offset ))
128137                : block ::getLong 
@@ -133,7 +142,7 @@ public static QueryList dateTermQueryList(MappedFieldType field, SearchExecution
133142     * Returns a list of geo_shape queries for the given field and the input block. 
134143     */ 
135144    public  static  QueryList  geoShapeQueryList (MappedFieldType  field , SearchExecutionContext  searchExecutionContext , Block  block ) {
136-         return  new  GeoShapeQueryList (field , searchExecutionContext , block );
145+         return  new  GeoShapeQueryList (field , searchExecutionContext , block ,  false );
137146    }
138147
139148    private  static  class  TermQueryList  extends  QueryList  {
@@ -145,18 +154,27 @@ private TermQueryList(
145154            MappedFieldType  field ,
146155            SearchExecutionContext  searchExecutionContext ,
147156            Block  block ,
157+             boolean  onlySingleValues ,
148158            IntFunction <Object > blockValueReader 
149159        ) {
150-             super (block );
160+             super (block ,  onlySingleValues );
151161            this .field  = field ;
152162            this .searchExecutionContext  = searchExecutionContext ;
153163            this .blockValueReader  = blockValueReader ;
154164        }
155165
166+         @ Override 
167+         public  TermQueryList  onlySingleValues () {
168+             return  new  TermQueryList (field , searchExecutionContext , block , true , blockValueReader );
169+         }
170+ 
156171        @ Override 
157172        Query  getQuery (int  position ) {
158-             final  int  first  = block .getFirstValueIndex (position );
159173            final  int  count  = block .getValueCount (position );
174+             if  (onlySingleValues  && count  != 1 ) {
175+                 return  null ;
176+             }
177+             final  int  first  = block .getFirstValueIndex (position );
160178            return  switch  (count ) {
161179                case  0  -> null ;
162180                case  1  -> field .termQuery (blockValueReader .apply (first ), searchExecutionContext );
@@ -179,19 +197,32 @@ private static class GeoShapeQueryList extends QueryList {
179197        private  final  IntFunction <Geometry > blockValueReader ;
180198        private  final  IntFunction <Query > shapeQuery ;
181199
182-         private  GeoShapeQueryList (MappedFieldType  field , SearchExecutionContext  searchExecutionContext , Block  block ) {
183-             super (block );
200+         private  GeoShapeQueryList (
201+             MappedFieldType  field ,
202+             SearchExecutionContext  searchExecutionContext ,
203+             Block  block ,
204+             boolean  onlySingleValues 
205+         ) {
206+             super (block , onlySingleValues );
184207
185208            this .field  = field ;
186209            this .searchExecutionContext  = searchExecutionContext ;
187210            this .blockValueReader  = blockToGeometry (block );
188211            this .shapeQuery  = shapeQuery ();
189212        }
190213
214+         @ Override 
215+         public  GeoShapeQueryList  onlySingleValues () {
216+             return  new  GeoShapeQueryList (field , searchExecutionContext , block , true );
217+         }
218+ 
191219        @ Override 
192220        Query  getQuery (int  position ) {
193-             final  int  first  = block .getFirstValueIndex (position );
194221            final  int  count  = block .getValueCount (position );
222+             if  (onlySingleValues  && count  != 1 ) {
223+                 return  null ;
224+             }
225+             final  int  first  = block .getFirstValueIndex (position );
195226            return  switch  (count ) {
196227                case  0  -> null ;
197228                case  1  -> shapeQuery .apply (first );
0 commit comments