use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class DataSizeFunctions method parsePrestoDataSize.
@Description("Converts data size string to bytes")
@ScalarFunction(value = "parse_data_size", alias = "parse_presto_data_size")
@LiteralParameters("x")
@SqlType("decimal(38,0)")
public static Int128 parsePrestoDataSize(@SqlType("varchar(x)") Slice input) {
String dataSize = input.toStringUtf8();
int valueLength = 0;
for (int i = 0; i < dataSize.length(); i++) {
char c = dataSize.charAt(i);
if (isDigit(c) || c == '.') {
valueLength++;
} else {
break;
}
}
if (valueLength == 0) {
throw invalidDataSize(dataSize);
}
BigDecimal value = parseValue(dataSize.substring(0, valueLength), dataSize);
Unit unit = Unit.parse(dataSize.substring(valueLength), dataSize);
BigInteger bytes = value.multiply(unit.getFactor()).toBigInteger();
try {
return Decimals.valueOf(bytes);
} catch (ArithmeticException e) {
throw new TrinoException(NUMERIC_VALUE_OUT_OF_RANGE, format("Value out of range: '%s' ('%sB')", dataSize, bytes));
}
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class DateTimeFunctions method currentDate.
@Description("Current date")
@ScalarFunction
@SqlType(StandardTypes.DATE)
public static long currentDate(ConnectorSession session) {
ISOChronology chronology = getChronology(session.getTimeZoneKey());
// It is ok for this method to use the Object interfaces because it is constant folded during
// plan optimization
LocalDate currentDate = new DateTime(session.getStart().toEpochMilli(), chronology).toLocalDate();
return Days.daysBetween(new LocalDate(1970, 1, 1), currentDate).getDays();
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class IpAddressFunctions method contains.
@Description("Determines whether given IP address exists in the CIDR")
@ScalarFunction
@SqlType(StandardTypes.BOOLEAN)
public static boolean contains(@SqlType(StandardTypes.VARCHAR) Slice network, @SqlType(StandardTypes.IPADDRESS) Slice address) {
String cidr = network.toStringUtf8();
int separator = cidr.indexOf("/");
if (separator == -1) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid CIDR");
}
byte[] base;
boolean isIpv4;
try {
InetAddress inetAddress = InetAddresses.forString(cidr.substring(0, separator));
base = inetAddress.getAddress();
isIpv4 = inetAddress instanceof Inet4Address;
} catch (IllegalArgumentException e) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid network IP address");
}
int prefixLength = Integer.parseInt(cidr.substring(separator + 1));
if (prefixLength < 0) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid prefix length");
}
int baseLength = base.length * Byte.SIZE;
if (prefixLength > baseLength) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Prefix length exceeds address length");
}
if (isIpv4 && !isValidIpV4Cidr(base, prefixLength)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid CIDR");
}
if (!isIpv4 && !isValidIpV6Cidr(prefixLength)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid CIDR");
}
byte[] ipAddress;
try {
ipAddress = InetAddress.getByAddress(address.getBytes()).getAddress();
} catch (UnknownHostException e) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Invalid IP address");
}
if (base.length != ipAddress.length) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "IP address version should be the same");
}
if (prefixLength == 0) {
return true;
}
BigInteger cidrPrefix = new BigInteger(base).shiftRight(baseLength - prefixLength);
BigInteger addressPrefix = new BigInteger(ipAddress).shiftRight(baseLength - prefixLength);
return cidrPrefix.equals(addressPrefix);
}
use of io.trino.spi.function.ScalarFunction in project trino by trinodb.
the class CreateHll method createHll.
@ScalarFunction
@SqlType(StandardTypes.HYPER_LOG_LOG)
public static Slice createHll(@SqlType(StandardTypes.BIGINT) long value) {
HyperLogLog hll = HyperLogLog.newInstance(4096);
hll.add(value);
return hll.serialize();
}
use of io.trino.spi.function.ScalarFunction in project yauaa by nielsbasjes.
the class ParseUserAgentFunctionClientHints method parseUserAgent.
@ScalarFunction("parse_user_agent")
@Description("Tries to parse and analyze the provided useragent string and extract as many attributes " + "as possible. Uses Yauaa (Yet Another UserAgent Analyzer) version " + Version.PROJECT_VERSION + ". " + "See https://yauaa.basjes.nl/udf/trino/ for documentation.")
@SqlType("map(varchar, varchar)")
public static Block parseUserAgent(@SqlType("array(varchar)") Block input) throws IllegalArgumentException {
UserAgentAnalyzer userAgentAnalyzer = threadLocalUserAgentAnalyzer.get();
Map<String, String> requestHeaders = new TreeMap<>();
int i = 0;
int inputLength = input.getPositionCount();
while (i < inputLength) {
Slice parameterSlice = getSlice(input, i);
if (parameterSlice == null) {
throw new IllegalArgumentException("Null argument provided to ParseUserAgent.");
}
String parameter = parameterSlice.toStringUtf8();
if (parameter.isEmpty()) {
throw new IllegalArgumentException("Empty argument provided to ParseUserAgent.");
}
if (userAgentAnalyzer.supportedClientHintHeaders().stream().anyMatch(parameter::equalsIgnoreCase) || USERAGENT_HEADER.equalsIgnoreCase(parameter)) {
String value;
if (i + 1 >= inputLength) {
throw new IllegalArgumentException("Invalid last element in argument list (was a header name which requires a value to follow)");
} else {
value = getSlice(input, i + 1).toStringUtf8();
i++;
}
requestHeaders.put(parameter, value);
i++;
continue;
}
if (i == 0) {
requestHeaders.put(USERAGENT_HEADER, getSlice(input, i).toStringUtf8());
i++;
continue;
}
throw new IllegalArgumentException("Bad argument list for ParseUserAgent: \"" + parameter + "\"");
}
UserAgent userAgent = userAgentAnalyzer.parse(requestHeaders);
Map<String, String> resultMap = userAgent.toMap(userAgentAnalyzer.getAllPossibleFieldNamesSorted());
MapType mapType = new MapType(VARCHAR, VARCHAR, new TypeOperators());
BlockBuilder blockBuilder = mapType.createBlockBuilder(null, resultMap.size());
BlockBuilder singleMapBlockBuilder = blockBuilder.beginBlockEntry();
for (Map.Entry<String, String> entry : resultMap.entrySet()) {
VARCHAR.writeString(singleMapBlockBuilder, entry.getKey());
VARCHAR.writeString(singleMapBlockBuilder, entry.getValue());
}
blockBuilder.closeEntry();
return mapType.getObject(blockBuilder, blockBuilder.getPositionCount() - 1);
}
Aggregations