use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
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 PrestoException(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 PrestoException(INVALID_FUNCTION_ARGUMENT, "Invalid replacement character");
}
} else {
replacementCodePoint = OptionalInt.empty();
}
return SliceUtf8.fixInvalidUtf8(slice, replacementCodePoint);
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
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 com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class CreateHll method createHll.
@ScalarFunction
@SqlType(StandardTypes.HYPER_LOG_LOG)
public static Slice createHll(@SqlType(StandardTypes.BIGINT) long value) {
HyperLogLog hll = HyperLogLog.newInstance(4096);
hll.add(value);
return hll.serialize();
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class StringFunctions method substr.
@Description("substring of given length starting at an index")
@ScalarFunction
@LiteralParameters("x")
@SqlType("varchar(x)")
public static Slice substr(@SqlType("varchar(x)") Slice utf8, @SqlType(StandardTypes.BIGINT) long start, @SqlType(StandardTypes.BIGINT) long length) {
if (start == 0 || (length <= 0) || (utf8.length() == 0)) {
return Slices.EMPTY_SLICE;
}
int startCodePoint = Ints.saturatedCast(start);
int lengthCodePoints = Ints.saturatedCast(length);
if (startCodePoint > 0) {
int indexStart = offsetOfCodePoint(utf8, startCodePoint - 1);
if (indexStart < 0) {
// before beginning of string
return Slices.EMPTY_SLICE;
}
int indexEnd = offsetOfCodePoint(utf8, indexStart, lengthCodePoints);
if (indexEnd < 0) {
// after end of string
indexEnd = utf8.length();
}
return utf8.slice(indexStart, indexEnd - indexStart);
}
// negative start is relative to end of string
int codePoints = countCodePoints(utf8);
startCodePoint += codePoints;
// before beginning of string
if (startCodePoint < 0) {
return Slices.EMPTY_SLICE;
}
int indexStart = offsetOfCodePoint(utf8, startCodePoint);
int indexEnd;
if (startCodePoint + lengthCodePoints < codePoints) {
indexEnd = offsetOfCodePoint(utf8, indexStart, lengthCodePoints);
} else {
indexEnd = utf8.length();
}
return utf8.slice(indexStart, indexEnd - indexStart);
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class MapToMapCast method toMap.
@TypeParameter("FK")
@TypeParameter("FV")
@TypeParameter("TK")
@TypeParameter("TV")
@SqlType("map(TK,TV)")
public static Block toMap(@OperatorDependency(operator = EQUAL, returnType = StandardTypes.BOOLEAN, argumentTypes = { "TK", "TK" }) MethodHandle toKeyEqualsFunction, @OperatorDependency(operator = CAST, returnType = "TK", argumentTypes = { "FK" }) MethodHandle keyCastFunction, @OperatorDependency(operator = CAST, returnType = "TV", argumentTypes = { "FV" }) MethodHandle valueCastFunction, @TypeParameter("FK") Type fromKeyType, @TypeParameter("FV") Type fromValueType, @TypeParameter("TK") Type toKeyType, @TypeParameter("TV") Type toValueType, ConnectorSession session, @SqlType("map(FK,FV)") Block fromMap) {
// loop over all the parameter types and bind ConnectorSession if needed
// TODO: binding `ConnectorSession` should be done in function invocation framework
Class<?>[] parameterTypes = keyCastFunction.type().parameterArray();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i] == ConnectorSession.class) {
keyCastFunction = MethodHandles.insertArguments(keyCastFunction, i, session);
break;
}
}
parameterTypes = valueCastFunction.type().parameterArray();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i] == ConnectorSession.class) {
valueCastFunction = MethodHandles.insertArguments(valueCastFunction, i, session);
break;
}
}
TypedSet typedSet = new TypedSet(toKeyType, fromMap.getPositionCount() / 2);
BlockBuilder keyBlockBuilder = toKeyType.createBlockBuilder(new BlockBuilderStatus(), fromMap.getPositionCount() / 2);
for (int i = 0; i < fromMap.getPositionCount(); i += 2) {
Object fromKey = readNativeValue(fromKeyType, fromMap, i);
try {
Object toKey = keyCastFunction.invoke(fromKey);
if (toKey == null) {
throw new PrestoException(StandardErrorCode.INVALID_CAST_ARGUMENT, "map key is null");
}
writeNativeValue(toKeyType, keyBlockBuilder, toKey);
} catch (Throwable t) {
Throwables.propagateIfInstanceOf(t, Error.class);
Throwables.propagateIfInstanceOf(t, PrestoException.class);
throw new PrestoException(StandardErrorCode.GENERIC_INTERNAL_ERROR, t);
}
}
Block keyBlock = keyBlockBuilder.build();
BlockBuilder blockBuilder = new InterleavedBlockBuilder(ImmutableList.of(toKeyType, toValueType), new BlockBuilderStatus(), fromMap.getPositionCount());
for (int i = 0; i < fromMap.getPositionCount(); i += 2) {
if (!typedSet.contains(keyBlock, i / 2)) {
typedSet.add(keyBlock, i / 2);
toKeyType.appendTo(keyBlock, i / 2, blockBuilder);
if (fromMap.isNull(i + 1)) {
blockBuilder.appendNull();
continue;
}
Object fromValue = readNativeValue(fromValueType, fromMap, i + 1);
try {
Object toValue = valueCastFunction.invoke(fromValue);
writeNativeValue(toValueType, blockBuilder, toValue);
} catch (Throwable t) {
Throwables.propagateIfInstanceOf(t, Error.class);
Throwables.propagateIfInstanceOf(t, PrestoException.class);
throw new PrestoException(StandardErrorCode.GENERIC_INTERNAL_ERROR, t);
}
} else {
// if there are duplicated keys, fail it!
throw new PrestoException(StandardErrorCode.INVALID_CAST_ARGUMENT, "duplicate keys");
}
}
return blockBuilder.build();
}
Aggregations