use of io.prestosql.spi.function.LiteralParameters in project hetu-core by openlookeng.
the class ApproximateSetAggregation method input.
@InputFunction
@LiteralParameters("x")
public static void input(@AggregationState HyperLogLogState state, @SqlType("varchar(x)") Slice value) {
HyperLogLog hll = getOrCreateHyperLogLog(state);
state.addMemoryUsage(-hll.estimatedInMemorySize());
hll.add(value);
state.addMemoryUsage(hll.estimatedInMemorySize());
}
use of io.prestosql.spi.function.LiteralParameters in project hetu-core by openlookeng.
the class Re2JRegexpReplaceLambdaFunction method regexpReplace.
@LiteralParameters("x")
@SqlType("varchar")
@SqlNullable
public Slice regexpReplace(@SqlType("varchar") Slice source, @SqlType(Re2JRegexpType.NAME) Re2JRegexp pattern, @SqlType("function(array(varchar), varchar(x))") UnaryFunctionInterface replaceFunction) {
// If there is no match we can simply return the original source without doing copy.
Matcher matcher = pattern.re2jPattern.matcher(source);
if (!matcher.find()) {
return source;
}
SliceOutput output = new DynamicSliceOutput(source.length());
// that will be passed to the lambda function.
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
int groupCount = matcher.groupCount();
int appendPosition = 0;
do {
int start = matcher.start();
int end = matcher.end();
// Append the un-matched part
if (appendPosition < start) {
output.writeBytes(source, appendPosition, start - appendPosition);
}
appendPosition = end;
// Append the capturing groups to the target block that will be passed to lambda
for (int i = 1; i <= groupCount; i++) {
Slice matchedGroupSlice = matcher.group(i);
if (matchedGroupSlice != null) {
VARCHAR.writeSlice(blockBuilder, matchedGroupSlice);
} else {
blockBuilder.appendNull();
}
}
pageBuilder.declarePositions(groupCount);
Block target = blockBuilder.getRegion(blockBuilder.getPositionCount() - groupCount, groupCount);
// Call the lambda function to replace the block, and append the result to output
Slice replaced = (Slice) replaceFunction.apply(target);
if (replaced == null) {
// replacing a substring with null (unknown) makes the entire string null
return null;
}
output.appendBytes(replaced);
} while (matcher.find());
// Append the rest of un-matched
output.writeBytes(source, appendPosition, source.length() - appendPosition);
return output.slice();
}
use of io.prestosql.spi.function.LiteralParameters in project hetu-core by openlookeng.
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 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.prestosql.spi.function.LiteralParameters in project hetu-core by openlookeng.
the class StringFunctions method splitPart.
@SqlNullable
@Description("splits a string by a delimiter and returns the specified field (counting from one)")
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType("varchar(x)")
public static Slice splitPart(@SqlType("varchar(x)") Slice string, @SqlType("varchar(y)") Slice delimiter, @SqlType(StandardTypes.BIGINT) long index) {
checkCondition(index > 0, INVALID_FUNCTION_ARGUMENT, "Index must be greater than zero");
// Empty delimiter? Then every character will be a split
if (delimiter.length() == 0) {
int startCodePoint = toIntExact(index);
int indexStart = offsetOfCodePoint(string, startCodePoint - 1);
if (indexStart < 0) {
// index too big
return null;
}
int length = lengthOfCodePoint(string, indexStart);
if (indexStart + length > string.length()) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Invalid UTF-8 encoding");
}
return string.slice(indexStart, length);
}
int matchCount = 0;
int previousIndex = 0;
while (previousIndex < string.length()) {
int matchIndex = string.indexOf(delimiter, previousIndex);
// No match
if (matchIndex < 0) {
break;
}
// Reached the requested part?
if (++matchCount == index) {
return string.slice(previousIndex, matchIndex - previousIndex);
}
// Continue searching after the delimiter
previousIndex = matchIndex + delimiter.length();
}
if (matchCount == index - 1) {
// returns last section of the split
return string.slice(previousIndex, string.length() - previousIndex);
}
// index is too big, null is returned
return null;
}
use of io.prestosql.spi.function.LiteralParameters in project hetu-core by openlookeng.
the class StringFunctions method split.
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType("array(varchar(x))")
public static Block split(@SqlType("varchar(x)") Slice string, @SqlType("varchar(y)") Slice delimiter, @SqlType(StandardTypes.BIGINT) long limit) {
checkCondition(limit > 0, INVALID_FUNCTION_ARGUMENT, "Limit must be positive");
checkCondition(limit <= Integer.MAX_VALUE, INVALID_FUNCTION_ARGUMENT, "Limit is too large");
checkCondition(delimiter.length() > 0, INVALID_FUNCTION_ARGUMENT, "The delimiter may not be the empty string");
BlockBuilder parts = VARCHAR.createBlockBuilder(null, 1, string.length());
// If limit is one, the last and only element is the complete string
if (limit == 1) {
VARCHAR.writeSlice(parts, string);
return parts.build();
}
int index = 0;
while (index < string.length()) {
int splitIndex = string.indexOf(delimiter, index);
// Found split?
if (splitIndex < 0) {
break;
}
// Add the part from current index to found split
VARCHAR.writeSlice(parts, string, index, splitIndex - index);
// Continue searching after delimiter
index = splitIndex + delimiter.length();
// Reached limit-1 parts so we can stop
if (parts.getPositionCount() == limit - 1) {
break;
}
}
// Rest of string
VARCHAR.writeSlice(parts, string, index, string.length() - index);
return parts.build();
}
Aggregations