use of com.facebook.presto.spi.function.LiteralParameters in project presto by prestodb.
the class JoniRegexpFunctions method regexpReplace.
@Description("replaces substrings matching a regular expression by given string")
@ScalarFunction
@LiteralParameters({ "x", "y", "z" })
// to get the formula: x + max(x * y / 2, y) * (x + 1)
@Constraint(variable = "z", expression = "min(2147483647, x + max(x * y / 2, y) * (x + 1))")
@SqlType("varchar(z)")
public static Slice regexpReplace(@SqlType("varchar(x)") Slice source, @SqlType(JoniRegexpType.NAME) Regex pattern, @SqlType("varchar(y)") Slice replacement) {
Matcher matcher = pattern.matcher(source.getBytes());
SliceOutput sliceOutput = new DynamicSliceOutput(source.length() + replacement.length() * 5);
int lastEnd = 0;
// nextStart is the same as lastEnd, unless the last match was zero-width. In such case, nextStart is lastEnd + 1.
int nextStart = 0;
while (true) {
int offset = matcher.search(nextStart, source.length(), Option.DEFAULT);
if (offset == -1) {
break;
}
if (matcher.getEnd() == matcher.getBegin()) {
nextStart = matcher.getEnd() + 1;
} else {
nextStart = matcher.getEnd();
}
Slice sliceBetweenReplacements = source.slice(lastEnd, matcher.getBegin() - lastEnd);
lastEnd = matcher.getEnd();
sliceOutput.appendBytes(sliceBetweenReplacements);
appendReplacement(sliceOutput, source, pattern, matcher.getEagerRegion(), replacement);
}
sliceOutput.appendBytes(source.slice(lastEnd, source.length() - lastEnd));
return sliceOutput.slice();
}
use of com.facebook.presto.spi.function.LiteralParameters in project presto by prestodb.
the class JoniRegexpFunctions method regexpExtractAll.
@Description("group(s) extracted using the given pattern")
@ScalarFunction
@LiteralParameters("x")
@SqlType("array(varchar(x))")
public static Block regexpExtractAll(@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());
BlockBuilder blockBuilder = VARCHAR.createBlockBuilder(new BlockBuilderStatus(), 32);
int group = toIntExact(groupIndex);
int nextStart = 0;
while (true) {
int offset = matcher.search(nextStart, source.length(), Option.DEFAULT);
if (offset == -1) {
break;
}
if (matcher.getEnd() == matcher.getBegin()) {
nextStart = matcher.getEnd() + 1;
} else {
nextStart = matcher.getEnd();
}
Region region = matcher.getEagerRegion();
int beg = region.beg[group];
int end = region.end[group];
if (beg == -1 || end == -1) {
blockBuilder.appendNull();
} else {
Slice slice = source.slice(beg, end - beg);
VARCHAR.writeSlice(blockBuilder, slice);
}
}
return blockBuilder.build();
}
use of com.facebook.presto.spi.function.LiteralParameters in project presto by prestodb.
the class JoniRegexpFunctions method regexpLike.
@Description("returns whether the pattern is contained within the string")
@ScalarFunction
@LiteralParameters("x")
@SqlType(StandardTypes.BOOLEAN)
public static boolean regexpLike(@SqlType("varchar(x)") Slice source, @SqlType(JoniRegexpType.NAME) Regex pattern) {
Matcher m = pattern.matcher(source.getBytes());
int offset = m.search(0, source.length(), Option.DEFAULT);
return offset != -1;
}
use of com.facebook.presto.spi.function.LiteralParameters in project presto by prestodb.
the class JsonOperators method castToVarchar.
@ScalarOperator(CAST)
@SqlNullable
@LiteralParameters("x")
@SqlType("varchar(x)")
public static Slice castToVarchar(@SqlType(JSON) Slice json) {
try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
JsonToken nextToken = parser.nextToken();
Slice result;
switch(nextToken) {
case VALUE_NULL:
result = null;
break;
case VALUE_STRING:
result = Slices.utf8Slice(parser.getText());
break;
case VALUE_NUMBER_FLOAT:
// Avoidance of loss of precision does not seem to be possible here because of Jackson implementation.
result = DoubleOperators.castToVarchar(parser.getDoubleValue());
break;
case VALUE_NUMBER_INT:
// An alternative is calling getLongValue and then BigintOperators.castToVarchar.
// It doesn't work as well because it can result in overflow and underflow exceptions for large integral numbers.
result = Slices.utf8Slice(parser.getText());
break;
case VALUE_TRUE:
result = BooleanOperators.castToVarchar(true);
break;
case VALUE_FALSE:
result = BooleanOperators.castToVarchar(false);
break;
default:
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), VARCHAR));
}
// check no trailing token
checkCondition(parser.nextToken() == null, INVALID_CAST_ARGUMENT, "Cannot cast input json to VARCHAR");
return result;
} catch (IOException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), VARCHAR));
}
}
use of com.facebook.presto.spi.function.LiteralParameters 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;
}
Aggregations