diff --git a/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkBlockSerde.java b/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkBlockSerde.java index 81430da3c64a..beacffa5fa66 100644 --- a/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkBlockSerde.java +++ b/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkBlockSerde.java @@ -27,6 +27,7 @@ import io.trino.spi.type.DecimalType; import io.trino.spi.type.Decimals; import io.trino.spi.type.Int128; +import io.trino.spi.type.RowType; import io.trino.spi.type.SqlDecimal; import io.trino.spi.type.Type; import io.trino.spi.type.VarcharType; @@ -42,7 +43,9 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; import org.testng.annotations.Test; +import oshi.util.tuples.Pair; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; @@ -176,6 +179,18 @@ public Object deserializeLineitem(LineitemBenchmarkData data) return ImmutableList.copyOf(readPages(data.getPagesSerde(), new BasicSliceInput(data.getDataSource()))); } + @Benchmark + public Object serializeRow(RowTypeBenchmarkData data) + { + return serializePages(data); + } + + @Benchmark + public Object deserializeRow(RowTypeBenchmarkData data) + { + return ImmutableList.copyOf(readPages(data.getPagesSerde(), new BasicSliceInput(data.getDataSource()))); + } + private static List serializePages(BenchmarkData data) { PagesSerdeContext context = new PagesSerdeContext(); @@ -199,35 +214,7 @@ public void setup(Type type, Function valueGenerator) Iterator values = createValues(ROWS, valueGenerator, nullChance); while (values.hasNext()) { - Object value = values.next(); - if (value == null) { - blockBuilder.appendNull(); - } - else if (BIGINT.equals(type)) { - BIGINT.writeLong(blockBuilder, ((Number) value).longValue()); - } - else if (Decimals.isLongDecimal(type)) { - type.writeObject(blockBuilder, Int128.valueOf(((SqlDecimal) value).toBigDecimal().unscaledValue())); - } - else if (type instanceof VarcharType) { - Slice slice = truncateToLength(utf8Slice((String) value), type); - type.writeSlice(blockBuilder, slice); - } - else if (TIMESTAMP_PICOS.equals(type)) { - TIMESTAMP_PICOS.writeObject(blockBuilder, value); - } - else if (INTEGER.equals(type)) { - blockBuilder.writeInt((int) value); - } - else if (SMALLINT.equals(type)) { - blockBuilder.writeShort((short) value); - } - else if (TINYINT.equals(type)) { - blockBuilder.writeByte((byte) value); - } - else { - throw new IllegalArgumentException("Unsupported type " + type); - } + writeValue(type, values.next(), blockBuilder); pageBuilder.declarePosition(); if (pageBuilder.isFull()) { pagesBuilder.add(pageBuilder.build()); @@ -245,6 +232,51 @@ else if (TINYINT.equals(type)) { setup(sliceOutput.slice(), pagesSerde, pages); } + + private void writeValue(Type type, Object value, BlockBuilder blockBuilder) + { + if (value == null) { + blockBuilder.appendNull(); + } + else if (BIGINT.equals(type)) { + BIGINT.writeLong(blockBuilder, ((Number) value).longValue()); + } + else if (Decimals.isLongDecimal(type)) { + type.writeObject(blockBuilder, Int128.valueOf(((SqlDecimal) value).toBigDecimal().unscaledValue())); + } + else if (type instanceof VarcharType) { + Slice slice = truncateToLength(utf8Slice((String) value), type); + type.writeSlice(blockBuilder, slice); + } + else if (TIMESTAMP_PICOS.equals(type)) { + TIMESTAMP_PICOS.writeObject(blockBuilder, value); + } + else if (INTEGER.equals(type)) { + blockBuilder.writeInt((int) value); + } + else if (SMALLINT.equals(type)) { + blockBuilder.writeShort((short) value); + } + else if (TINYINT.equals(type)) { + blockBuilder.writeByte((byte) value); + } + else if (type instanceof RowType) { + BlockBuilder row = blockBuilder.beginBlockEntry(); + List values = (List) value; + if (values.size() != type.getTypeParameters().size()) { + throw new IllegalArgumentException("Size of types and values must have the same size"); + } + List> pairs = new ArrayList<>(); + for (int i = 0; i < type.getTypeParameters().size(); i++) { + pairs.add(new Pair(type.getTypeParameters().get(i), ((List) value).get(i))); + } + pairs.forEach(p -> writeValue(p.getA(), p.getB(), row)); + blockBuilder.closeEntry(); + } + else { + throw new IllegalArgumentException("Unsupported type " + type); + } + } } public abstract static class BenchmarkData @@ -369,6 +401,18 @@ public void setup() } } + @State(Thread) + public static class RowTypeBenchmarkData + extends TypeBenchmarkData + { + @Setup + public void setup() + { + RowType type = RowType.anonymous(ImmutableList.of(BIGINT)); + super.setup(type, (random -> BenchmarkDataGenerator.randomRow(type.getTypeParameters(), random))); + } + } + @Test public void test() { diff --git a/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkDataGenerator.java b/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkDataGenerator.java index b9efb4711f23..c12fd9455194 100644 --- a/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkDataGenerator.java +++ b/core/trino-main/src/test/java/io/trino/execution/buffer/BenchmarkDataGenerator.java @@ -13,8 +13,10 @@ */ package io.trino.execution.buffer; +import io.trino.spi.type.DecimalType; import io.trino.spi.type.LongTimestamp; import io.trino.spi.type.SqlDecimal; +import io.trino.spi.type.Type; import java.math.BigInteger; import java.util.ArrayList; @@ -23,7 +25,9 @@ import java.util.Random; import java.util.function.Function; +import static io.trino.spi.type.BigintType.BIGINT; import static io.trino.spi.type.Timestamps.PICOSECONDS_PER_MICROSECOND; +import static io.trino.spi.type.VarcharType.VARCHAR; public class BenchmarkDataGenerator { @@ -93,4 +97,24 @@ public static byte randomByte(Random random) { return (byte) random.nextInt(); } + + public static List randomRow(List fieldTypes, Random random) + { + List row = new ArrayList<>(fieldTypes.size()); + for (Type type : fieldTypes) { + if (type == VARCHAR) { + row.add(randomAsciiString(random)); + } + else if (type == BIGINT) { + row.add(random.nextLong()); + } + else if (type instanceof DecimalType) { + row.add(randomLongDecimal(random)); + } + else { + throw new UnsupportedOperationException(String.format("The %s is not supported", type)); + } + } + return row; + } } diff --git a/core/trino-spi/src/main/java/io/trino/spi/block/AbstractRowBlock.java b/core/trino-spi/src/main/java/io/trino/spi/block/AbstractRowBlock.java index 58e39bbd47b1..6523e7019ca5 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/block/AbstractRowBlock.java +++ b/core/trino-spi/src/main/java/io/trino/spi/block/AbstractRowBlock.java @@ -38,6 +38,7 @@ public final List getChildren() protected abstract Block[] getRawFieldBlocks(); + @Nullable protected abstract int[] getFieldBlockOffsets(); protected abstract int getOffsetBase(); @@ -51,7 +52,8 @@ public final List getChildren() // the offset in each field block, it can also be viewed as the "entry-based" offset in the RowBlock protected final int getFieldBlockOffset(int position) { - return getFieldBlockOffsets()[position + getOffsetBase()]; + int[] offsets = getFieldBlockOffsets(); + return offsets != null ? offsets[position + getOffsetBase()] : position + getOffsetBase(); } protected AbstractRowBlock(int numFields) @@ -73,7 +75,7 @@ public final Block copyPositions(int[] positions, int offset, int length) { checkArrayRange(positions, offset, length); - int[] newOffsets = new int[length + 1]; + int[] newOffsets = null; int[] fieldBlockPositions = new int[length]; int fieldBlockPositionCount; @@ -82,17 +84,15 @@ public final Block copyPositions(int[] positions, int offset, int length) // No nulls are present newRowIsNull = null; for (int i = 0; i < fieldBlockPositions.length; i++) { - newOffsets[i] = i; // No nulls, all offsets are just their index mapping int position = positions[offset + i]; checkReadablePosition(position); fieldBlockPositions[i] = getFieldBlockOffset(position); } - // Record last offset position - newOffsets[fieldBlockPositions.length] = fieldBlockPositions.length; fieldBlockPositionCount = fieldBlockPositions.length; } else { newRowIsNull = new boolean[length]; + newOffsets = new int[length + 1]; fieldBlockPositionCount = 0; for (int i = 0; i < length; i++) { newOffsets[i] = fieldBlockPositionCount; @@ -107,8 +107,9 @@ public final Block copyPositions(int[] positions, int offset, int length) // Record last offset position newOffsets[length] = fieldBlockPositionCount; if (fieldBlockPositionCount == length) { - // No nulls encountered, discard the null mask + // No nulls encountered, discard the null mask and offsets newRowIsNull = null; + newOffsets = null; } } @@ -183,12 +184,12 @@ public Block copyRegion(int position, int length) for (int i = 0; i < numFields; i++) { newBlocks[i] = getRawFieldBlocks()[i].copyRegion(startFieldBlockOffset, fieldBlockLength); } - - int[] newOffsets = compactOffsets(getFieldBlockOffsets(), position + getOffsetBase(), length); + int[] fieldBlockOffsets = getFieldBlockOffsets(); + int[] newOffsets = fieldBlockOffsets == null ? null : compactOffsets(fieldBlockOffsets, position + getOffsetBase(), length); boolean[] rowIsNull = getRowIsNull(); boolean[] newRowIsNull = rowIsNull == null ? null : compactArray(rowIsNull, position + getOffsetBase(), length); - if (arraySame(newBlocks, getRawFieldBlocks()) && newOffsets == getFieldBlockOffsets() && newRowIsNull == rowIsNull) { + if (arraySame(newBlocks, getRawFieldBlocks()) && newOffsets == fieldBlockOffsets && newRowIsNull == rowIsNull) { return this; } return createRowBlockInternal(0, length, newRowIsNull, newOffsets, newBlocks); @@ -218,7 +219,7 @@ public Block getSingleValueBlock(int position) newBlocks[i] = getRawFieldBlocks()[i].copyRegion(startFieldBlockOffset, fieldBlockLength); } boolean[] newRowIsNull = isNull(position) ? new boolean[] {true} : null; - int[] newOffsets = new int[] {0, fieldBlockLength}; + int[] newOffsets = isNull(position) ? new int[] {0, fieldBlockLength} : null; return createRowBlockInternal(0, 1, newRowIsNull, newOffsets, newBlocks); } diff --git a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlock.java b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlock.java index b0768d976875..910cb293cdad 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlock.java +++ b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlock.java @@ -46,15 +46,10 @@ public class RowBlock public static Block fromFieldBlocks(int positionCount, Optional rowIsNullOptional, Block[] fieldBlocks) { boolean[] rowIsNull = rowIsNullOptional.orElse(null); - int[] fieldBlockOffsets = new int[positionCount + 1]; - if (rowIsNull == null) { - // Fast-path create identity field block offsets from position only - for (int position = 0; position < fieldBlockOffsets.length; position++) { - fieldBlockOffsets[position] = position; - } - } - else { + int[] fieldBlockOffsets = null; + if (rowIsNull != null) { // Check for nulls when computing field block offsets + fieldBlockOffsets = new int[positionCount + 1]; fieldBlockOffsets[0] = 0; for (int position = 0; position < positionCount; position++) { fieldBlockOffsets[position + 1] = fieldBlockOffsets[position] + (rowIsNull[position] ? 0 : 1); @@ -63,6 +58,7 @@ public static Block fromFieldBlocks(int positionCount, Optional rowIs if (fieldBlockOffsets[positionCount] == positionCount) { // No nulls encountered, discard the null mask rowIsNull = null; + fieldBlockOffsets = null; } } @@ -73,13 +69,13 @@ public static Block fromFieldBlocks(int positionCount, Optional rowIs /** * Create a row block directly without per element validations. */ - static RowBlock createRowBlockInternal(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, int[] fieldBlockOffsets, Block[] fieldBlocks) + static RowBlock createRowBlockInternal(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, @Nullable int[] fieldBlockOffsets, Block[] fieldBlocks) { validateConstructorArguments(startOffset, positionCount, rowIsNull, fieldBlockOffsets, fieldBlocks); return new RowBlock(startOffset, positionCount, rowIsNull, fieldBlockOffsets, fieldBlocks); } - private static void validateConstructorArguments(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, int[] fieldBlockOffsets, Block[] fieldBlocks) + private static void validateConstructorArguments(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, @Nullable int[] fieldBlockOffsets, Block[] fieldBlocks) { if (startOffset < 0) { throw new IllegalArgumentException("arrayOffset is negative"); @@ -93,8 +89,11 @@ private static void validateConstructorArguments(int startOffset, int positionCo throw new IllegalArgumentException("rowIsNull length is less than positionCount"); } - requireNonNull(fieldBlockOffsets, "fieldBlockOffsets is null"); - if (fieldBlockOffsets.length - startOffset < positionCount + 1) { + if ((rowIsNull == null) != (fieldBlockOffsets == null)) { + throw new IllegalArgumentException("When rowIsNull is (non) null then fieldBlockOffsets should be (non) null as well"); + } + + if (fieldBlockOffsets != null && fieldBlockOffsets.length - startOffset < positionCount + 1) { throw new IllegalArgumentException("fieldBlockOffsets length is less than positionCount"); } @@ -116,7 +115,7 @@ private static void validateConstructorArguments(int startOffset, int positionCo * Use createRowBlockInternal or fromFieldBlocks instead of this method. The caller of this method is assumed to have * validated the arguments with validateConstructorArguments. */ - private RowBlock(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, int[] fieldBlockOffsets, Block[] fieldBlocks) + private RowBlock(int startOffset, int positionCount, @Nullable boolean[] rowIsNull, @Nullable int[] fieldBlockOffsets, Block[] fieldBlocks) { super(fieldBlocks.length); @@ -136,6 +135,7 @@ protected Block[] getRawFieldBlocks() } @Override + @Nullable protected int[] getFieldBlockOffsets() { return fieldBlockOffsets; @@ -176,8 +176,8 @@ public long getSizeInBytes() long sizeInBytes = getBaseSizeInBytes(); boolean hasUnloadedBlocks = false; - int startFieldBlockOffset = fieldBlockOffsets[startOffset]; - int endFieldBlockOffset = fieldBlockOffsets[startOffset + positionCount]; + int startFieldBlockOffset = fieldBlockOffsets != null ? fieldBlockOffsets[startOffset] : startOffset; + int endFieldBlockOffset = fieldBlockOffsets != null ? fieldBlockOffsets[startOffset + positionCount] : startOffset + positionCount; int fieldBlockLength = endFieldBlockOffset - startFieldBlockOffset; for (Block fieldBlock : fieldBlocks) { diff --git a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockBuilder.java b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockBuilder.java index 0cfe1eaafae5..15726bcd733c 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockBuilder.java +++ b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockBuilder.java @@ -85,9 +85,10 @@ protected Block[] getRawFieldBlocks() } @Override + @Nullable protected int[] getFieldBlockOffsets() { - return fieldBlockOffsets; + return hasNullRow ? fieldBlockOffsets : null; } @Override @@ -223,7 +224,7 @@ public Block build() for (int i = 0; i < numFields; i++) { fieldBlocks[i] = fieldBlockBuilders[i].build(); } - return createRowBlockInternal(0, positionCount, hasNullRow ? rowIsNull : null, fieldBlockOffsets, fieldBlocks); + return createRowBlockInternal(0, positionCount, hasNullRow ? rowIsNull : null, hasNullRow ? fieldBlockOffsets : null, fieldBlocks); } @Override diff --git a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockEncoding.java b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockEncoding.java index 1dec830e76e7..00fe6302fea4 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockEncoding.java +++ b/core/trino-spi/src/main/java/io/trino/spi/block/RowBlockEncoding.java @@ -35,40 +35,61 @@ public String getName() public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceOutput, Block block) { AbstractRowBlock rowBlock = (AbstractRowBlock) block; + int[] fieldBlockOffsets = rowBlock.getFieldBlockOffsets(); + int numFields = rowBlock.numFields; int positionCount = rowBlock.getPositionCount(); int offsetBase = rowBlock.getOffsetBase(); - int[] fieldBlockOffsets = rowBlock.getFieldBlockOffsets(); - int startFieldBlockOffset = fieldBlockOffsets[offsetBase]; - int endFieldBlockOffset = fieldBlockOffsets[offsetBase + positionCount]; + + int startFieldBlockOffset = fieldBlockOffsets != null ? fieldBlockOffsets[offsetBase] : offsetBase; + int endFieldBlockOffset = fieldBlockOffsets != null ? fieldBlockOffsets[offsetBase + positionCount] : offsetBase + positionCount; sliceOutput.appendInt(numFields); + sliceOutput.appendInt(positionCount); + for (int i = 0; i < numFields; i++) { blockEncodingSerde.writeBlock(sliceOutput, rowBlock.getRawFieldBlocks()[i].getRegion(startFieldBlockOffset, endFieldBlockOffset - startFieldBlockOffset)); } - sliceOutput.appendInt(positionCount); - for (int position = 0; position < positionCount + 1; position++) { - sliceOutput.writeInt(fieldBlockOffsets[offsetBase + position] - startFieldBlockOffset); - } EncoderUtil.encodeNullsAsBits(sliceOutput, block); + + if ((rowBlock.getRowIsNull() == null) != (fieldBlockOffsets == null)) { + throw new IllegalArgumentException("When rowIsNull is (non) null then fieldBlockOffsets should be (non) null as well"); + } + + if (fieldBlockOffsets != null) { + if (startFieldBlockOffset == 0) { + sliceOutput.writeBytes(wrappedIntArray(fieldBlockOffsets, offsetBase, positionCount + 1)); + } + else { + int[] newFieldBlockOffsets = new int[positionCount + 1]; + for (int position = 0; position < positionCount + 1; position++) { + newFieldBlockOffsets[position] = fieldBlockOffsets[offsetBase + position] - startFieldBlockOffset; + } + sliceOutput.writeBytes(wrappedIntArray(newFieldBlockOffsets)); + } + } } @Override public Block readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput) { int numFields = sliceInput.readInt(); + int positionCount = sliceInput.readInt(); + Block[] fieldBlocks = new Block[numFields]; for (int i = 0; i < numFields; i++) { fieldBlocks[i] = blockEncodingSerde.readBlock(sliceInput); } - int positionCount = sliceInput.readInt(); - int[] fieldBlockOffsets = new int[positionCount + 1]; - sliceInput.readBytes(wrappedIntArray(fieldBlockOffsets)); boolean[] rowIsNull = EncoderUtil.decodeNullBits(sliceInput, positionCount).orElse(null); + int[] fieldBlockOffsets = null; + if (rowIsNull != null) { + fieldBlockOffsets = new int[positionCount + 1]; + sliceInput.readBytes(wrappedIntArray(fieldBlockOffsets)); + } return createRowBlockInternal(0, positionCount, rowIsNull, fieldBlockOffsets, fieldBlocks); } } diff --git a/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlock.java b/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlock.java new file mode 100644 index 000000000000..2b7f14637d77 --- /dev/null +++ b/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlock.java @@ -0,0 +1,43 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.trino.spi.block; + +import org.testng.annotations.Test; + +import java.util.Optional; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; + +public class TestRowBlock +{ + @Test + public void testFieldBlockOffsetsIsNullWhenThereIsNoNullRow() + { + Block fieldBlock = new ByteArrayBlock(1, Optional.empty(), new byte[]{10}); + AbstractRowBlock rowBlock = (RowBlock) RowBlock.fromFieldBlocks(1, Optional.empty(), new Block[] {fieldBlock}); + // Blocks should discard the offset mask during creation if no values are null + assertNull(rowBlock.getFieldBlockOffsets()); + } + + @Test + public void testFieldBlockOffsetsIsNotNullWhenThereIsNullRow() + { + Block fieldBlock = new ByteArrayBlock(1, Optional.empty(), new byte[]{10}); + AbstractRowBlock rowBlock = (RowBlock) RowBlock.fromFieldBlocks(1, Optional.of(new boolean[] {true}), new Block[] {fieldBlock}); + // Blocks should not discard the offset mask during creation if no values are null + assertNotNull(rowBlock.getFieldBlockOffsets()); + } +} diff --git a/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlockEncoding.java b/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlockEncoding.java new file mode 100644 index 000000000000..1d662813c4d6 --- /dev/null +++ b/core/trino-spi/src/test/java/io/trino/spi/block/TestRowBlockEncoding.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.trino.spi.block; + +import com.google.common.collect.ImmutableList; +import io.trino.spi.type.RowType; +import io.trino.spi.type.Type; + +import java.nio.charset.Charset; +import java.util.Random; + +import static io.airlift.slice.Slices.utf8Slice; +import static io.trino.spi.type.BigintType.BIGINT; +import static io.trino.spi.type.VarcharType.VARCHAR; + +public class TestRowBlockEncoding + extends BaseBlockEncodingTest +{ + @Override + protected Type getType() + { + return RowType.anonymous(ImmutableList.of(BIGINT, VARCHAR)); + } + + @Override + protected void write(BlockBuilder blockBuilder, Object[] value) + { + BlockBuilder row = blockBuilder.beginBlockEntry(); + BIGINT.writeLong(row, (long) value[0]); + VARCHAR.writeSlice(row, utf8Slice((String) value[1])); + blockBuilder.closeEntry(); + } + + @Override + protected Object[] randomValue(Random random) + { + byte[] data = new byte[random.nextInt(256)]; + random.nextBytes(data); + return new Object[] {random.nextLong(), new String(data, Charset.defaultCharset()), null}; + } +} diff --git a/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerWithSplits.java b/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerWithSplits.java index 56b698e1fde3..1a2dbce355a2 100644 --- a/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerWithSplits.java +++ b/testing/trino-tests/src/test/java/io/trino/execution/TestEventListenerWithSplits.java @@ -164,7 +164,7 @@ public void testSplitsForNormalQuery() // Deterministic statistics assertEquals(statistics.getPhysicalInputBytes(), 0); assertEquals(statistics.getPhysicalInputRows(), expectedCompletedPositions); - assertEquals(statistics.getInternalNetworkBytes(), 405); + assertEquals(statistics.getInternalNetworkBytes(), 381); assertEquals(statistics.getInternalNetworkRows(), 3); assertEquals(statistics.getTotalBytes(), 0); assertEquals(statistics.getOutputBytes(), 9);