use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class BenchmarkArraySort method oldArraySort.
@ScalarFunction
@SqlType("array(varchar)")
public static Block oldArraySort(@SqlType("array(varchar)") Block block) {
List<Integer> positions = Ints.asList(new int[block.getPositionCount()]);
for (int i = 0; i < block.getPositionCount(); i++) {
positions.set(i, i);
}
positions.sort((p1, p2) -> {
// TODO: This could be quite slow, it should use parametric equals
return (int) VARCHAR_COMPARISON.compare(block, p1, block, p2);
});
BlockBuilder blockBuilder = VARCHAR.createBlockBuilder(null, block.getPositionCount());
for (int position : positions) {
VARCHAR.appendTo(block, position, blockBuilder);
}
return blockBuilder.build();
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class MathFunctions method inverseBetaCdf.
@Description("Inverse of Beta cdf given a, b parameters and probability")
@ScalarFunction
@SqlType(StandardTypes.DOUBLE)
public static double inverseBetaCdf(@SqlType(StandardTypes.DOUBLE) double a, @SqlType(StandardTypes.DOUBLE) double b, @SqlType(StandardTypes.DOUBLE) double p) {
checkCondition(p >= 0 && p <= 1, INVALID_FUNCTION_ARGUMENT, "p must be 0 >= p >= 1");
checkCondition(a > 0 && b > 0, INVALID_FUNCTION_ARGUMENT, "a, b must be > 0");
BetaDistribution distribution = new BetaDistribution(null, a, b, BetaDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
return distribution.inverseCumulativeProbability(p);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class MathFunctions method widthBucket.
@Description("The bucket number of a value given an array of bins")
@ScalarFunction("width_bucket")
@SqlType(StandardTypes.BIGINT)
public static long widthBucket(@SqlType(StandardTypes.DOUBLE) double operand, @SqlType("array(double)") Block bins) {
int numberOfBins = bins.getPositionCount();
checkCondition(numberOfBins > 0, INVALID_FUNCTION_ARGUMENT, "Bins cannot be an empty array");
checkCondition(!isNaN(operand), INVALID_FUNCTION_ARGUMENT, "Operand cannot be NaN");
int lower = 0;
int upper = numberOfBins;
int index;
double bin;
while (lower < upper) {
if (DOUBLE.getDouble(bins, lower) > DOUBLE.getDouble(bins, upper - 1)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Bin values are not sorted in ascending order");
}
index = (lower + upper) / 2;
bin = DOUBLE.getDouble(bins, index);
if (!isFinite(bin)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Bin value must be finite, got " + bin);
}
if (operand < bin) {
upper = index;
} else {
lower = index + 1;
}
}
return lower;
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class JoniRegexpFunctions method regexpPosition.
@ScalarFunction
@Description("Returns the index of the n-th matched substring starting from the specified position")
@LiteralParameters("x")
@SqlType(StandardTypes.INTEGER)
public static long regexpPosition(@SqlType("varchar(x)") Slice source, @SqlType(JoniRegexpType.NAME) JoniRegexp pattern, @SqlType(StandardTypes.INTEGER) long start, @SqlType(StandardTypes.INTEGER) long occurrence) {
// start position cannot be smaller than 1
if (start < 1) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "start position cannot be smaller than 1");
}
// occurrence cannot be smaller than 1
if (occurrence < 1) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "occurrence cannot be smaller than 1");
}
// returns -1 if start is greater than the length of source
if (start > SliceUtf8.countCodePoints(source)) {
return -1;
}
Matcher matcher = pattern.matcher(source.getBytes());
long count = 0;
// convert char position to byte position
// subtract 1 because codePointCount starts from zero
int nextStart = SliceUtf8.offsetOfCodePoint(source, (int) start - 1);
while (true) {
int offset = matcher.search(nextStart, source.length(), Option.DEFAULT);
// Check whether offset is negative, offset is -1 if no pattern was found or -2 if process was interrupted
if (offset < 0) {
return -1;
}
if (++count == occurrence) {
// Plus 1 because position returned start from 1
return SliceUtf8.countCodePoints(source, 0, matcher.getBegin()) + 1;
}
nextStart = getNextStart(source, matcher);
}
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class JoniRegexpFunctions method regexpReplace.
@Description("Replaces substrings matching a regular expression by given string")
@ScalarFunction
@LiteralParameters({ "x", "y", "z" })
// to get the formula: x + max(x * y / 2, y) * (x + 1)
@Constraint(variable = "z", expression = "min(2147483647, x + max(x * y / 2, y) * (x + 1))")
@SqlType("varchar(z)")
public static Slice regexpReplace(@SqlType("varchar(x)") Slice source, @SqlType(JoniRegexpType.NAME) JoniRegexp pattern, @SqlType("varchar(y)") Slice replacement) {
Matcher matcher = pattern.matcher(source.getBytes());
SliceOutput sliceOutput = new DynamicSliceOutput(source.length() + replacement.length() * 5);
int lastEnd = 0;
// nextStart is the same as lastEnd, unless the last match was zero-width. In such case, nextStart is lastEnd + 1.
int nextStart = 0;
while (true) {
int offset = matcher.search(nextStart, source.length(), Option.DEFAULT);
if (offset == -1) {
break;
}
nextStart = getNextStart(source, matcher);
Slice sliceBetweenReplacements = source.slice(lastEnd, matcher.getBegin() - lastEnd);
lastEnd = matcher.getEnd();
sliceOutput.appendBytes(sliceBetweenReplacements);
appendReplacement(sliceOutput, source, pattern.regex(), matcher.getEagerRegion(), replacement);
}
sliceOutput.appendBytes(source.slice(lastEnd, source.length() - lastEnd));
return sliceOutput.slice();
}
Aggregations