use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class JsonOperators method castToDouble.
@ScalarOperator(CAST)
@SqlNullable
@SqlType(DOUBLE)
public static Double castToDouble(@SqlType(JSON) Slice json) {
try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
parser.nextToken();
Double result;
switch(parser.getCurrentToken()) {
case VALUE_NULL:
result = null;
break;
case VALUE_STRING:
result = VarcharOperators.castToDouble(Slices.utf8Slice(parser.getText()));
break;
case VALUE_NUMBER_FLOAT:
result = parser.getDoubleValue();
break;
case VALUE_NUMBER_INT:
// An alternative is calling getLongValue and then BigintOperators.castToDouble.
// It doesn't work as well because it can result in overflow and underflow exceptions for large integral numbers.
result = parser.getDoubleValue();
break;
case VALUE_TRUE:
result = BooleanOperators.castToDouble(true);
break;
case VALUE_FALSE:
result = BooleanOperators.castToDouble(false);
break;
default:
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), DOUBLE));
}
// check no trailing token
checkCondition(parser.nextToken() == null, INVALID_CAST_ARGUMENT, "Cannot cast input json to DOUBLE");
return result;
} catch (IOException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), DOUBLE));
}
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
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.getQuery() == null)) {
return null;
}
Slice query = slice(uri.getQuery());
String parameter = parameterName.toStringUtf8();
Iterable<String> queryArgs = QUERY_SPLITTER.split(query.toStringUtf8());
for (String queryArg : queryArgs) {
Iterator<String> arg = ARG_SPLITTER.split(queryArg).iterator();
if (arg.next().equals(parameter)) {
if (arg.hasNext()) {
return utf8Slice(arg.next());
}
// first matched key is empty
return Slices.EMPTY_SLICE;
}
}
// no key matched
return null;
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class VarbinaryFunctions method xxhash64.
@Description("compute xxhash64 hash")
@ScalarFunction
@SqlType(StandardTypes.VARBINARY)
public static Slice xxhash64(@SqlType(StandardTypes.VARBINARY) Slice slice) {
Slice hash = Slices.allocate(Long.BYTES);
hash.setLong(0, Long.reverseBytes(XxHash64.hash(slice)));
return hash;
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class SequenceFunction method sequenceTimestampYearToMonth.
@ScalarFunction("sequence")
@SqlType("array(timestamp)")
public static Block sequenceTimestampYearToMonth(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long start, @SqlType(StandardTypes.TIMESTAMP) long end, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long step) {
checkCondition(step != 0, INVALID_FUNCTION_ARGUMENT, "interval must not be zero");
checkCondition(step > 0 ? end >= start : end <= start, INVALID_FUNCTION_ARGUMENT, "sequence end value should be greater than or equal to start value if step is greater than zero otherwise end should be less than start");
int length = toIntExact(diffTimestamp(session, MONTH, start, end) / step + 1);
BlockBuilder blockBuilder = BIGINT.createBlockBuilder(new BlockBuilderStatus(), length);
int value = 0;
for (int i = 0; i < length; ++i) {
BIGINT.writeLong(blockBuilder, DateTimeOperators.timestampPlusIntervalYearToMonth(session, start, value));
value += step;
}
return blockBuilder.build();
}
use of com.facebook.presto.spi.function.SqlType in project presto by prestodb.
the class StringFunctions method levenshteinDistance.
@Description("computes Levenshtein distance between two strings")
@ScalarFunction
@LiteralParameters({ "x", "y" })
@SqlType(StandardTypes.BIGINT)
public static long levenshteinDistance(@SqlType("varchar(x)") Slice left, @SqlType("varchar(y)") Slice right) {
int[] leftCodePoints = castToCodePoints(left);
int[] rightCodePoints = castToCodePoints(right);
if (leftCodePoints.length < rightCodePoints.length) {
int[] tempCodePoints = leftCodePoints;
leftCodePoints = rightCodePoints;
rightCodePoints = tempCodePoints;
}
if (rightCodePoints.length == 0) {
return leftCodePoints.length;
}
checkCondition((leftCodePoints.length * (rightCodePoints.length - 1)) <= 1_000_000, INVALID_FUNCTION_ARGUMENT, "The combined inputs for Levenshtein distance are too large");
int[] distances = new int[rightCodePoints.length];
for (int i = 0; i < rightCodePoints.length; i++) {
distances[i] = i + 1;
}
for (int i = 0; i < leftCodePoints.length; i++) {
int leftUpDistance = distances[0];
if (leftCodePoints[i] == rightCodePoints[0]) {
distances[0] = i;
} else {
distances[0] = Math.min(i, distances[0]) + 1;
}
for (int j = 1; j < rightCodePoints.length; j++) {
int leftUpDistanceNext = distances[j];
if (leftCodePoints[i] == rightCodePoints[j]) {
distances[j] = leftUpDistance;
} else {
distances[j] = Math.min(distances[j - 1], Math.min(leftUpDistance, distances[j])) + 1;
}
leftUpDistance = leftUpDistanceNext;
}
}
return distances[rightCodePoints.length - 1];
}
Aggregations