Skip to content

Commit

Permalink
KE-11534 [Follow up]KE-42243 merge with new Calcite
Browse files Browse the repository at this point in the history
  • Loading branch information
gleonSun committed Aug 25, 2023
1 parent 8ab4d43 commit 02cb750
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2332,6 +2332,8 @@ private static class BinaryImplementor extends AbstractRexCallImplementor {
final Primitive primitive = Primitive.ofBoxOr(type0);
if (primitive == null
|| type1 == BigDecimal.class
|| backupMethodName.equals("plus")
&& isNumberOrString(type0) && isNumberOrString(type1)
|| COMPARISON_OPERATORS.contains(op)
&& !COMP_OP_TYPES.contains(primitive)) {
return Expressions.call(SqlFunctions.class, backupMethodName,
Expand All @@ -2352,6 +2354,15 @@ private static class BinaryImplementor extends AbstractRexCallImplementor {
argValueList.get(0), argValueList.get(1));
}

// see https://olapio.atlassian.net/browse/KE-42243
private boolean isNumberOrString(Type type) {
if (type == String.class || type == BigDecimal.class) {
return true;
}
Primitive primitive = Primitive.ofBoxOr(type);
return primitive != null && Number.class.isAssignableFrom(primitive.boxClass);
}

/** Returns whether any of a call's operands have ANY type. */
private static boolean anyAnyOperands(RexCall call) {
for (RexNode operand : call.operands) {
Expand Down
20 changes: 13 additions & 7 deletions core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -1006,30 +1006,35 @@ public static int plus(int b0, int b1) {
}

// see https://olapio.atlassian.net/browse/KE-42084
public static Double plus(String s0, String s1) {
// see https://olapio.atlassian.net/browse/KE-42243
public static BigDecimal plus(String s0, String s1) {
try {
return plus(toBigDecimal(s0), toBigDecimal(s1)).doubleValue();
return plus(toBigDecimal(s0), toBigDecimal(s1));
} catch (NumberFormatException ignored) {
return null;
}
}

public static Double plus(String s0, BigDecimal b1) {
public static BigDecimal plus(String s0, BigDecimal b1) {
try {
return plus(toBigDecimal(s0), b1).doubleValue();
return plus(toBigDecimal(s0), b1);
} catch (NumberFormatException ignored) {
return null;
}
}

public static Double plus(String s0, Number b1) {
public static BigDecimal plus(String s0, Number b1) {
return plus(s0, toBigDecimal(b1));
}

public static Double plus(Number b1, String s0) {
public static BigDecimal plus(Number b1, String s0) {
return plus(s0, toBigDecimal(b1));
}

public static BigDecimal plus(Number b1, Number b2) {
return plus(toBigDecimal(b1), toBigDecimal(b2));
}

/** SQL <code>+</code> operator applied to Object values (at least one operand
* has ANY type; either may be null). */
public static @PolyNull Object plusAny(@PolyNull Object b0,
Expand Down Expand Up @@ -2213,7 +2218,8 @@ public static BigDecimal toBigDecimal(String s) {
public static BigDecimal toBigDecimal(Number number) {
// There are some values of "long" that cannot be represented as "double".
// Not so "int". If it isn't a long, go straight to double.
return number instanceof BigDecimal ? (BigDecimal) number
return number == null ? null
: number instanceof BigDecimal ? (BigDecimal) number
: number instanceof BigInteger ? new BigDecimal((BigInteger) number)
: number instanceof Long ? new BigDecimal(number.longValue())
: new BigDecimal(number.doubleValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ protected boolean binaryArithmeticWithStrings(
SqlCallBinding binding,
RelDataType left,
RelDataType right) {
// see https://olapio.atlassian.net/browse/KE-42243
// Calcite's implicit conversion may fail when the operator is "plus" and the left and right
// sides are numeric and string types respectively, which will not be supported in Kylin,
// and the logic is commented out for now.
return false;

// For expression "NUMERIC <OP> CHARACTER",
// PostgreSQL and MS-SQL coerce the CHARACTER operand to NUMERIC,
// i.e. for '9':VARCHAR(1) / 2: INT, '9' would be coerced to INTEGER,
Expand All @@ -183,20 +189,20 @@ protected boolean binaryArithmeticWithStrings(

// Keep sync with PostgreSQL and MS-SQL because their behaviors are more in
// line with the SQL standard.
if (SqlTypeUtil.isString(left) && SqlTypeUtil.isNumeric(right)) {
// If the numeric operand is DECIMAL type, coerce the STRING operand to
// max precision/scale DECIMAL.
if (SqlTypeUtil.isDecimal(right)) {
right = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
}
return coerceOperandType(binding.getScope(), binding.getCall(), 0, right);
} else if (SqlTypeUtil.isNumeric(left) && SqlTypeUtil.isString(right)) {
if (SqlTypeUtil.isDecimal(left)) {
left = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
}
return coerceOperandType(binding.getScope(), binding.getCall(), 1, left);
}
return false;
// if (SqlTypeUtil.isString(left) && SqlTypeUtil.isNumeric(right)) {
// // If the numeric operand is DECIMAL type, coerce the STRING operand to
// // max precision/scale DECIMAL.
// if (SqlTypeUtil.isDecimal(right)) {
// right = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
// }
// return coerceOperandType(binding.getScope(), binding.getCall(), 0, right);
// } else if (SqlTypeUtil.isNumeric(left) && SqlTypeUtil.isString(right)) {
// if (SqlTypeUtil.isDecimal(left)) {
// left = SqlTypeUtil.getMaxPrecisionScaleDecimal(factory);
// }
// return coerceOperandType(binding.getScope(), binding.getCall(), 1, left);
// }
// return false;
}

/**
Expand Down

0 comments on commit 02cb750

Please sign in to comment.