[Bug](cast) change binary predicate finally cast to varchar (#11796)

This commit is contained in:
Pxl
2022-08-21 10:13:47 +08:00
committed by GitHub
parent 25b427d0c6
commit 192cdd4d76
5 changed files with 80 additions and 19 deletions

View File

@ -376,18 +376,12 @@ public class BinaryPredicate extends Predicate implements Writable {
// When int column compares with string, Mysql will convert string to int.
// So it is also compatible with Mysql.
if (t1 == PrimitiveType.BIGINT && (t2 == PrimitiveType.VARCHAR || t2 == PrimitiveType.STRING)) {
Expr rightChild = getChild(1);
Long parsedLong = Type.tryParseToLong(rightChild);
if (parsedLong != null) {
return Type.BIGINT;
if (t1.isStringType() || t2.isStringType()) {
if ((t1 == PrimitiveType.BIGINT || t1 == PrimitiveType.LARGEINT) && Type.canParseTo(getChild(1), t1)) {
return Type.fromPrimitiveType(t1);
}
}
if ((t1 == PrimitiveType.VARCHAR || t1 == PrimitiveType.STRING) && t2 == PrimitiveType.BIGINT) {
Expr leftChild = getChild(0);
Long parsedLong = Type.tryParseToLong(leftChild);
if (parsedLong != null) {
return Type.BIGINT;
if ((t2 == PrimitiveType.BIGINT || t2 == PrimitiveType.LARGEINT) && Type.canParseTo(getChild(0), t2)) {
return Type.fromPrimitiveType(t2);
}
}

View File

@ -414,7 +414,6 @@ public class CastExpr extends Expr {
} else if (type.isDecimalV2() || type.isDecimalV3()) {
return new DecimalLiteral(value.getStringValue());
} else if (type.isFloatingPointType()) {
return new FloatLiteral(value.getDoubleValue(), type);
} else if (type.isStringType()) {
return new StringLiteral(value.getStringValue());

View File

@ -18,7 +18,9 @@
package org.apache.doris.catalog;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.LargeIntLiteral;
import org.apache.doris.analysis.StringLiteral;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.Pair;
import org.apache.doris.thrift.TColumnType;
@ -545,15 +547,39 @@ public abstract class Type {
}
/**
* Returns null if this expr is not instance of StringLiteral or StringLiteral
* inner value could not parse to long. otherwise return parsed Long result.
* Returns true if expr is StringLiteral and can parse to valid type, false
* otherwise.
* This function only support LargeInt and BigInt now.
*/
public static Long tryParseToLong(Expr expectStringExpr) {
if (expectStringExpr instanceof StringLiteral) {
String value = ((StringLiteral) expectStringExpr).getValue();
return Longs.tryParse(value);
public static boolean canParseTo(Expr expr, PrimitiveType type) {
if (expr instanceof StringLiteral) {
if (type == PrimitiveType.BIGINT) {
return canParseToBigInt((StringLiteral) expr);
} else if (type == PrimitiveType.LARGEINT) {
return canParseToLargeInt((StringLiteral) expr);
}
}
return null;
return false;
}
/**
* Returns true if expr can parse to valid BigInt, false otherwise.
*/
private static boolean canParseToBigInt(StringLiteral expr) {
String value = ((StringLiteral) expr).getValue();
return Longs.tryParse(value) != null;
}
/**
* Returns true if expr can parse to valid LargeInt, false otherwise.
*/
private static boolean canParseToLargeInt(Expr expr) {
try {
new LargeIntLiteral(((StringLiteral) expr).getValue());
} catch (AnalysisException e) {
return false;
}
return true;
}
/**