Search in sources :

Example 11 with LiteralParameters

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

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

Example 12 with LiteralParameters

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

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

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

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

the class JoniRegexpFunctions method regexpExtract.

@SqlNullable
@Description("returns regex group of extracted string with a pattern")
@ScalarFunction
@LiteralParameters("x")
@SqlType("varchar(x)")
public static Slice regexpExtract(@SqlType("varchar(x)") Slice source, @SqlType(JoniRegexpType.NAME) Regex pattern, @SqlType(StandardTypes.BIGINT) long groupIndex) {
    Matcher matcher = pattern.matcher(source.getBytes());
    validateGroup(groupIndex, matcher.getEagerRegion());
    int group = toIntExact(groupIndex);
    int offset = matcher.search(0, source.length(), Option.DEFAULT);
    if (offset == -1) {
        return null;
    }
    Region region = matcher.getEagerRegion();
    int beg = region.beg[group];
    int end = region.end[group];
    if (beg == -1) {
        // end == -1 must be true
        return null;
    }
    Slice slice = source.slice(beg, end - beg);
    return slice;
}
Also used : Matcher(io.airlift.joni.Matcher) Slice(io.airlift.slice.Slice) Region(io.airlift.joni.Region) Constraint(com.facebook.presto.type.Constraint) 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)

Aggregations

LiteralParameters (com.facebook.presto.spi.function.LiteralParameters)21 SqlType (com.facebook.presto.spi.function.SqlType)19 ScalarFunction (com.facebook.presto.spi.function.ScalarFunction)17 Description (com.facebook.presto.spi.function.Description)12 Constraint (com.facebook.presto.type.Constraint)12 Slice (io.airlift.slice.Slice)8 SliceUtf8.offsetOfCodePoint (io.airlift.slice.SliceUtf8.offsetOfCodePoint)7 SliceUtf8.lengthOfCodePoint (io.airlift.slice.SliceUtf8.lengthOfCodePoint)6 PrestoException (com.facebook.presto.spi.PrestoException)5 SqlNullable (com.facebook.presto.spi.function.SqlNullable)5 Matcher (io.airlift.joni.Matcher)5 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)3 BlockBuilderStatus (com.facebook.presto.spi.block.BlockBuilderStatus)3 IOException (java.io.IOException)3 ScalarOperator (com.facebook.presto.spi.function.ScalarOperator)2 JsonUtil.createJsonParser (com.facebook.presto.util.JsonUtil.createJsonParser)2 JsonParser (com.fasterxml.jackson.core.JsonParser)2 JsonToken (com.fasterxml.jackson.core.JsonToken)2 Region (io.airlift.joni.Region)2 DynamicSliceOutput (io.airlift.slice.DynamicSliceOutput)2