use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class ColorFunctions method bar.
@ScalarFunction
@SqlType(StandardTypes.VARCHAR)
public static Slice bar(@SqlType(StandardTypes.DOUBLE) double percent, @SqlType(StandardTypes.BIGINT) long width, @SqlType(ColorType.NAME) long lowColor, @SqlType(ColorType.NAME) long highColor) {
long count = (int) (percent * width);
count = Math.min(width, count);
count = Math.max(0, count);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < count; i++) {
float fraction = (float) (i * 1.0 / (width - 1));
int color = interpolate(fraction, lowColor, highColor);
builder.append(ansiColorEscape(color)).append('\u2588');
}
// reset
builder.append(ANSI_RESET);
// pad to force column to be the requested width
for (long i = count; i < width; ++i) {
builder.append(' ');
}
return utf8Slice(builder.toString());
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class StringFunctions method hammingDistance.
@Description("Computes Hamming distance between two strings")
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType(StandardTypes.BIGINT)
public static long hammingDistance(@SqlType("varchar(x)") Slice left, @SqlType("varchar(y)") Slice right) {
int distance = 0;
int leftPosition = 0;
int rightPosition = 0;
while (leftPosition < left.length() && rightPosition < right.length()) {
int codePointLeft = tryGetCodePointAt(left, leftPosition);
int codePointRight = tryGetCodePointAt(right, rightPosition);
// the following code treats them as equal if they happen to be of the same length
if (codePointLeft != codePointRight) {
distance++;
}
leftPosition += codePointLeft > 0 ? lengthOfCodePoint(codePointLeft) : -codePointLeft;
rightPosition += codePointRight > 0 ? lengthOfCodePoint(codePointRight) : -codePointRight;
}
checkCondition(leftPosition == left.length() && rightPosition == right.length(), INVALID_FUNCTION_ARGUMENT, "The input strings to hamming_distance function must have the same length");
return distance;
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class StringFunctions method fromUtf8.
@Description("Decodes the UTF-8 encoded string")
@ScalarFunction
@LiteralParameters("x")
@SqlType(StandardTypes.VARCHAR)
public static Slice fromUtf8(@SqlType(StandardTypes.VARBINARY) Slice slice, @SqlType("varchar(x)") Slice replacementCharacter) {
int count = countCodePoints(replacementCharacter);
if (count > 1) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Replacement character string must empty or a single character");
}
OptionalInt replacementCodePoint;
if (count == 1) {
try {
replacementCodePoint = OptionalInt.of(getCodePointAt(replacementCharacter, 0));
} catch (InvalidUtf8Exception e) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid replacement character");
}
} else {
replacementCodePoint = OptionalInt.empty();
}
return SliceUtf8.fixInvalidUtf8(slice, replacementCodePoint);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class StringFunctions method replace.
@Description("Greedily replaces occurrences of a pattern with a string")
@ScalarFunction
@LiteralParameters({ "x", "y", "z", "u" })
@Constraint(variable = "u", expression = "min(2147483647, x + z * (x + 1))")
@SqlType("varchar(u)")
public static Slice replace(@SqlType("varchar(x)") Slice str, @SqlType("varchar(y)") Slice search, @SqlType("varchar(z)") Slice replace) {
// Empty search?
if (search.length() == 0) {
// With empty `search` we insert `replace` in front of every character and the end
Slice buffer = Slices.allocate((countCodePoints(str) + 1) * replace.length() + str.length());
// Always start with replace
buffer.setBytes(0, replace);
int indexBuffer = replace.length();
// After every code point insert `replace`
int index = 0;
while (index < str.length()) {
int codePointLength = lengthOfCodePointSafe(str, index);
// Append current code point
buffer.setBytes(indexBuffer, str, index, codePointLength);
indexBuffer += codePointLength;
// Append `replace`
buffer.setBytes(indexBuffer, replace);
indexBuffer += replace.length();
// Advance pointer to current code point
index += codePointLength;
}
return buffer;
}
// Allocate a reasonable buffer
Slice buffer = Slices.allocate(str.length());
int index = 0;
int indexBuffer = 0;
while (index < str.length()) {
int matchIndex = str.indexOf(search, index);
// Found a match?
if (matchIndex < 0) {
// No match found so copy the rest of string
int bytesToCopy = str.length() - index;
buffer = Slices.ensureSize(buffer, indexBuffer + bytesToCopy);
buffer.setBytes(indexBuffer, str, index, bytesToCopy);
indexBuffer += bytesToCopy;
break;
}
int bytesToCopy = matchIndex - index;
buffer = Slices.ensureSize(buffer, indexBuffer + bytesToCopy + replace.length());
// Non empty match?
if (bytesToCopy > 0) {
buffer.setBytes(indexBuffer, str, index, bytesToCopy);
indexBuffer += bytesToCopy;
}
// Non empty replace?
if (replace.length() > 0) {
buffer.setBytes(indexBuffer, replace);
indexBuffer += replace.length();
}
// Continue searching after match
index = matchIndex + search.length();
}
return buffer.slice(0, indexBuffer);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class ScalarImplementationHeader method fromAnnotatedElement.
public static List<ScalarImplementationHeader> fromAnnotatedElement(AnnotatedElement annotated) {
ScalarFunction scalarFunction = annotated.getAnnotation(ScalarFunction.class);
ScalarOperator scalarOperator = annotated.getAnnotation(ScalarOperator.class);
Optional<String> description = parseDescription(annotated);
ImmutableList.Builder<ScalarImplementationHeader> builder = ImmutableList.builder();
if (scalarFunction != null) {
String baseName = scalarFunction.value().isEmpty() ? camelToSnake(annotatedName(annotated)) : scalarFunction.value();
builder.add(new ScalarImplementationHeader(baseName, new ScalarHeader(description, scalarFunction.hidden(), scalarFunction.deterministic())));
for (String alias : scalarFunction.alias()) {
builder.add(new ScalarImplementationHeader(alias, new ScalarHeader(description, scalarFunction.hidden(), scalarFunction.deterministic())));
}
}
if (scalarOperator != null) {
builder.add(new ScalarImplementationHeader(scalarOperator.value(), new ScalarHeader(description, true, true)));
}
List<ScalarImplementationHeader> result = builder.build();
checkArgument(!result.isEmpty());
return result;
}
Aggregations