package io.crate.operation.operator; import com.google.common.collect.ImmutableList; import io.crate.analyze.symbol.Function; import io.crate.analyze.symbol.Literal; import io.crate.analyze.symbol.Symbol; import io.crate.analyze.symbol.format.OperatorFormatSpec; import io.crate.metadata.FunctionIdent; import io.crate.metadata.FunctionInfo; import io.crate.metadata.Scalar; import io.crate.metadata.TransactionContext; import io.crate.types.DataType; import io.crate.types.DataTypes; import java.util.Locale; public abstract class Operator<I> extends Scalar<Boolean, I> implements OperatorFormatSpec { public static final io.crate.types.DataType RETURN_TYPE = DataTypes.BOOLEAN; @Override public String operator(Function function) { // strip "op_" from function name return info().ident().name().substring(3).toUpperCase(Locale.ENGLISH); } @Override public Symbol normalizeSymbol(Function function, TransactionContext transactionContext) { // all operators evaluates to NULL if one argument is NULL // let's handle this here to prevent unnecessary collect operations for (Symbol symbol : function.arguments()) { if (isNull(symbol)) { return Literal.NULL; } } return super.normalizeSymbol(function, transactionContext); } private static boolean isNull(Symbol symbol) { return symbol.symbolType().isValueSymbol() && ((Literal) symbol).value() == null; } protected static FunctionInfo generateInfo(String name, DataType type) { return new FunctionInfo(new FunctionIdent(name, ImmutableList.of(type, type)), RETURN_TYPE); } }