diff --git a/coding/src/test/java/io/dingodb/expr/coding/TestExprCoder.java b/coding/src/test/java/io/dingodb/expr/coding/TestExprCoder.java index 0c143e00..4bc3b1eb 100644 --- a/coding/src/test/java/io/dingodb/expr/coding/TestExprCoder.java +++ b/coding/src/test/java/io/dingodb/expr/coding/TestExprCoder.java @@ -57,16 +57,21 @@ public class TestExprCoder { arguments(val(3.1415926), "15400921FB4D12D84A"), arguments(val(3E8), "1541B1E1A300000000"), arguments(val("abc"), "1703616263"), - arguments(op(ADD, val(1), val(1)), "110111018301"), - arguments(op(ADD, val(2), val(3)), "110211038301"), + + //{CAST{ CONST{1} -> BIGINT}} BIGINT_ADD {CAST{ CONST{1} -> BIGINT}} + arguments(op(ADD, val(1), val(1)), "1101F0211101F0218302"), + + //{CAST{{CONST INT} 2 -> BIGINT} BIGINT_ADD CAST{{CONST INT} 3 -> BIGINT}} + arguments(op(ADD, val(2), val(3)), "1102f0211103f0218302"), + arguments(op(ADD, val(1L), val(1L)), "120112018302"), arguments(op(ADD, val(2L), val(3L)), "120212038302"), - arguments(op(ADD, val(3), op(MUL, val(4), val(6))), "11031104110685018301"), - arguments(op(EQ, op(ADD, val(5), val(6)), val(11)), "110511068301110B9101"), + arguments(op(ADD, val(3), op(MUL, val(4), val(6))), "11031104F0211106F0218502"), + arguments(op(EQ, op(ADD, val(5), val(6)), val(11)), "1105F0211106F0218302110BF0219102"), arguments(op(GT, val("abc"), val("a")), "17036162631701619307"), arguments( op(AND, op(GT, op(ADD, val(7), val(8)), val(14)), op(LT, val(6), val(5))), - "110711088301110E930111061105950152" + "1107F0211108F0218302110EF021930211061105950152" ), arguments(op(TO_LONG, val(21)), "1115F021"), arguments(op(AND, val(false), val(null, Types.BOOL)), "230352"), diff --git a/runtime/src/main/java/io/dingodb/expr/runtime/op/BinaryOp.java b/runtime/src/main/java/io/dingodb/expr/runtime/op/BinaryOp.java index 8ae7d1e9..b432cbdc 100644 --- a/runtime/src/main/java/io/dingodb/expr/runtime/op/BinaryOp.java +++ b/runtime/src/main/java/io/dingodb/expr/runtime/op/BinaryOp.java @@ -16,7 +16,10 @@ package io.dingodb.expr.runtime.op; +import io.dingodb.expr.common.type.FloatType; +import io.dingodb.expr.common.type.IntType; import io.dingodb.expr.common.type.Type; +import io.dingodb.expr.common.type.Types; import io.dingodb.expr.runtime.EvalContext; import io.dingodb.expr.runtime.ExprConfig; import io.dingodb.expr.runtime.exception.EvalNotImplemented; @@ -63,10 +66,33 @@ public OpKey bestKeyOf(@NonNull Type @NonNull [] types) { Type type0 = operand0.getType(); Type type1 = operand1.getType(); BinaryOp op = getOp(keyOf(type0, type1)); - if (op != null) { + boolean needCast = false; + + if (op != null && type0 instanceof IntType && type1 instanceof IntType + && (op.getOpType() == OpType.ADD || op.getOpType() == OpType.SUB + || op.getOpType() == OpType.MUL || op.getOpType() == OpType.DIV)) { + needCast = true; + } else if (op != null && type0 instanceof FloatType && type1 instanceof FloatType + && (op.getOpType() == OpType.ADD || op.getOpType() == OpType.SUB + || op.getOpType() == OpType.MUL || op.getOpType() == OpType.DIV)) { + needCast = true; + } + + if (op != null && !needCast) { result = op.createExpr(operand0, operand1); } else { - Type[] types = new Type[]{type0, type1}; + Type[] types; + if (op != null && type0 instanceof IntType && type1 instanceof IntType + && (op.getOpType() == OpType.ADD || op.getOpType() == OpType.SUB || op.getOpType() == OpType.MUL)) { + types = new Type[]{Types.LONG, Types.LONG}; + } else if (op != null && type0 instanceof FloatType && type1 instanceof FloatType + && (op.getOpType() == OpType.ADD || op.getOpType() == OpType.SUB + || op.getOpType() == OpType.MUL || op.getOpType() == OpType.DIV)) { + types = new Type[]{Types.DOUBLE, Types.DOUBLE}; + } else { + types = new Type[]{type0, type1}; + } + BinaryOp op1 = getOp(bestKeyOf(types)); if (op1 != null) { result = op1.createExpr(doCast(operand0, types[0], config), doCast(operand1, types[1], config)); diff --git a/test/src/test/java/io/dingodb/expr/test/TestToDebugString.java b/test/src/test/java/io/dingodb/expr/test/TestToDebugString.java index 2a8c5764..473970ac 100644 --- a/test/src/test/java/io/dingodb/expr/test/TestToDebugString.java +++ b/test/src/test/java/io/dingodb/expr/test/TestToDebugString.java @@ -47,9 +47,24 @@ public class TestToDebugString { private static @NonNull Stream getParameters1() { return Stream.of( - arguments("1 + 2", "AddIntInt[ADD](Val[1, INT], Val[2, INT])"), - arguments("1 + 2*3", "AddIntInt[ADD](Val[1, INT], MulIntInt[MUL](Val[2, INT], Val[3, INT]))"), - arguments("1*(2 + 3)", "MulIntInt[MUL](Val[1, INT], AddIntInt[ADD](Val[2, INT], Val[3, INT]))") + arguments("1 + 2", + "AddLongLong[ADD](" + + + "LongCastInt[CASTLONG](Val[1, INT]), " + + + "LongCastInt[CASTLONG](Val[2, INT]))"), + arguments("1 + 2*3", + "AddAnyAny[ADD](" + + + "Val[1, INT], MulLongLong[MUL](LongCastInt[CASTLONG](Val[2, INT]), " + + + "LongCastInt[CASTLONG](Val[3, INT])))"), + arguments("1*(2 + 3)", + "MulLongLong[MUL](" + + + "LongCastInt[CASTLONG](Val[1, INT]), " + + + "AddLongLong[ADD](LongCastInt[CASTLONG](Val[2, INT]), LongCastInt[CASTLONG](Val[3, INT])))") ); } diff --git a/test/src/test/java/io/dingodb/expr/test/TestToString.java b/test/src/test/java/io/dingodb/expr/test/TestToString.java index 6962ce19..955fe95f 100644 --- a/test/src/test/java/io/dingodb/expr/test/TestToString.java +++ b/test/src/test/java/io/dingodb/expr/test/TestToString.java @@ -61,9 +61,10 @@ public class TestToString { private static @NonNull Stream getParameters1() { return Stream.of( - arguments("1 + 2", "1 + 2"), - arguments("1 + 2*3", "1 + 2*3"), - arguments("1*(2 + 3)", "1*(2 + 3)"), + arguments("1 + 2", "CASTLONG(1) + CASTLONG(2)"), + arguments("1 + 2*3", "1 + CASTLONG(2)*CASTLONG(3)"), + arguments("1*(2 + 3)", + "CASTLONG(1)*(CASTLONG(2) + CASTLONG(3))"), arguments("1 < 2 && 3 < 4 || false", "1 < 2 && 3 < 4 || false"), //arguments("5 + a*3.2 - 1.0", "CASTDECIMAL(5) + CASTDECIMAL($[0])*3.2 - 1.0"), //arguments("(a + (c + b)) * max(a, b)", @@ -91,9 +92,9 @@ public class TestToString { private static @NonNull Stream getParameters2() { return Stream.of( - arguments("1 + 2", "3"), - arguments("1 + 2*3", "7"), - arguments("1*(2 + 3)", "5"), + arguments("1 + 2", "LONG(3)"), + arguments("1 + 2*3", "LONG(7)"), + arguments("1*(2 + 3)", "LONG(5)"), arguments("1 < 2 && 3 < 4 or false", "true"), //arguments("5 + a*3.2 - 1.0", "DECIMAL(5) + CASTDECIMAL($[0])*3.2 - 1.0"), //arguments("(a + (c + b)) * max(a, b)", diff --git a/test/src/test/java/io/dingodb/expr/test/cases/EvalConstProvider.java b/test/src/test/java/io/dingodb/expr/test/cases/EvalConstProvider.java index a1d2f9c8..a2115794 100644 --- a/test/src/test/java/io/dingodb/expr/test/cases/EvalConstProvider.java +++ b/test/src/test/java/io/dingodb/expr/test/cases/EvalConstProvider.java @@ -302,9 +302,9 @@ public Stream provideArguments(ExtensionContext context) { arguments(op(NEG, 1.1f), -1.1f), arguments(op(NEG, 1.1), -1.1), arguments(op(NEG, dec(1.1)), BigDecimal.valueOf(-1.1)), - arguments(op(ADD, 1, 2), 3), + arguments(op(ADD, 1, 2), 3L), arguments(op(ADD, 1L, 2L), 3L), - arguments(op(ADD, 1.1f, 2.2f), 3.3f), + arguments(op(ADD, 1.1f, 2.2f), 3.3d), arguments(op(ADD, 1.1, 2.2), 3.3), arguments(op(ADD, dec(1.1), dec(2.2)), BigDecimal.valueOf(3.3)), arguments(op(ADD, 1, 2L), 3L), @@ -312,18 +312,18 @@ public Stream provideArguments(ExtensionContext context) { arguments(op(ADD, 1.1f, 2.2), 3.3), arguments(op(ADD, 1.1, dec(2.2)), BigDecimal.valueOf(3.3)), //arguments(op(ADD, "a", "bc"), "0"), - arguments(op(SUB, 1, 2), -1), + arguments(op(SUB, 1, 2), -1L), arguments(op(SUB, 1L, 2L), -1L), - arguments(op(SUB, 1.1f, 2.2f), -1.1f), + arguments(op(SUB, 1.1f, 2.2f), -1.1d), arguments(op(SUB, 1.1, 2.2), -1.1), arguments(op(SUB, dec(1.1), dec(2.2)), BigDecimal.valueOf(-1.1)), arguments(op(SUB, 1, 2L), -1L), arguments(op(SUB, 1L, 2.2f), -1.2f), arguments(op(SUB, 1.1f, 2.2), -1.1), arguments(op(SUB, 1.1, dec(2.2)), BigDecimal.valueOf(-1.1)), - arguments(op(MUL, 1, 2), 2), + arguments(op(MUL, 1, 2), 2L), arguments(op(MUL, 1L, 2L), 2L), - arguments(op(MUL, 1.1f, 2.2f), 2.42f), + arguments(op(MUL, 1.1f, 2.2f), 2.42d), arguments(op(MUL, 1.1, 2.2), 2.42), arguments(op(MUL, dec(1.1), dec(2.2)), BigDecimal.valueOf(2.42)), arguments(op(MUL, 1, 2L), 2L), @@ -332,7 +332,7 @@ public Stream provideArguments(ExtensionContext context) { arguments(op(MUL, 1.1, dec(2.2)), BigDecimal.valueOf(2.42)), //arguments(op(DIV, 1, 2), 0.5), //arguments(op(DIV, 1L, 2L), 0.5), - arguments(op(DIV, 1.1f, 2.2f), 0.5f), + arguments(op(DIV, 1.1f, 2.2f), 0.5d), arguments(op(DIV, 1.1, 2.2), 0.5), arguments(op(DIV, dec(1.1), dec(2.2)), BigDecimal.valueOf(0.5).setScale(5)), //arguments(op(DIV, 1, 2L), 0.5), diff --git a/test/src/test/java/io/dingodb/expr/test/cases/ParseEvalConstProvider.java b/test/src/test/java/io/dingodb/expr/test/cases/ParseEvalConstProvider.java index 95625030..38afc3e7 100644 --- a/test/src/test/java/io/dingodb/expr/test/cases/ParseEvalConstProvider.java +++ b/test/src/test/java/io/dingodb/expr/test/cases/ParseEvalConstProvider.java @@ -89,18 +89,18 @@ public Stream provideArguments(ExtensionContext context) { // Arithmetics arguments("+ null", null), arguments("- null", null), - arguments("1 + 2", 3), + arguments("1 + 2", 3L), arguments("null + null", null), - arguments("1 + 2 * 3", 7), - arguments("(1 + 2) * 3", 9), - arguments("(1 + 2) * (5 - (3 + 4))", -6), + arguments("1 + 2 * 3", 7L), + arguments("(1 + 2) * 3", 9L), + arguments("(1 + 2) * (5 - (3 + 4))", -6L), arguments("3 * 1.5 + 2.34", new BigDecimal("6.84")), arguments("2 * -3.14e2", new BigDecimal("-6.28e2")), arguments("5e4 + 3e3", new BigDecimal("5.3e4")), //arguments("1 / 100", 0.01), arguments("1.0 / 100", new BigDecimal("0.01000")), arguments("double(1.0) / 100", 0.01), - arguments("1 + (2 * 3-4)", 3), + arguments("1 + (2 * 3-4)", 3L), // Relations & logics arguments("3 < 4", true),