Search in sources :

Example 36 with SqlType

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);
}
Also used : InvalidUtf8Exception(io.airlift.slice.InvalidUtf8Exception) PrestoException(com.facebook.presto.spi.PrestoException) OptionalInt(java.util.OptionalInt) Constraint(com.facebook.presto.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) Description(com.facebook.presto.spi.function.Description) LiteralParameters(com.facebook.presto.spi.function.LiteralParameters) SqlType(com.facebook.presto.spi.function.SqlType)

Example 37 with SqlType

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);
}
Also used : Slice(io.airlift.slice.Slice) Slices.utf8Slice(io.airlift.slice.Slices.utf8Slice) Constraint(com.facebook.presto.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) Description(com.facebook.presto.spi.function.Description) LiteralParameters(com.facebook.presto.spi.function.LiteralParameters) Constraint(com.facebook.presto.type.Constraint) SqlType(com.facebook.presto.spi.function.SqlType)

Example 38 with SqlType

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();
}
Also used : HyperLogLog(io.airlift.stats.cardinality.HyperLogLog) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) SqlType(com.facebook.presto.spi.function.SqlType)

Example 39 with SqlType

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);
}
Also used : Constraint(com.facebook.presto.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) Description(com.facebook.presto.spi.function.Description) LiteralParameters(com.facebook.presto.spi.function.LiteralParameters) SqlType(com.facebook.presto.spi.function.SqlType)

Example 40 with SqlType

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();
}
Also used : TypedSet(com.facebook.presto.operator.aggregation.TypedSet) Block(com.facebook.presto.spi.block.Block) PrestoException(com.facebook.presto.spi.PrestoException) InterleavedBlockBuilder(com.facebook.presto.spi.block.InterleavedBlockBuilder) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder) InterleavedBlockBuilder(com.facebook.presto.spi.block.InterleavedBlockBuilder) BlockBuilderStatus(com.facebook.presto.spi.block.BlockBuilderStatus) TypeParameter(com.facebook.presto.spi.function.TypeParameter) SqlType(com.facebook.presto.spi.function.SqlType)

Aggregations

SqlType (com.facebook.presto.spi.function.SqlType)74 ScalarFunction (com.facebook.presto.spi.function.ScalarFunction)36 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)24 TypeParameter (com.facebook.presto.spi.function.TypeParameter)24 PrestoException (com.facebook.presto.spi.PrestoException)22 BlockBuilderStatus (com.facebook.presto.spi.block.BlockBuilderStatus)20 LiteralParameters (com.facebook.presto.spi.function.LiteralParameters)19 Description (com.facebook.presto.spi.function.Description)18 Constraint (com.facebook.presto.type.Constraint)15 SqlNullable (com.facebook.presto.spi.function.SqlNullable)14 Slice (io.airlift.slice.Slice)13 IOException (java.io.IOException)12 ScalarOperator (com.facebook.presto.spi.function.ScalarOperator)11 JsonUtil.createJsonParser (com.facebook.presto.util.JsonUtil.createJsonParser)11 JsonParser (com.fasterxml.jackson.core.JsonParser)11 TypeParameterSpecialization (com.facebook.presto.spi.function.TypeParameterSpecialization)9 JsonToken (com.fasterxml.jackson.core.JsonToken)7 SliceUtf8.offsetOfCodePoint (io.airlift.slice.SliceUtf8.offsetOfCodePoint)7 SliceUtf8.lengthOfCodePoint (io.airlift.slice.SliceUtf8.lengthOfCodePoint)6 TypedSet (com.facebook.presto.operator.aggregation.TypedSet)5