use of io.trino.spi.TrinoException in project trino by trinodb.
the class SplitToMapFunction method splitToMap.
@SqlType("map(varchar,varchar)")
public Block splitToMap(@TypeParameter("map(varchar,varchar)") Type mapType, @SqlType(StandardTypes.VARCHAR) Slice string, @SqlType(StandardTypes.VARCHAR) Slice entryDelimiter, @SqlType(StandardTypes.VARCHAR) Slice keyValueDelimiter) {
checkCondition(entryDelimiter.length() > 0, INVALID_FUNCTION_ARGUMENT, "entryDelimiter is empty");
checkCondition(keyValueDelimiter.length() > 0, INVALID_FUNCTION_ARGUMENT, "keyValueDelimiter is empty");
checkCondition(!entryDelimiter.equals(keyValueDelimiter), INVALID_FUNCTION_ARGUMENT, "entryDelimiter and keyValueDelimiter must not be the same");
Map<Slice, Slice> map = new HashMap<>();
int entryStart = 0;
while (entryStart < string.length()) {
// Extract key-value pair based on current index
// then add the pair if it can be split by keyValueDelimiter
Slice keyValuePair;
int entryEnd = string.indexOf(entryDelimiter, entryStart);
if (entryEnd >= 0) {
keyValuePair = string.slice(entryStart, entryEnd - entryStart);
} else {
// The rest of the string is the last possible pair.
keyValuePair = string.slice(entryStart, string.length() - entryStart);
}
int keyEnd = keyValuePair.indexOf(keyValueDelimiter);
if (keyEnd >= 0) {
int valueStart = keyEnd + keyValueDelimiter.length();
Slice key = keyValuePair.slice(0, keyEnd);
Slice value = keyValuePair.slice(valueStart, keyValuePair.length() - valueStart);
if (value.indexOf(keyValueDelimiter) >= 0) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Key-value delimiter must appear exactly once in each entry. Bad input: '" + keyValuePair.toStringUtf8() + "'");
}
if (map.containsKey(key)) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Duplicate keys (%s) are not allowed", key.toStringUtf8()));
}
map.put(key, value);
} else {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "Key-value delimiter must appear exactly once in each entry. Bad input: '" + keyValuePair.toStringUtf8() + "'");
}
if (entryEnd < 0) {
// No more pairs to add
break;
}
// Next possible pair is placed next to the current entryDelimiter
entryStart = entryEnd + entryDelimiter.length();
}
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
BlockBuilder singleMapBlockBuilder = blockBuilder.beginBlockEntry();
for (Map.Entry<Slice, Slice> entry : map.entrySet()) {
VARCHAR.writeSlice(singleMapBlockBuilder, entry.getKey());
VARCHAR.writeSlice(singleMapBlockBuilder, entry.getValue());
}
blockBuilder.closeEntry();
pageBuilder.declarePosition();
return (Block) mapType.getObject(blockBuilder, blockBuilder.getPositionCount() - 1);
}
use of io.trino.spi.TrinoException in project trino by trinodb.
the class StringFunctions method stringPositionFromEnd.
private static long stringPositionFromEnd(Slice string, Slice substring, long instance) {
if (instance <= 0) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "'instance' must be a positive or negative number.");
}
if (substring.length() == 0) {
return 1;
}
int foundInstances = 0;
int index = string.length();
do {
// step backwards through string
index = string.toStringUtf8().lastIndexOf(substring.toStringUtf8(), index - 1);
if (index < 0) {
return 0;
}
foundInstances++;
} while (foundInstances < instance);
return index + 1;
}
use of io.trino.spi.TrinoException 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);
}
use of io.trino.spi.TrinoException 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);
}
}
use of io.trino.spi.TrinoException in project trino by trinodb.
the class WithTimeZone method shortPrecision.
@LiteralParameters({ "x", "p" })
@SqlType("timestamp(p) with time zone")
public static long shortPrecision(@LiteralParameter("p") long precision, @SqlType("timestamp(p)") long timestamp, @SqlType("varchar(x)") Slice zoneId) {
verify(precision <= 3, "Expected precision <= 3");
TimeZoneKey toTimeZoneKey;
try {
toTimeZoneKey = getTimeZoneKey(zoneId.toStringUtf8());
} catch (TimeZoneNotSupportedException e) {
throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("'%s' is not a valid time zone", zoneId.toStringUtf8()));
}
DateTimeZone toDateTimeZone = getDateTimeZone(toTimeZoneKey);
return packDateTimeWithZone(UTC.getMillisKeepLocal(toDateTimeZone, scaleEpochMicrosToMillis(timestamp)), toTimeZoneKey);
}
Aggregations