Browse Source

Add flag for how multivalued fields are sorted (ESQL-1109)

This adds the a flag to the `Block` interface to communicate how
multivalued fields are sorted. It defaults to `UNORDERED` and our block
do values loaders can set it to `ASCENDING`. We can use that for
multivalue functions and groupings.
Nik Everett 2 years ago
parent
commit
99e3c71736
25 changed files with 434 additions and 75 deletions
  1. 11 4
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BooleanArrayBlock.java
  2. 12 1
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BooleanBlockBuilder.java
  3. 11 4
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BytesRefArrayBlock.java
  4. 12 1
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BytesRefBlockBuilder.java
  5. 11 4
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/DoubleArrayBlock.java
  6. 12 1
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/DoubleBlockBuilder.java
  7. 11 4
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/IntArrayBlock.java
  8. 12 1
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/IntBlockBuilder.java
  9. 11 4
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/LongArrayBlock.java
  10. 12 1
      x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/LongBlockBuilder.java
  11. 38 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractArrayBlock.java
  12. 2 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractBlockBuilder.java
  13. 5 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractFilterBlock.java
  14. 5 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractVectorBlock.java
  15. 15 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/Block.java
  16. 5 0
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java
  17. 16 7
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/X-ArrayBlock.java.st
  18. 12 1
      x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/X-BlockBuilder.java.st
  19. 21 5
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BasicBlockTests.java
  20. 37 6
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BooleanBlockEqualityTests.java
  21. 42 6
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BytesRefBlockEqualityTests.java
  22. 42 6
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/DoubleBlockEqualityTests.java
  23. 13 7
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/FilteredBlockTests.java
  24. 30 6
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/IntBlockEqualityTests.java
  25. 36 6
      x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/LongBlockEqualityTests.java

+ 11 - 4
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BooleanArrayBlock.java

@@ -14,12 +14,12 @@ import java.util.BitSet;
  * Block implementation that stores an array of boolean.
  * This class is generated. Do not edit it.
  */
-public final class BooleanArrayBlock extends AbstractBlock implements BooleanBlock {
+public final class BooleanArrayBlock extends AbstractArrayBlock implements BooleanBlock {
 
     private final boolean[] values;
 
-    public BooleanArrayBlock(boolean[] values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
-        super(positionCount, firstValueIndexes, nulls);
+    public BooleanArrayBlock(boolean[] values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -58,6 +58,13 @@ public final class BooleanArrayBlock extends AbstractBlock implements BooleanBlo
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ", values=" + Arrays.toString(values) + ']';
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
+            + ", values="
+            + Arrays.toString(values)
+            + ']';
     }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BooleanBlockBuilder.java

@@ -113,6 +113,17 @@ final class BooleanBlockBuilder extends AbstractBlockBuilder implements BooleanB
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public BooleanBlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public BooleanBlock build() {
         finish();
@@ -125,7 +136,7 @@ final class BooleanBlockBuilder extends AbstractBlockBuilder implements BooleanB
             if (isDense() && singleValued()) {
                 return new BooleanArrayVector(values, positionCount).asBlock();
             } else {
-                return new BooleanArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new BooleanArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 11 - 4
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BytesRefArrayBlock.java

@@ -16,12 +16,12 @@ import java.util.BitSet;
  * Block implementation that stores an array of BytesRef.
  * This class is generated. Do not edit it.
  */
-public final class BytesRefArrayBlock extends AbstractBlock implements BytesRefBlock {
+public final class BytesRefArrayBlock extends AbstractArrayBlock implements BytesRefBlock {
 
     private final BytesRefArray values;
 
-    public BytesRefArrayBlock(BytesRefArray values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
-        super(positionCount, firstValueIndexes, nulls);
+    public BytesRefArrayBlock(BytesRefArray values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -60,6 +60,13 @@ public final class BytesRefArrayBlock extends AbstractBlock implements BytesRefB
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ']';
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
+            + ", values="
+            + values.size()
+            + ']';
     }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BytesRefBlockBuilder.java

@@ -128,6 +128,17 @@ final class BytesRefBlockBuilder extends AbstractBlockBuilder implements BytesRe
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public BytesRefBlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public BytesRefBlock build() {
         finish();
@@ -137,7 +148,7 @@ final class BytesRefBlockBuilder extends AbstractBlockBuilder implements BytesRe
             if (isDense() && singleValued()) {
                 return new BytesRefArrayVector(values, positionCount).asBlock();
             } else {
-                return new BytesRefArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new BytesRefArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 11 - 4
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/DoubleArrayBlock.java

@@ -14,12 +14,12 @@ import java.util.BitSet;
  * Block implementation that stores an array of double.
  * This class is generated. Do not edit it.
  */
-public final class DoubleArrayBlock extends AbstractBlock implements DoubleBlock {
+public final class DoubleArrayBlock extends AbstractArrayBlock implements DoubleBlock {
 
     private final double[] values;
 
-    public DoubleArrayBlock(double[] values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
-        super(positionCount, firstValueIndexes, nulls);
+    public DoubleArrayBlock(double[] values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -58,6 +58,13 @@ public final class DoubleArrayBlock extends AbstractBlock implements DoubleBlock
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ", values=" + Arrays.toString(values) + ']';
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
+            + ", values="
+            + Arrays.toString(values)
+            + ']';
     }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/DoubleBlockBuilder.java

@@ -113,6 +113,17 @@ final class DoubleBlockBuilder extends AbstractBlockBuilder implements DoubleBlo
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public DoubleBlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public DoubleBlock build() {
         finish();
@@ -125,7 +136,7 @@ final class DoubleBlockBuilder extends AbstractBlockBuilder implements DoubleBlo
             if (isDense() && singleValued()) {
                 return new DoubleArrayVector(values, positionCount).asBlock();
             } else {
-                return new DoubleArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new DoubleArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 11 - 4
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/IntArrayBlock.java

@@ -14,12 +14,12 @@ import java.util.BitSet;
  * Block implementation that stores an array of int.
  * This class is generated. Do not edit it.
  */
-public final class IntArrayBlock extends AbstractBlock implements IntBlock {
+public final class IntArrayBlock extends AbstractArrayBlock implements IntBlock {
 
     private final int[] values;
 
-    public IntArrayBlock(int[] values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
-        super(positionCount, firstValueIndexes, nulls);
+    public IntArrayBlock(int[] values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -58,6 +58,13 @@ public final class IntArrayBlock extends AbstractBlock implements IntBlock {
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ", values=" + Arrays.toString(values) + ']';
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
+            + ", values="
+            + Arrays.toString(values)
+            + ']';
     }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/IntBlockBuilder.java

@@ -113,6 +113,17 @@ final class IntBlockBuilder extends AbstractBlockBuilder implements IntBlock.Bui
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public IntBlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public IntBlock build() {
         finish();
@@ -125,7 +136,7 @@ final class IntBlockBuilder extends AbstractBlockBuilder implements IntBlock.Bui
             if (isDense() && singleValued()) {
                 return new IntArrayVector(values, positionCount).asBlock();
             } else {
-                return new IntArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new IntArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 11 - 4
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/LongArrayBlock.java

@@ -14,12 +14,12 @@ import java.util.BitSet;
  * Block implementation that stores an array of long.
  * This class is generated. Do not edit it.
  */
-public final class LongArrayBlock extends AbstractBlock implements LongBlock {
+public final class LongArrayBlock extends AbstractArrayBlock implements LongBlock {
 
     private final long[] values;
 
-    public LongArrayBlock(long[] values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
-        super(positionCount, firstValueIndexes, nulls);
+    public LongArrayBlock(long[] values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -58,6 +58,13 @@ public final class LongArrayBlock extends AbstractBlock implements LongBlock {
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ", values=" + Arrays.toString(values) + ']';
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
+            + ", values="
+            + Arrays.toString(values)
+            + ']';
     }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/data/LongBlockBuilder.java

@@ -113,6 +113,17 @@ final class LongBlockBuilder extends AbstractBlockBuilder implements LongBlock.B
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public LongBlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public LongBlock build() {
         finish();
@@ -125,7 +136,7 @@ final class LongBlockBuilder extends AbstractBlockBuilder implements LongBlock.B
             if (isDense() && singleValued()) {
                 return new LongArrayVector(values, positionCount).asBlock();
             } else {
-                return new LongArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new LongArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 38 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractArrayBlock.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.compute.data;
+
+import org.elasticsearch.core.Nullable;
+
+import java.util.BitSet;
+
+abstract class AbstractArrayBlock extends AbstractBlock {
+
+    private final MvOrdering mvOrdering;
+
+    /**
+     * @param positionCount the number of values in this block
+     */
+    protected AbstractArrayBlock(int positionCount, MvOrdering mvOrdering) {
+        super(positionCount);
+        this.mvOrdering = mvOrdering;
+    }
+
+    /**
+     * @param positionCount the number of values in this block
+     */
+    protected AbstractArrayBlock(int positionCount, @Nullable int[] firstValueIndexes, @Nullable BitSet nullsMask, MvOrdering mvOrdering) {
+        super(positionCount, firstValueIndexes, nullsMask);
+        this.mvOrdering = mvOrdering;
+    }
+
+    @Override
+    public final MvOrdering mvOrdering() {
+        return mvOrdering;
+    }
+}

+ 2 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractBlockBuilder.java

@@ -25,6 +25,8 @@ abstract class AbstractBlockBuilder {
 
     protected boolean hasNonNullValue;
 
+    protected Block.MvOrdering mvOrdering = Block.MvOrdering.UNORDERED;
+
     protected AbstractBlockBuilder() {}
 
     public AbstractBlockBuilder appendNull() {

+ 5 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractFilterBlock.java

@@ -86,6 +86,11 @@ abstract class AbstractFilterBlock implements Block {
         return block.getFirstValueIndex(mapPosition(position));
     }
 
+    @Override
+    public MvOrdering mvOrdering() {
+        return block.mvOrdering();
+    }
+
     private int mapPosition(int position) {
         assert assertPosition(position);
         return positions[position];

+ 5 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/AbstractVectorBlock.java

@@ -44,4 +44,9 @@ abstract class AbstractVectorBlock extends AbstractBlock {
     public boolean areAllValuesNull() {
         return false;
     }
+
+    @Override
+    public final MvOrdering mvOrdering() {
+        return MvOrdering.UNORDERED;
+    }
 }

+ 15 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/Block.java

@@ -86,6 +86,21 @@ public interface Block extends NamedWriteable {
      */
     Block filter(int... positions);
 
+    /**
+     * How are multivalued fields ordered?
+     * <p>Note that there isn't a {@code DESCENDING} because we don't have
+     * anything that makes descending fields.</p>
+     */
+    enum MvOrdering {
+        ASCENDING,
+        UNORDERED;
+    }
+
+    /**
+     * How are multivalued fields ordered?
+     */
+    MvOrdering mvOrdering();
+
     /**
      * {@return a constant null block with the given number of positions}.
      */

+ 5 - 0
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java

@@ -78,6 +78,11 @@ public final class ConstantNullBlock extends AbstractBlock {
         out.writeVInt(getPositionCount());
     }
 
+    @Override
+    public MvOrdering mvOrdering() {
+        return MvOrdering.UNORDERED;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof ConstantNullBlock that) {

+ 16 - 7
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/X-ArrayBlock.java.st

@@ -20,7 +20,7 @@ import java.util.BitSet;
  * Block implementation that stores an array of $type$.
  * This class is generated. Do not edit it.
  */
-public final class $Type$ArrayBlock extends AbstractBlock implements $Type$Block {
+public final class $Type$ArrayBlock extends AbstractArrayBlock implements $Type$Block {
 
 $if(BytesRef)$
     private final BytesRefArray values;
@@ -30,11 +30,11 @@ $else$
 $endif$
 
 $if(BytesRef)$
-    public $Type$ArrayBlock(BytesRefArray values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
+    public $Type$ArrayBlock(BytesRefArray values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
 $else$
-    public $Type$ArrayBlock($type$[] values, int positionCount, int[] firstValueIndexes, BitSet nulls) {
+    public $Type$ArrayBlock($type$[] values, int positionCount, int[] firstValueIndexes, BitSet nulls, MvOrdering mvOrdering) {
 $endif$
-        super(positionCount, firstValueIndexes, nulls);
+        super(positionCount, firstValueIndexes, nulls, mvOrdering);
         this.values = values;
     }
 
@@ -78,9 +78,18 @@ $endif$
 
     @Override
     public String toString() {
+        return getClass().getSimpleName()
+            + "[positions="
+            + getPositionCount()
+            + ", mvOrdering="
+            + mvOrdering()
 $if(BytesRef)$
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ']';
+            + ", values="
+            + values.size()
 $else$
-        return getClass().getSimpleName() + "[positions=" + getPositionCount() + ", values=" + Arrays.toString(values) + ']';
-$endif$    }
+            + ", values="
+            + Arrays.toString(values)
+$endif$
+            + ']';
+    }
 }

+ 12 - 1
x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/X-BlockBuilder.java.st

@@ -168,6 +168,17 @@ $endif$
         }
     }
 
+    /**
+     * How are multivalued fields ordered? This defaults to {@link Block.MvOrdering#UNORDERED}
+     * and operators can use it to optimize themselves. This order isn't checked so don't
+     * set it to anything other than {@link Block.MvOrdering#UNORDERED} unless you are sure
+     * of the ordering.
+     */
+    public $Type$BlockBuilder mvOrdering(Block.MvOrdering mvOrdering) {
+        this.mvOrdering = mvOrdering;
+        return this;
+    }
+
     @Override
     public $Type$Block build() {
         finish();
@@ -185,7 +196,7 @@ $endif$
             if (isDense() && singleValued()) {
                 return new $Type$ArrayVector(values, positionCount).asBlock();
             } else {
-                return new $Type$ArrayBlock(values, positionCount, firstValueIndexes, nullsMask);
+                return new $Type$ArrayBlock(values, positionCount, firstValueIndexes, nullsMask, mvOrdering);
             }
         }
     }

+ 21 - 5
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BasicBlockTests.java

@@ -28,28 +28,44 @@ import static org.hamcrest.Matchers.is;
 public class BasicBlockTests extends ESTestCase {
 
     public void testEmpty() {
-        assertThat(new IntArrayBlock(new int[] {}, 0, new int[] {}, new BitSet()).getPositionCount(), is(0));
+        assertThat(
+            new IntArrayBlock(new int[] {}, 0, new int[] {}, new BitSet(), randomFrom(Block.MvOrdering.values())).getPositionCount(),
+            is(0)
+        );
         assertThat(IntBlock.newBlockBuilder(0).build().getPositionCount(), is(0));
         assertThat(new IntArrayVector(new int[] {}, 0).getPositionCount(), is(0));
         assertThat(IntVector.newVectorBuilder(0).build().getPositionCount(), is(0));
 
-        assertThat(new LongArrayBlock(new long[] {}, 0, new int[] {}, new BitSet()).getPositionCount(), is(0));
+        assertThat(
+            new LongArrayBlock(new long[] {}, 0, new int[] {}, new BitSet(), randomFrom(Block.MvOrdering.values())).getPositionCount(),
+            is(0)
+        );
         assertThat(LongBlock.newBlockBuilder(0).build().getPositionCount(), is(0));
         assertThat(new LongArrayVector(new long[] {}, 0).getPositionCount(), is(0));
         assertThat(LongVector.newVectorBuilder(0).build().getPositionCount(), is(0));
 
-        assertThat(new DoubleArrayBlock(new double[] {}, 0, new int[] {}, new BitSet()).getPositionCount(), is(0));
+        assertThat(
+            new DoubleArrayBlock(new double[] {}, 0, new int[] {}, new BitSet(), randomFrom(Block.MvOrdering.values())).getPositionCount(),
+            is(0)
+        );
         assertThat(DoubleBlock.newBlockBuilder(0).build().getPositionCount(), is(0));
         assertThat(new DoubleArrayVector(new double[] {}, 0).getPositionCount(), is(0));
         assertThat(DoubleVector.newVectorBuilder(0).build().getPositionCount(), is(0));
 
         var emptyArray = new BytesRefArray(0, BigArrays.NON_RECYCLING_INSTANCE);
-        assertThat(new BytesRefArrayBlock(emptyArray, 0, new int[] {}, new BitSet()).getPositionCount(), is(0));
+        assertThat(
+            new BytesRefArrayBlock(emptyArray, 0, new int[] {}, new BitSet(), randomFrom(Block.MvOrdering.values())).getPositionCount(),
+            is(0)
+        );
         assertThat(BytesRefBlock.newBlockBuilder(0).build().getPositionCount(), is(0));
         assertThat(new BytesRefArrayVector(emptyArray, 0).getPositionCount(), is(0));
         assertThat(BytesRefVector.newVectorBuilder(0).build().getPositionCount(), is(0));
 
-        assertThat(new BooleanArrayBlock(new boolean[] {}, 0, new int[] {}, new BitSet()).getPositionCount(), is(0));
+        assertThat(
+            new BooleanArrayBlock(new boolean[] {}, 0, new int[] {}, new BitSet(), randomFrom(Block.MvOrdering.values()))
+                .getPositionCount(),
+            is(0)
+        );
         assertThat(BooleanBlock.newBlockBuilder(0).build().getPositionCount(), is(0));
         assertThat(new BooleanArrayVector(new boolean[] {}, 0).getPositionCount(), is(0));
         assertThat(BooleanVector.newVectorBuilder(0).build().getPositionCount(), is(0));

+ 37 - 6
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BooleanBlockEqualityTests.java

@@ -30,8 +30,20 @@ public class BooleanBlockEqualityTests extends ESTestCase {
     public void testEmptyBlock() {
         // all these "empty" vectors should be equivalent
         List<BooleanBlock> blocks = List.of(
-            new BooleanArrayBlock(new boolean[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
-            new BooleanArrayBlock(new boolean[] { randomBoolean() }, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
+            new BooleanArrayBlock(
+                new boolean[] {},
+                0,
+                new int[] {},
+                BitSet.valueOf(new byte[] { 0b00 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new BooleanArrayBlock(
+                new boolean[] { randomBoolean() },
+                0,
+                new int[] {},
+                BitSet.valueOf(new byte[] { 0b00 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             BooleanBlock.newConstantBlockWith(randomBoolean(), 0),
             BooleanBlock.newBlockBuilder(0).build(),
             BooleanBlock.newBlockBuilder(0).appendBoolean(randomBoolean()).build().filter(),
@@ -107,12 +119,19 @@ public class BooleanBlockEqualityTests extends ESTestCase {
         // all these blocks should be equivalent
         List<BooleanBlock> blocks = List.of(
             new BooleanArrayVector(new boolean[] { true, false, true }, 3).asBlock(),
-            new BooleanArrayBlock(new boolean[] { true, false, true }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b000 })),
+            new BooleanArrayBlock(
+                new boolean[] { true, false, true },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new BooleanArrayBlock(
                 new boolean[] { true, false, true, false },
                 3,
                 new int[] { 0, 1, 2, 3 },
-                BitSet.valueOf(new byte[] { 0b1000 })
+                BitSet.valueOf(new byte[] { 0b1000 }),
+                randomFrom(Block.MvOrdering.values())
             ),
             new BooleanArrayVector(new boolean[] { true, false, true }, 3).filter(0, 1, 2).asBlock(),
             new BooleanArrayVector(new boolean[] { true, false, true, false }, 3).filter(0, 1, 2).asBlock(),
@@ -140,8 +159,20 @@ public class BooleanBlockEqualityTests extends ESTestCase {
         // all these constant-like blocks should be equivalent
         List<BooleanBlock> moreBlocks = List.of(
             new BooleanArrayVector(new boolean[] { true, true }, 2).asBlock(),
-            new BooleanArrayBlock(new boolean[] { true, true }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new BooleanArrayBlock(new boolean[] { true, true, false }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b100 })),
+            new BooleanArrayBlock(
+                new boolean[] { true, true },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new BooleanArrayBlock(
+                new boolean[] { true, true, false },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b100 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new BooleanArrayVector(new boolean[] { true, true }, 2).filter(0, 1).asBlock(),
             new BooleanArrayVector(new boolean[] { true, true, false }, 2).filter(0, 1).asBlock(),
             new BooleanArrayVector(new boolean[] { true, true, false }, 3).filter(0, 1).asBlock(),

+ 42 - 6
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/BytesRefBlockEqualityTests.java

@@ -43,8 +43,20 @@ public class BytesRefBlockEqualityTests extends ESTestCase {
         // all these "empty" vectors should be equivalent
         try (var bytesRefArray1 = new BytesRefArray(0, bigArrays); var bytesRefArray2 = new BytesRefArray(1, bigArrays)) {
             List<BytesRefBlock> blocks = List.of(
-                new BytesRefArrayBlock(bytesRefArray1, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
-                new BytesRefArrayBlock(bytesRefArray2, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
+                new BytesRefArrayBlock(
+                    bytesRefArray1,
+                    0,
+                    new int[] {},
+                    BitSet.valueOf(new byte[] { 0b00 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
+                new BytesRefArrayBlock(
+                    bytesRefArray2,
+                    0,
+                    new int[] {},
+                    BitSet.valueOf(new byte[] { 0b00 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
                 BytesRefBlock.newConstantBlockWith(new BytesRef(), 0),
                 BytesRefBlock.newBlockBuilder(0).build(),
                 BytesRefBlock.newBlockBuilder(0).appendBytesRef(new BytesRef()).build().filter(),
@@ -144,8 +156,20 @@ public class BytesRefBlockEqualityTests extends ESTestCase {
         try (var bytesRefArray1 = arrayOf("1", "2", "3"); var bytesRefArray2 = arrayOf("1", "2", "3", "4")) {
             List<BytesRefBlock> blocks = List.of(
                 new BytesRefArrayVector(bytesRefArray1, 3).asBlock(),
-                new BytesRefArrayBlock(bytesRefArray1, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b000 })),
-                new BytesRefArrayBlock(bytesRefArray2, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b1000 })),
+                new BytesRefArrayBlock(
+                    bytesRefArray1,
+                    3,
+                    new int[] { 0, 1, 2, 3 },
+                    BitSet.valueOf(new byte[] { 0b000 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
+                new BytesRefArrayBlock(
+                    bytesRefArray2,
+                    3,
+                    new int[] { 0, 1, 2, 3 },
+                    BitSet.valueOf(new byte[] { 0b1000 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
                 new BytesRefArrayVector(bytesRefArray1, 3).filter(0, 1, 2).asBlock(),
                 new BytesRefArrayVector(bytesRefArray2, 3).filter(0, 1, 2).asBlock(),
                 new BytesRefArrayVector(bytesRefArray2, 4).filter(0, 1, 2).asBlock(),
@@ -182,8 +206,20 @@ public class BytesRefBlockEqualityTests extends ESTestCase {
         try (var bytesRefArray1 = arrayOf("9", "9"); var bytesRefArray2 = arrayOf("9", "9", "4")) {
             List<BytesRefBlock> moreBlocks = List.of(
                 new BytesRefArrayVector(bytesRefArray1, 2).asBlock(),
-                new BytesRefArrayBlock(bytesRefArray1, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b000 })),
-                new BytesRefArrayBlock(bytesRefArray2, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b100 })),
+                new BytesRefArrayBlock(
+                    bytesRefArray1,
+                    2,
+                    new int[] { 0, 1, 2 },
+                    BitSet.valueOf(new byte[] { 0b000 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
+                new BytesRefArrayBlock(
+                    bytesRefArray2,
+                    2,
+                    new int[] { 0, 1, 2 },
+                    BitSet.valueOf(new byte[] { 0b100 }),
+                    randomFrom(Block.MvOrdering.values())
+                ),
                 new BytesRefArrayVector(bytesRefArray1, 2).filter(0, 1).asBlock(),
                 new BytesRefArrayVector(bytesRefArray2, 2).filter(0, 1).asBlock(),
                 new BytesRefArrayVector(bytesRefArray2, 3).filter(0, 1).asBlock(),

+ 42 - 6
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/DoubleBlockEqualityTests.java

@@ -31,8 +31,20 @@ public class DoubleBlockEqualityTests extends ESTestCase {
     public void testEmptyBlock() {
         // all these "empty" vectors should be equivalent
         List<DoubleBlock> blocks = List.of(
-            new DoubleArrayBlock(new double[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
-            new DoubleArrayBlock(new double[] { 0 }, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
+            new DoubleArrayBlock(
+                new double[] {},
+                0,
+                new int[] {},
+                BitSet.valueOf(new byte[] { 0b00 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new DoubleArrayBlock(
+                new double[] { 0 },
+                0,
+                new int[] {},
+                BitSet.valueOf(new byte[] { 0b00 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             DoubleBlock.newConstantBlockWith(0, 0),
             DoubleBlock.newBlockBuilder(0).build(),
             DoubleBlock.newBlockBuilder(0).appendDouble(1).build().filter(),
@@ -108,8 +120,20 @@ public class DoubleBlockEqualityTests extends ESTestCase {
         // all these blocks should be equivalent
         List<DoubleBlock> blocks = List.of(
             new DoubleArrayVector(new double[] { 1, 2, 3 }, 3).asBlock(),
-            new DoubleArrayBlock(new double[] { 1, 2, 3 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new DoubleArrayBlock(new double[] { 1, 2, 3, 4 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b1000 })),
+            new DoubleArrayBlock(
+                new double[] { 1, 2, 3 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new DoubleArrayBlock(
+                new double[] { 1, 2, 3, 4 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b1000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new DoubleArrayVector(new double[] { 1, 2, 3 }, 3).filter(0, 1, 2).asBlock(),
             new DoubleArrayVector(new double[] { 1, 2, 3, 4 }, 3).filter(0, 1, 2).asBlock(),
             new DoubleArrayVector(new double[] { 1, 2, 3, 4 }, 4).filter(0, 1, 2).asBlock(),
@@ -124,8 +148,20 @@ public class DoubleBlockEqualityTests extends ESTestCase {
         // all these constant-like blocks should be equivalent
         List<DoubleBlock> moreBlocks = List.of(
             new DoubleArrayVector(new double[] { 9, 9 }, 2).asBlock(),
-            new DoubleArrayBlock(new double[] { 9, 9 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new DoubleArrayBlock(new double[] { 9, 9, 4 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b100 })),
+            new DoubleArrayBlock(
+                new double[] { 9, 9 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new DoubleArrayBlock(
+                new double[] { 9, 9, 4 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b100 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new DoubleArrayVector(new double[] { 9, 9 }, 2).filter(0, 1).asBlock(),
             new DoubleArrayVector(new double[] { 9, 9, 4 }, 2).filter(0, 1).asBlock(),
             new DoubleArrayVector(new double[] { 9, 9, 4 }, 3).filter(0, 1).asBlock(),

+ 13 - 7
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/FilteredBlockTests.java

@@ -85,7 +85,7 @@ public class FilteredBlockTests extends ESTestCase {
         if (randomBoolean()) {
             var nulls = new BitSet();
             nulls.set(1);
-            block = new IntArrayBlock(new int[] { 10, 0, 30, 40 }, 4, null, nulls);
+            block = new IntArrayBlock(new int[] { 10, 0, 30, 40 }, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
         } else {
             var blockBuilder = IntBlock.newBlockBuilder(4);
             blockBuilder.appendInt(10);
@@ -111,7 +111,7 @@ public class FilteredBlockTests extends ESTestCase {
         if (randomBoolean()) {
             var nulls = new BitSet();
             nulls.set(0, 4);
-            block = new IntArrayBlock(new int[] { 0, 0, 0, 0 }, 4, null, nulls);
+            block = new IntArrayBlock(new int[] { 0, 0, 0, 0 }, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
         } else {
             var blockBuilder = IntBlock.newBlockBuilder(4);
             blockBuilder.appendNull();
@@ -159,7 +159,13 @@ public class FilteredBlockTests extends ESTestCase {
         BitSet nulls = BitSet.valueOf(new byte[] { 0x08 });  // any non-empty bitset, that does not affect the filter, should suffice
 
         var boolVector = new BooleanArrayVector(new boolean[] { true, false, false, true }, 4);
-        var boolBlock = new BooleanArrayBlock(new boolean[] { true, false, false, true }, 4, null, nulls);
+        var boolBlock = new BooleanArrayBlock(
+            new boolean[] { true, false, false, true },
+            4,
+            null,
+            nulls,
+            randomFrom(Block.MvOrdering.values())
+        );
         for (Object obj : List.of(boolVector.filter(0, 2), boolVector.asBlock().filter(0, 2), boolBlock.filter(0, 2))) {
             String s = obj.toString();
             assertThat(s, containsString("[true, false]"));
@@ -167,7 +173,7 @@ public class FilteredBlockTests extends ESTestCase {
         }
 
         var intVector = new IntArrayVector(new int[] { 10, 20, 30, 40 }, 4);
-        var intBlock = new IntArrayBlock(new int[] { 10, 20, 30, 40 }, 4, null, nulls);
+        var intBlock = new IntArrayBlock(new int[] { 10, 20, 30, 40 }, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
         for (Object obj : List.of(intVector.filter(0, 2), intVector.asBlock().filter(0, 2), intBlock.filter(0, 2))) {
             String s = obj.toString();
             assertThat(s, containsString("[10, 30]"));
@@ -175,7 +181,7 @@ public class FilteredBlockTests extends ESTestCase {
         }
 
         var longVector = new LongArrayVector(new long[] { 100L, 200L, 300L, 400L }, 4);
-        var longBlock = new LongArrayBlock(new long[] { 100L, 200L, 300L, 400L }, 4, null, nulls);
+        var longBlock = new LongArrayBlock(new long[] { 100L, 200L, 300L, 400L }, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
         for (Object obj : List.of(longVector.filter(0, 2), longVector.asBlock().filter(0, 2), longBlock.filter(0, 2))) {
             String s = obj.toString();
             assertThat(s, containsString("[100, 300]"));
@@ -183,7 +189,7 @@ public class FilteredBlockTests extends ESTestCase {
         }
 
         var doubleVector = new DoubleArrayVector(new double[] { 1.1, 2.2, 3.3, 4.4 }, 4);
-        var doubleBlock = new DoubleArrayBlock(new double[] { 1.1, 2.2, 3.3, 4.4 }, 4, null, nulls);
+        var doubleBlock = new DoubleArrayBlock(new double[] { 1.1, 2.2, 3.3, 4.4 }, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
         for (Object obj : List.of(doubleVector.filter(0, 2), doubleVector.asBlock().filter(0, 2), doubleBlock.filter(0, 2))) {
             String s = obj.toString();
             assertThat(s, containsString("[1.1, 3.3]"));
@@ -193,7 +199,7 @@ public class FilteredBlockTests extends ESTestCase {
         assert new BytesRef("1a").toString().equals("[31 61]") && new BytesRef("3c").toString().equals("[33 63]");
         try (var bytesRefArray = arrayOf("1a", "2b", "3c", "4d")) {
             var bytesRefVector = new BytesRefArrayVector(bytesRefArray, 4);
-            var bytesRefBlock = new BytesRefArrayBlock(bytesRefArray, 4, null, nulls);
+            var bytesRefBlock = new BytesRefArrayBlock(bytesRefArray, 4, null, nulls, randomFrom(Block.MvOrdering.values()));
             for (Object obj : List.of(bytesRefVector.filter(0, 2), bytesRefVector.asBlock().filter(0, 2), bytesRefBlock.filter(0, 2))) {
                 String s = obj.toString();
                 assertThat(s, containsString("[[31 61], [33 63]]"));

+ 30 - 6
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/IntBlockEqualityTests.java

@@ -31,8 +31,8 @@ public class IntBlockEqualityTests extends ESTestCase {
     public void testEmptyBlock() {
         // all these "empty" vectors should be equivalent
         List<IntBlock> blocks = List.of(
-            new IntArrayBlock(new int[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
-            new IntArrayBlock(new int[] { 0 }, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
+            new IntArrayBlock(new int[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 }), randomFrom(Block.MvOrdering.values())),
+            new IntArrayBlock(new int[] { 0 }, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 }), randomFrom(Block.MvOrdering.values())),
             IntBlock.newConstantBlockWith(0, 0),
             IntBlock.newBlockBuilder(0).build(),
             IntBlock.newBlockBuilder(0).appendInt(1).build().filter(),
@@ -80,8 +80,20 @@ public class IntBlockEqualityTests extends ESTestCase {
         // all these blocks should be equivalent
         List<IntBlock> blocks = List.of(
             new IntArrayVector(new int[] { 1, 2, 3 }, 3).asBlock(),
-            new IntArrayBlock(new int[] { 1, 2, 3 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new IntArrayBlock(new int[] { 1, 2, 3, 4 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b1000 })),
+            new IntArrayBlock(
+                new int[] { 1, 2, 3 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new IntArrayBlock(
+                new int[] { 1, 2, 3, 4 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b1000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new IntArrayVector(new int[] { 1, 2, 3 }, 3).filter(0, 1, 2).asBlock(),
             new IntArrayVector(new int[] { 1, 2, 3, 4 }, 3).filter(0, 1, 2).asBlock(),
             new IntArrayVector(new int[] { 1, 2, 3, 4 }, 4).filter(0, 1, 2).asBlock(),
@@ -96,8 +108,20 @@ public class IntBlockEqualityTests extends ESTestCase {
         // all these constant-like blocks should be equivalent
         List<IntBlock> moreBlocks = List.of(
             new IntArrayVector(new int[] { 9, 9 }, 2).asBlock(),
-            new IntArrayBlock(new int[] { 9, 9 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new IntArrayBlock(new int[] { 9, 9, 4 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b100 })),
+            new IntArrayBlock(
+                new int[] { 9, 9 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new IntArrayBlock(
+                new int[] { 9, 9, 4 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b100 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new IntArrayVector(new int[] { 9, 9 }, 2).filter(0, 1).asBlock(),
             new IntArrayVector(new int[] { 9, 9, 4 }, 2).filter(0, 1).asBlock(),
             new IntArrayVector(new int[] { 9, 9, 4 }, 3).filter(0, 1).asBlock(),

+ 36 - 6
x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/data/LongBlockEqualityTests.java

@@ -31,8 +31,14 @@ public class LongBlockEqualityTests extends ESTestCase {
     public void testEmptyBlock() {
         // all these "empty" vectors should be equivalent
         List<LongBlock> blocks = List.of(
-            new LongArrayBlock(new long[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
-            new LongArrayBlock(new long[] { 0 }, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 })),
+            new LongArrayBlock(new long[] {}, 0, new int[] {}, BitSet.valueOf(new byte[] { 0b00 }), randomFrom(Block.MvOrdering.values())),
+            new LongArrayBlock(
+                new long[] { 0 },
+                0,
+                new int[] {},
+                BitSet.valueOf(new byte[] { 0b00 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             LongBlock.newConstantBlockWith(0, 0),
             LongBlock.newBlockBuilder(0).build(),
             LongBlock.newBlockBuilder(0).appendLong(1).build().filter(),
@@ -80,8 +86,20 @@ public class LongBlockEqualityTests extends ESTestCase {
         // all these blocks should be equivalent
         List<LongBlock> blocks = List.of(
             new LongArrayVector(new long[] { 1, 2, 3 }, 3).asBlock(),
-            new LongArrayBlock(new long[] { 1, 2, 3 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new LongArrayBlock(new long[] { 1, 2, 3, 4 }, 3, new int[] { 0, 1, 2, 3 }, BitSet.valueOf(new byte[] { 0b1000 })),
+            new LongArrayBlock(
+                new long[] { 1, 2, 3 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new LongArrayBlock(
+                new long[] { 1, 2, 3, 4 },
+                3,
+                new int[] { 0, 1, 2, 3 },
+                BitSet.valueOf(new byte[] { 0b1000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new LongArrayVector(new long[] { 1, 2, 3 }, 3).filter(0, 1, 2).asBlock(),
             new LongArrayVector(new long[] { 1, 2, 3, 4 }, 3).filter(0, 1, 2).asBlock(),
             new LongArrayVector(new long[] { 1, 2, 3, 4 }, 4).filter(0, 1, 2).asBlock(),
@@ -96,8 +114,20 @@ public class LongBlockEqualityTests extends ESTestCase {
         // all these constant-like blocks should be equivalent
         List<LongBlock> moreBlocks = List.of(
             new LongArrayVector(new long[] { 9, 9 }, 2).asBlock(),
-            new LongArrayBlock(new long[] { 9, 9 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b000 })),
-            new LongArrayBlock(new long[] { 9, 9, 4 }, 2, new int[] { 0, 1, 2 }, BitSet.valueOf(new byte[] { 0b100 })),
+            new LongArrayBlock(
+                new long[] { 9, 9 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b000 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
+            new LongArrayBlock(
+                new long[] { 9, 9, 4 },
+                2,
+                new int[] { 0, 1, 2 },
+                BitSet.valueOf(new byte[] { 0b100 }),
+                randomFrom(Block.MvOrdering.values())
+            ),
             new LongArrayVector(new long[] { 9, 9 }, 2).filter(0, 1).asBlock(),
             new LongArrayVector(new long[] { 9, 9, 4 }, 2).filter(0, 1).asBlock(),
             new LongArrayVector(new long[] { 9, 9, 4 }, 3).filter(0, 1).asBlock(),