Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CharType.getRange #14912

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.trino.spi.type.VarcharType;

import static io.trino.spi.type.VarcharType.createVarcharType;
import static java.lang.Character.MAX_CODE_POINT;
import static org.testng.Assert.assertEquals;

public class TestBoundedVarcharType
Expand Down Expand Up @@ -58,17 +59,7 @@ protected Object getGreaterValue(Object value)
public void testRange()
{
Type.Range range = type.getRange().orElseThrow();

String expectedMax = new StringBuilder()
.appendCodePoint(Character.MAX_CODE_POINT)
.appendCodePoint(Character.MAX_CODE_POINT)
.appendCodePoint(Character.MAX_CODE_POINT)
.appendCodePoint(Character.MAX_CODE_POINT)
.appendCodePoint(Character.MAX_CODE_POINT)
.appendCodePoint(Character.MAX_CODE_POINT)
.toString();

assertEquals(range.getMin(), Slices.utf8Slice(""));
assertEquals(range.getMax(), Slices.utf8Slice(expectedMax));
assertEquals(range.getMax(), Slices.utf8Slice(Character.toString(MAX_CODE_POINT).repeat(((VarcharType) type).getBoundedLength())));
}
}
10 changes: 10 additions & 0 deletions core/trino-main/src/test/java/io/trino/type/TestCharType.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
import io.trino.spi.block.Block;
import io.trino.spi.block.BlockBuilder;
import io.trino.spi.type.CharType;
import io.trino.spi.type.Type;
import org.testng.annotations.Test;

import static io.airlift.slice.SliceUtf8.codePointToUtf8;
import static io.airlift.slice.Slices.EMPTY_SLICE;
import static io.trino.spi.type.CharType.createCharType;
import static io.trino.testing.TestingConnectorSession.SESSION;
import static java.lang.Character.MAX_CODE_POINT;
import static java.lang.Character.MIN_CODE_POINT;
import static java.lang.Character.MIN_SUPPLEMENTARY_CODE_POINT;
import static java.lang.Character.isSupplementaryCodePoint;
import static org.testng.Assert.assertEquals;
Expand Down Expand Up @@ -86,4 +88,12 @@ public void testGetObjectValue()
}
}
}

@Override
public void testRange()
{
Type.Range range = type.getRange().orElseThrow();
assertEquals(range.getMin(), Slices.utf8Slice(Character.toString(MIN_CODE_POINT).repeat(((CharType) type).getLength())));
assertEquals(range.getMax(), Slices.utf8Slice(Character.toString(MAX_CODE_POINT).repeat(((CharType) type).getLength())));
}
}
40 changes: 40 additions & 0 deletions core/trino-spi/src/main/java/io/trino/spi/type/CharType.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package io.trino.spi.type;

import io.airlift.slice.Slice;
import io.airlift.slice.SliceUtf8;
import io.airlift.slice.Slices;
import io.airlift.slice.XxHash64;
import io.trino.spi.TrinoException;
Expand All @@ -26,6 +27,7 @@
import io.trino.spi.function.ScalarOperator;

import java.util.Objects;
import java.util.Optional;

import static io.airlift.slice.SliceUtf8.countCodePoints;
import static io.trino.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT;
Expand All @@ -36,6 +38,8 @@
import static io.trino.spi.type.Chars.padSpaces;
import static io.trino.spi.type.Slices.sliceRepresentation;
import static io.trino.spi.type.TypeOperatorDeclaration.extractOperatorDeclaration;
import static java.lang.Character.MAX_CODE_POINT;
import static java.lang.Character.MIN_CODE_POINT;
import static java.lang.String.format;
import static java.lang.invoke.MethodHandles.lookup;
import static java.util.Collections.singletonList;
Expand All @@ -48,6 +52,7 @@ public final class CharType
public static final int MAX_LENGTH = 65_536;

private final int length;
private volatile Optional<Range> range;

public static CharType createCharType(long length)
{
Expand Down Expand Up @@ -91,6 +96,41 @@ public TypeOperatorDeclaration getTypeOperatorDeclaration(TypeOperators typeOper
return TYPE_OPERATOR_DECLARATION;
}

@Override
public Optional<Range> getRange()
{
Optional<Range> range = this.range;
@SuppressWarnings("OptionalAssignedToNull")
boolean cachedRangePresent = range != null;
if (!cachedRangePresent) {
if (length > 100) {
// The max/min values may be materialized in the plan, so we don't want them to be too large.
// Range comparison against large values are usually nonsensical, too, so no need to support them
// beyond a certain size. They specific choice above is arbitrary and can be adjusted if needed.
range = Optional.empty();
}
else {
int minCodePointSize = SliceUtf8.lengthOfCodePoint(MIN_CODE_POINT);
int maxCodePointSize = SliceUtf8.lengthOfCodePoint(MAX_CODE_POINT);

Slice min = Slices.allocate(minCodePointSize * length);
Slice max = Slices.allocate(maxCodePointSize * length);
int position = 0;
for (int i = 0; i < length; i++) {
position += SliceUtf8.setCodePointAt(MIN_CODE_POINT, min, position);
}
position = 0;
for (int i = 0; i < length; i++) {
position += SliceUtf8.setCodePointAt(MAX_CODE_POINT, max, position);
}

range = Optional.of(new Range(min, max));
}
this.range = range;
}
return range;
}

@Override
public Object getObjectValue(ConnectorSession session, Block block, int position)
{
Expand Down