Search in sources :

Example 16 with ScalarFunction

use of com.facebook.presto.spi.function.ScalarFunction 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 17 with ScalarFunction

use of com.facebook.presto.spi.function.ScalarFunction 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 18 with ScalarFunction

use of com.facebook.presto.spi.function.ScalarFunction in project presto by prestodb.

the class ScalarImplementationHeader method fromAnnotatedElement.

public static List<ScalarImplementationHeader> fromAnnotatedElement(AnnotatedElement annotated) {
    ScalarFunction scalarFunction = annotated.getAnnotation(ScalarFunction.class);
    ScalarOperator scalarOperator = annotated.getAnnotation(ScalarOperator.class);
    Description descriptionAnnotation = annotated.getAnnotation(Description.class);
    ImmutableList.Builder<ScalarImplementationHeader> builder = ImmutableList.builder();
    Optional<String> description = Optional.empty();
    if (descriptionAnnotation != null) {
        description = Optional.of(descriptionAnnotation.value());
    }
    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;
}
Also used : ScalarOperator(com.facebook.presto.spi.function.ScalarOperator) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) Description(com.facebook.presto.spi.function.Description) ImmutableList(com.google.common.collect.ImmutableList) ScalarHeader(com.facebook.presto.operator.scalar.ScalarHeader)

Example 19 with ScalarFunction

use of com.facebook.presto.spi.function.ScalarFunction in project presto by prestodb.

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

use of com.facebook.presto.spi.function.ScalarFunction in project presto by prestodb.

the class TimestampOperators method castToDate.

@ScalarFunction("date")
@ScalarOperator(CAST)
@SqlType(StandardTypes.DATE)
public static long castToDate(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) {
    // round down the current timestamp to days
    ISOChronology chronology = getChronology(session.getTimeZoneKey());
    long date = chronology.dayOfYear().roundFloor(value);
    // date is currently midnight in timezone of the session
    // convert to UTC
    long millis = date + chronology.getZone().getOffset(date);
    return TimeUnit.MILLISECONDS.toDays(millis);
}
Also used : ISOChronology(org.joda.time.chrono.ISOChronology) ScalarOperator(com.facebook.presto.spi.function.ScalarOperator) ScalarFunction(com.facebook.presto.spi.function.ScalarFunction) SqlType(com.facebook.presto.spi.function.SqlType)

Aggregations

ScalarFunction (com.facebook.presto.spi.function.ScalarFunction)37 SqlType (com.facebook.presto.spi.function.SqlType)36 Description (com.facebook.presto.spi.function.Description)19 LiteralParameters (com.facebook.presto.spi.function.LiteralParameters)17 Constraint (com.facebook.presto.type.Constraint)15 Slice (io.airlift.slice.Slice)10 SqlNullable (com.facebook.presto.spi.function.SqlNullable)9 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)7 BlockBuilderStatus (com.facebook.presto.spi.block.BlockBuilderStatus)7 SliceUtf8.lengthOfCodePoint (io.airlift.slice.SliceUtf8.lengthOfCodePoint)7 SliceUtf8.offsetOfCodePoint (io.airlift.slice.SliceUtf8.offsetOfCodePoint)7 IOException (java.io.IOException)7 PrestoException (com.facebook.presto.spi.PrestoException)6 JsonUtil.createJsonParser (com.facebook.presto.util.JsonUtil.createJsonParser)6 JsonParser (com.fasterxml.jackson.core.JsonParser)6 JsonToken (com.fasterxml.jackson.core.JsonToken)6 Matcher (io.airlift.joni.Matcher)5 ISOChronology (org.joda.time.chrono.ISOChronology)4 ScalarOperator (com.facebook.presto.spi.function.ScalarOperator)3 Slices.utf8Slice (io.airlift.slice.Slices.utf8Slice)3