Skip to content

Commit

Permalink
Refactor all regex scalars to new function registry
Browse files Browse the repository at this point in the history
  • Loading branch information
seut authored and mergify[bot] committed Mar 30, 2020
1 parent ddfafbe commit 2cc9652
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,50 @@
import io.crate.expression.symbol.Literal;
import io.crate.expression.symbol.Symbol;
import io.crate.expression.symbol.SymbolType;
import io.crate.metadata.BaseFunctionResolver;
import io.crate.metadata.FunctionIdent;
import io.crate.metadata.FunctionImplementation;
import io.crate.metadata.FunctionInfo;
import io.crate.metadata.Scalar;
import io.crate.metadata.TransactionContext;
import io.crate.metadata.functions.params.FuncParams;
import io.crate.metadata.functions.params.Param;
import io.crate.types.ArrayType;
import io.crate.types.DataType;
import io.crate.metadata.functions.Signature;
import io.crate.types.DataTypes;

import java.util.List;

import static io.crate.types.TypeSignature.parseTypeSignature;

public class MatchesFunction extends Scalar<List<String>, Object> {

public static final String NAME = "regexp_matches";
private static final ArrayType<String> ARRAY_STRING_TYPE = new ArrayType<>(DataTypes.STRING);

private FunctionInfo info;
private RegexMatcher regexMatcher;

public static void register(ScalarFunctionModule module) {
module.register(NAME,
new BaseFunctionResolver(
FuncParams.builder(Param.STRING, Param.STRING)
.withVarArgs(Param.STRING).limitVarArgOccurrences(1)
.build()) {

@Override
public FunctionImplementation getForTypes(List<DataType> dataTypes) throws IllegalArgumentException {
DataType<?> innerType = dataTypes.get(0);
return new MatchesFunction(
new FunctionInfo(new FunctionIdent(NAME, dataTypes), new ArrayType<>(innerType)));
}
});
module.register(
Signature.scalar(
NAME,
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("array(text)")
),
args ->
new MatchesFunction(
new FunctionInfo(new FunctionIdent(NAME, args), DataTypes.STRING_ARRAY)
)
);
module.register(
Signature.scalar(
NAME,
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("array(text)")
),
args ->
new MatchesFunction(
new FunctionInfo(new FunctionIdent(NAME, args), DataTypes.STRING_ARRAY)
)
);
}

private MatchesFunction(FunctionInfo info) {
Expand Down Expand Up @@ -102,7 +110,7 @@ public Symbol normalizeSymbol(Function symbol, TransactionContext txnCtx) {
if (size == 3) {
args[2] = (Input) symbol.arguments().get(2);
}
return Literal.of(evaluate(txnCtx, args), ARRAY_STRING_TYPE);
return Literal.of(evaluate(txnCtx, args), DataTypes.STRING_ARRAY);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,54 @@

import io.crate.data.Input;
import io.crate.expression.scalar.ScalarFunctionModule;
import io.crate.expression.symbol.FuncArg;
import io.crate.expression.symbol.Function;
import io.crate.expression.symbol.Literal;
import io.crate.expression.symbol.Symbol;
import io.crate.metadata.FunctionIdent;
import io.crate.metadata.FunctionImplementation;
import io.crate.metadata.FunctionInfo;
import io.crate.metadata.FunctionResolver;
import io.crate.metadata.TransactionContext;
import io.crate.metadata.Scalar;
import io.crate.metadata.functions.params.FuncParams;
import io.crate.metadata.functions.params.Param;
import io.crate.types.DataType;
import io.crate.metadata.TransactionContext;
import io.crate.metadata.functions.Signature;
import io.crate.types.DataTypes;

import javax.annotation.Nullable;
import java.util.List;

public class RegexpReplaceFunction extends Scalar<String, Object> implements FunctionResolver {

public static final String NAME = "regexp_replace";
import static io.crate.types.TypeSignature.parseTypeSignature;

private final FuncParams funcParams = FuncParams.builder(
Param.STRING, Param.STRING, Param.STRING)
.withVarArgs(Param.STRING).limitVarArgOccurrences(1)
.build();
public class RegexpReplaceFunction extends Scalar<String, Object> {

private static FunctionInfo createInfo(List<DataType> types) {
return new FunctionInfo(new FunctionIdent(NAME, types), DataTypes.STRING);
}
public static final String NAME = "regexp_replace";

public static void register(ScalarFunctionModule module) {
module.register(NAME, new RegexpReplaceFunction());
module.register(
Signature.scalar(
NAME,
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text")
),
args ->
new RegexpReplaceFunction(new FunctionInfo(new FunctionIdent(NAME, args), DataTypes.STRING))
);
module.register(
Signature.scalar(
NAME,
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text"),
parseTypeSignature("text")
),
args ->
new RegexpReplaceFunction(new FunctionInfo(new FunctionIdent(NAME, args), DataTypes.STRING))
);
}

private FunctionInfo info;
private RegexMatcher regexMatcher;

private RegexpReplaceFunction() {
}

private RegexpReplaceFunction(FunctionInfo info) {
this.info = info;
}
Expand Down Expand Up @@ -143,17 +150,6 @@ public String evaluate(TransactionContext txnCtx, Input[] args) {
return matcher.replace(val, replacement);
}

@Override
public FunctionImplementation getForTypes(List<DataType> dataTypes) throws IllegalArgumentException {
return new RegexpReplaceFunction(createInfo(dataTypes));
}

@Nullable
@Override
public List<DataType> getSignature(List<? extends FuncArg> dataTypes) {
return funcParams.match(dataTypes);
}

private static String eval(String value, String pattern, String replacement, @Nullable String flags) {
RegexMatcher regexMatcher = new RegexMatcher(pattern, flags);
return regexMatcher.replace(value, replacement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ public void testNormalizeSymbolWithInvalidNumberOfArguments() throws Exception {

@Test
public void testNormalizeSymbolWithInvalidArgumentType() {
expectedException.expect(ConversionException.class);
expectedException.expectMessage("Cannot cast `'foobar'` of type `text` to type `bigint_array`");
expectedException.expect(UnsupportedOperationException.class);
expectedException.expectMessage("unknown function: regexp_replace(text, text, bigint_array)");

assertNormalize("regexp_replace('foobar', '.*', [1,2])", isLiteral(""));
}
Expand Down

0 comments on commit 2cc9652

Please sign in to comment.