Search in sources :

Example 1 with LiteralParameters

use of io.trino.spi.function.LiteralParameters in project trino by trinodb.

the class StringFunctions method hammingDistance.

@Description("Computes Hamming distance between two strings")
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType(StandardTypes.BIGINT)
public static long hammingDistance(@SqlType("varchar(x)") Slice left, @SqlType("varchar(y)") Slice right) {
    int distance = 0;
    int leftPosition = 0;
    int rightPosition = 0;
    while (leftPosition < left.length() && rightPosition < right.length()) {
        int codePointLeft = tryGetCodePointAt(left, leftPosition);
        int codePointRight = tryGetCodePointAt(right, rightPosition);
        // the following code treats them as equal if they happen to be of the same length
        if (codePointLeft != codePointRight) {
            distance++;
        }
        leftPosition += codePointLeft > 0 ? lengthOfCodePoint(codePointLeft) : -codePointLeft;
        rightPosition += codePointRight > 0 ? lengthOfCodePoint(codePointRight) : -codePointRight;
    }
    checkCondition(leftPosition == left.length() && rightPosition == right.length(), INVALID_FUNCTION_ARGUMENT, "The input strings to hamming_distance function must have the same length");
    return distance;
}
Also used : Constraint(io.trino.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(io.trino.spi.function.ScalarFunction) Description(io.trino.spi.function.Description) LiteralParameters(io.trino.spi.function.LiteralParameters) SqlType(io.trino.spi.function.SqlType)

Example 2 with LiteralParameters

use of io.trino.spi.function.LiteralParameters in project trino by trinodb.

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 TrinoException(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 TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid replacement character");
        }
    } else {
        replacementCodePoint = OptionalInt.empty();
    }
    return SliceUtf8.fixInvalidUtf8(slice, replacementCodePoint);
}
Also used : InvalidUtf8Exception(io.airlift.slice.InvalidUtf8Exception) TrinoException(io.trino.spi.TrinoException) OptionalInt(java.util.OptionalInt) Constraint(io.trino.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(io.trino.spi.function.ScalarFunction) Description(io.trino.spi.function.Description) LiteralParameters(io.trino.spi.function.LiteralParameters) SqlType(io.trino.spi.function.SqlType)

Example 3 with LiteralParameters

use of io.trino.spi.function.LiteralParameters in project trino by trinodb.

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 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(io.trino.type.Constraint) SliceUtf8.lengthOfCodePoint(io.airlift.slice.SliceUtf8.lengthOfCodePoint) SliceUtf8.offsetOfCodePoint(io.airlift.slice.SliceUtf8.offsetOfCodePoint) ScalarFunction(io.trino.spi.function.ScalarFunction) Description(io.trino.spi.function.Description) LiteralParameters(io.trino.spi.function.LiteralParameters) Constraint(io.trino.type.Constraint) SqlType(io.trino.spi.function.SqlType)

Example 4 with LiteralParameters

use of io.trino.spi.function.LiteralParameters in project trino by trinodb.

the class UrlFunctions method urlExtractParameter.

@SqlNullable
@Description("Extract query parameter from url")
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType("varchar(x)")
public static Slice urlExtractParameter(@SqlType("varchar(x)") Slice url, @SqlType("varchar(y)") Slice parameterName) {
    URI uri = parseUrl(url);
    if ((uri == null) || (uri.getRawQuery() == null)) {
        return null;
    }
    String parameter = parameterName.toStringUtf8();
    Iterable<String> queryArgs = QUERY_SPLITTER.split(uri.getRawQuery());
    for (String queryArg : queryArgs) {
        Iterator<String> arg = ARG_SPLITTER.split(queryArg).iterator();
        if (arg.next().equals(parameter)) {
            if (arg.hasNext()) {
                return decodeUrl(arg.next());
            }
            // first matched key is empty
            return Slices.EMPTY_SLICE;
        }
    }
    // no key matched
    return null;
}
Also used : URI(java.net.URI) SqlNullable(io.trino.spi.function.SqlNullable) ScalarFunction(io.trino.spi.function.ScalarFunction) Description(io.trino.spi.function.Description) LiteralParameters(io.trino.spi.function.LiteralParameters) SqlType(io.trino.spi.function.SqlType)

Example 5 with LiteralParameters

use of io.trino.spi.function.LiteralParameters in project trino by trinodb.

the class FormatDateTime method format.

@LiteralParameters({ "x", "p" })
@SqlType(StandardTypes.VARCHAR)
public static Slice format(ConnectorSession session, @SqlType("timestamp(p)") long timestamp, @SqlType("varchar(x)") Slice formatString) {
    // TODO: currently, date formatting only supports up to millis, so we round to that unit
    timestamp = scaleEpochMicrosToMillis(round(timestamp, 3));
    if (datetimeFormatSpecifiesZone(formatString)) {
        // Timezone is unknown for TIMESTAMP w/o TZ so it cannot be printed out.
        throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "format_datetime for TIMESTAMP type, cannot use 'Z' nor 'z' in format, as this type does not contain TZ information");
    }
    ISOChronology chronology = ISOChronology.getInstanceUTC();
    try {
        return utf8Slice(DateTimeFormat.forPattern(formatString.toStringUtf8()).withChronology(chronology).withLocale(session.getLocale()).print(timestamp));
    } catch (Exception e) {
        throw new TrinoException(INVALID_FUNCTION_ARGUMENT, e);
    }
}
Also used : ISOChronology(org.joda.time.chrono.ISOChronology) TrinoException(io.trino.spi.TrinoException) TrinoException(io.trino.spi.TrinoException) LiteralParameters(io.trino.spi.function.LiteralParameters) SqlType(io.trino.spi.function.SqlType)

Aggregations

LiteralParameters (io.trino.spi.function.LiteralParameters)62 SqlType (io.trino.spi.function.SqlType)60 ScalarFunction (io.trino.spi.function.ScalarFunction)25 Constraint (io.trino.type.Constraint)21 Description (io.trino.spi.function.Description)19 TrinoException (io.trino.spi.TrinoException)15 SliceUtf8.lengthOfCodePoint (io.airlift.slice.SliceUtf8.lengthOfCodePoint)11 Matcher (io.airlift.joni.Matcher)9 Slice (io.airlift.slice.Slice)9 SliceUtf8.offsetOfCodePoint (io.airlift.slice.SliceUtf8.offsetOfCodePoint)9 BlockBuilder (io.trino.spi.block.BlockBuilder)9 TimeZoneKey (io.trino.spi.type.TimeZoneKey)9 TimeZoneKey.getTimeZoneKey (io.trino.spi.type.TimeZoneKey.getTimeZoneKey)8 SqlNullable (io.trino.spi.function.SqlNullable)7 ZoneId (java.time.ZoneId)7 ScalarOperator (io.trino.spi.function.ScalarOperator)5 LongTimeWithTimeZone (io.trino.spi.type.LongTimeWithTimeZone)5 ISOChronology (org.joda.time.chrono.ISOChronology)5 DynamicSliceOutput (io.airlift.slice.DynamicSliceOutput)4 Instant (java.time.Instant)4