use of com.facebook.presto.spi.function.SqlNullable in project presto by prestodb.
the class JsonOperators method castToInteger.
@ScalarOperator(CAST)
@SqlNullable
@SqlType(INTEGER)
public static Long castToInteger(@SqlType(JSON) Slice json) {
try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
parser.nextToken();
Long result;
switch(parser.getCurrentToken()) {
case VALUE_NULL:
result = null;
break;
case VALUE_STRING:
result = VarcharOperators.castToInteger(Slices.utf8Slice(parser.getText()));
break;
case VALUE_NUMBER_FLOAT:
result = DoubleOperators.castToInteger(parser.getDoubleValue());
break;
case VALUE_NUMBER_INT:
result = (long) toIntExact(parser.getLongValue());
break;
case VALUE_TRUE:
result = BooleanOperators.castToInteger(true);
break;
case VALUE_FALSE:
result = BooleanOperators.castToInteger(false);
break;
default:
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), INTEGER));
}
// check no trailing token
checkCondition(parser.nextToken() == null, INVALID_CAST_ARGUMENT, "Cannot cast input json to INTEGER");
return result;
} catch (ArithmeticException | IOException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), INTEGER));
}
}
use of com.facebook.presto.spi.function.SqlNullable 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;
}
use of com.facebook.presto.spi.function.SqlNullable 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;
}
use of com.facebook.presto.spi.function.SqlNullable in project presto by prestodb.
the class JsonFunctions method jsonArrayContains.
@SqlNullable
@ScalarFunction
@SqlType(StandardTypes.BOOLEAN)
public static Boolean jsonArrayContains(@SqlType(StandardTypes.JSON) Slice json, @SqlType(StandardTypes.DOUBLE) double value) {
if (!Doubles.isFinite(value)) {
return false;
}
try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
if (parser.nextToken() != START_ARRAY) {
return null;
}
while (true) {
JsonToken token = parser.nextToken();
if (token == null) {
return null;
}
if (token == END_ARRAY) {
return false;
}
parser.skipChildren();
// noinspection FloatingPointEquality
if ((token == VALUE_NUMBER_FLOAT) && (parser.getDoubleValue() == value) && (Doubles.isFinite(parser.getDoubleValue()))) {
return true;
}
}
} catch (IOException e) {
return null;
}
}
use of com.facebook.presto.spi.function.SqlNullable in project presto by prestodb.
the class JsonFunctions method jsonArrayGet.
@SqlNullable
@ScalarFunction
@SqlType(StandardTypes.JSON)
public static Slice jsonArrayGet(@SqlType(StandardTypes.JSON) Slice json, @SqlType(StandardTypes.BIGINT) long index) {
// this value cannot be converted to positive number
if (index == Long.MIN_VALUE) {
return null;
}
try (JsonParser parser = createJsonParser(MAPPING_JSON_FACTORY, json)) {
if (parser.nextToken() != START_ARRAY) {
return null;
}
List<String> tokens = null;
if (index < 0) {
tokens = new LinkedList<>();
}
long count = 0;
while (true) {
JsonToken token = parser.nextToken();
if (token == null) {
return null;
}
if (token == END_ARRAY) {
if (tokens != null && count >= index * -1) {
return utf8Slice(tokens.get(0));
}
return null;
}
String arrayElement;
if (token == START_OBJECT || token == START_ARRAY) {
arrayElement = parser.readValueAsTree().toString();
} else {
arrayElement = parser.getValueAsString();
}
if (count == index) {
return arrayElement == null ? null : utf8Slice(arrayElement);
}
if (tokens != null) {
tokens.add(arrayElement);
if (count >= index * -1) {
tokens.remove(0);
}
}
count++;
}
} catch (IOException e) {
return null;
}
}
Aggregations