[fix](nereids) fix bug in SequenceFunction legality check (#15812)

1. fix bug in sequence_match function
2. do type promotion instead of explicit cast for
  - varcharLiteral -> stringLiteral
  - charLiteral->stringLiteral
This commit is contained in:
minghong
2023-01-13 12:09:53 +08:00
committed by GitHub
parent 34bb9cd5d3
commit 67378a2dc3
5 changed files with 83 additions and 15 deletions

View File

@ -29,13 +29,14 @@ public interface SequenceFunction extends FunctionTrait {
default void checkLegalityBeforeTypeCoercion() {
String functionName = getName();
Expression firstArg = getArgument(0);
if (firstArg instanceof StringLikeLiteral) {
throw new AnalysisException("The pattern params of " + functionName
+ " function must be string literal: " + toSql());
if (!(firstArg instanceof StringLikeLiteral)) {
throw new AnalysisException("The pattern param `" + firstArg.toSql() + "` of " + functionName
+ " function must be string literal, but it is "
+ firstArg.getClass().getSimpleName());
}
if (!getArgumentType(1).isDateType()) {
if (!getArgumentType(1).isDateLikeType()) {
throw new AnalysisException("The timestamp params of " + functionName
+ " function must be DATE or DATETIME");
+ " function must be DATE or DATETIME, but it is " + getArgumentType(1));
}
String pattern = ((StringLikeLiteral) firstArg).getStringValue();
if (!FunctionCallExpr.parsePattern(pattern)) {
@ -44,8 +45,9 @@ public interface SequenceFunction extends FunctionTrait {
for (int i = 2; i < arity(); i++) {
if (!getArgumentType(i).isBooleanType()) {
throw new AnalysisException("The 3th and subsequent params of "
+ functionName + " function must be boolean");
throw new AnalysisException("The param `" + child(i).toSql() + "` of "
+ functionName + " function must be boolean, but it is "
+ getArgumentType(i).getClass().getSimpleName());
}
}
}

View File

@ -27,6 +27,7 @@ import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
import org.apache.doris.nereids.types.coercion.AbstractDataType;
import org.apache.doris.nereids.types.coercion.CharacterType;
import org.apache.doris.nereids.types.coercion.IntegralType;
@ -52,12 +53,14 @@ public abstract class DataType implements AbstractDataType {
protected static final NereidsParser PARSER = new NereidsParser();
// use class and supplier here to avoid class load deadlock.
private static final Map<Class<? extends NumericType>, Supplier<DataType>> PROMOTION_MAP
= ImmutableMap.<Class<? extends NumericType>, Supplier<DataType>>builder()
private static final Map<Class<? extends PrimitiveType>, Supplier<DataType>> PROMOTION_MAP
= ImmutableMap.<Class<? extends PrimitiveType>, Supplier<DataType>>builder()
.put(TinyIntType.class, () -> SmallIntType.INSTANCE)
.put(SmallIntType.class, () -> IntegerType.INSTANCE)
.put(IntegerType.class, () -> BigIntType.INSTANCE)
.put(FloatType.class, () -> DoubleType.INSTANCE)
.put(VarcharType.class, () -> StringType.INSTANCE)
.put(CharType.class, () -> StringType.INSTANCE)
.build();
@Developing("This map is just use to search which itemType of the ArrayType is implicit castable for temporary."
@ -86,11 +89,7 @@ public abstract class DataType implements AbstractDataType {
/**
* create a specific Literal for a given dataType
*/
public static Literal promoteNumberLiteral(Object value, DataType dataType) {
if (! (value instanceof Number)) {
return null;
}
public static Literal promoteLiteral(Object value, DataType dataType) {
if (dataType.equals(SmallIntType.INSTANCE)) {
return new SmallIntLiteral(((Number) value).shortValue());
} else if (dataType.equals(IntegerType.INSTANCE)) {
@ -99,6 +98,8 @@ public abstract class DataType implements AbstractDataType {
return new BigIntLiteral(((Number) value).longValue());
} else if (dataType.equals(DoubleType.INSTANCE)) {
return new DoubleLiteral(((Number) value).doubleValue());
} else if (dataType.equals(StringType.INSTANCE)) {
return new StringLiteral((String) value);
}
return null;
}

View File

@ -380,7 +380,7 @@ public class TypeCoercionUtils {
type = promoted;
}
if (type.equals(dataType)) {
Literal promoted = DataType.promoteNumberLiteral(((Literal) input).getValue(), dataType);
Literal promoted = DataType.promoteLiteral(((Literal) input).getValue(), dataType);
if (promoted != null) {
return promoted;
}