diff --git hplsql/src/main/java/org/apache/hive/hplsql/Expression.java hplsql/src/main/java/org/apache/hive/hplsql/Expression.java index c10f702..735c413 100644 --- hplsql/src/main/java/org/apache/hive/hplsql/Expression.java +++ hplsql/src/main/java/org/apache/hive/hplsql/Expression.java @@ -18,6 +18,7 @@ package org.apache.hive.hplsql; +import java.math.BigDecimal; import java.sql.Date; import java.sql.Timestamp; import java.util.Calendar; @@ -338,6 +339,12 @@ public void operatorAdd(HplsqlParser.ExprContext ctx) { else if (v1.type == Type.BIGINT && v2.type == Type.BIGINT) { exec.stackPush(new Var((Long)v1.value + (Long)v2.value)); } + else if (v1.type == Type.DOUBLE || v2.type == Type.DOUBLE) { + exec.stackPush(new Var(v1.doubleValue() + v2.doubleValue())); + } + else if (v1.type == Type.DECIMAL || v2.type == Type.DECIMAL) { + exec.stackPush(new Var(v1.decimalValue().add(v2.decimalValue()))); + } else if (v1.type == Type.BIGINT && v2.type == Type.DATE) { exec.stackPush(changeDateByInt((Date)v2.value, (Long)v1.value, true /*add*/)); } @@ -370,6 +377,12 @@ public void operatorSub(HplsqlParser.ExprContext ctx) { else if (v1.type == Type.BIGINT && v2.type == Type.BIGINT) { exec.stackPush(new Var((Long)v1.value - (Long)v2.value)); } + else if (v1.type == Type.DOUBLE || v2.type == Type.DOUBLE) { + exec.stackPush(new Var(v1.doubleValue() - v2.doubleValue())); + } + else if (v1.type == Type.DECIMAL || v2.type == Type.DECIMAL) { + exec.stackPush(new Var(v1.decimalValue().subtract(v2.decimalValue()))); + } else if (v1.type == Type.DATE && v2.type == Type.BIGINT) { exec.stackPush(changeDateByInt((Date)v1.value, (Long)v2.value, false /*subtract*/)); } @@ -396,6 +409,12 @@ public void operatorMultiply(HplsqlParser.ExprContext ctx) { else if (v1.type == Type.BIGINT && v2.type == Type.BIGINT) { exec.stackPush(new Var((Long)v1.value * (Long)v2.value)); } + else if (v1.type == Type.DOUBLE || v2.type == Type.DOUBLE) { + exec.stackPush(new Var(v1.doubleValue() * v2.doubleValue())); + } + else if (v1.type == Type.DECIMAL || v2.type == Type.DECIMAL) { + exec.stackPush(new Var(v1.decimalValue().multiply(v2.decimalValue()))); + } else { exec.signal(Signal.Type.UNSUPPORTED_OPERATION, "Unsupported data types in multiplication operator"); } @@ -413,11 +432,17 @@ public void operatorDiv(HplsqlParser.ExprContext ctx) { else if (v1.type == Type.BIGINT && v2.type == Type.BIGINT) { exec.stackPush(new Var((Long)v1.value / (Long)v2.value)); } + else if (v1.type == Type.DOUBLE || v2.type == Type.DOUBLE) { + exec.stackPush(new Var(v1.doubleValue() / v2.doubleValue())); + } + else if (v1.type == Type.DECIMAL || v2.type == Type.DECIMAL) { + exec.stackPush(new Var(v1.decimalValue().divide(v2.decimalValue(), BigDecimal.ROUND_HALF_UP))); + } else { exec.signal(Signal.Type.UNSUPPORTED_OPERATION, "Unsupported data types in division operator"); } } - + /** * Add or subtract the specified number of days from DATE */ @@ -451,6 +476,10 @@ public void operatorEqual(HplsqlParser.Bool_expr_binaryContext ctx, boolean equa public void operatorCompare(HplsqlParser.Bool_expr_binaryContext ctx, HplsqlParser.Bool_expr_binary_operatorContext op) { Var v1 = evalPop(ctx.expr(0)); Var v2 = evalPop(ctx.expr(1)); + if (v1.isNull() || v2.isNull()) { + exec.stackPush(Var.Null); + return; + } int cmp = v1.compareTo(v2); boolean bool = false; if (op.T_GREATER() != null) { diff --git hplsql/src/main/java/org/apache/hive/hplsql/Var.java hplsql/src/main/java/org/apache/hive/hplsql/Var.java index 480d97c..6033c2a 100644 --- hplsql/src/main/java/org/apache/hive/hplsql/Var.java +++ hplsql/src/main/java/org/apache/hive/hplsql/Var.java @@ -522,6 +522,9 @@ public BigDecimal decimalValue() { if (type == Type.DECIMAL) { return (BigDecimal)value; } + else if (type == Type.BIGINT) { + return BigDecimal.valueOf(((Long)value).longValue()); + } throw new NumberFormatException(); } diff --git hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java index 8692661..7d957d8 100644 --- hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java +++ hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java @@ -39,6 +39,11 @@ public void testAdd() throws Exception { } @Test + public void testArith2() throws Exception { + run("arith2"); + } + + @Test public void testAssign() throws Exception { run("assign"); } diff --git hplsql/src/test/queries/local/arith2.sql hplsql/src/test/queries/local/arith2.sql new file mode 100644 index 0000000..2a9eb92 --- /dev/null +++ hplsql/src/test/queries/local/arith2.sql @@ -0,0 +1,44 @@ +declare i int default 10; +declare d decimal(4,2) default 1.1; +declare f float default 3.7; +declare db double default 7.1; + +print i * i; +print i * d; +print i * f; +print i * db; + +print i / i; +print i / d; +print i / f; +print i / db; + +print d * i; +print d * d; +print d * f; +print d * db; + +print d / i; +print d / d; +print d / f; +print d / db; + +print f * i; +print f * d; +print f * f; +print f * db; + +print f / i; +print f / d; +print f / f; +print f / db; + +print db * i; +print db * d; +print db * f; +print db * db; + +print db / i; +print db / d; +print db / f; +print db / db; diff --git hplsql/src/test/results/local/arith2.out.txt hplsql/src/test/results/local/arith2.out.txt new file mode 100644 index 0000000..087a8a3 --- /dev/null +++ hplsql/src/test/results/local/arith2.out.txt @@ -0,0 +1,68 @@ +Ln:1 DECLARE i int = 10 +Ln:2 DECLARE d decimal = 1.1 +Ln:3 DECLARE f float = 3.7 +Ln:4 DECLARE db double = 7.1 +Ln:6 PRINT +100 +Ln:7 PRINT +11.0 +Ln:8 PRINT +37.0 +Ln:9 PRINT +71.0 +Ln:11 PRINT +1 +Ln:12 PRINT +9 +Ln:13 PRINT +2.7027027027027026 +Ln:14 PRINT +1.4084507042253522 +Ln:16 PRINT +11.0 +Ln:17 PRINT +1.21 +Ln:18 PRINT +4.07 +Ln:19 PRINT +7.8100000000000005 +Ln:21 PRINT +0.1 +Ln:22 PRINT +1.0 +Ln:23 PRINT +0.2972972972972973 +Ln:24 PRINT +0.15492957746478875 +Ln:26 PRINT +37.0 +Ln:27 PRINT +4.07 +Ln:28 PRINT +13.690000000000001 +Ln:29 PRINT +26.27 +Ln:31 PRINT +0.37 +Ln:32 PRINT +3.3636363636363633 +Ln:33 PRINT +1.0 +Ln:34 PRINT +0.5211267605633804 +Ln:36 PRINT +71.0 +Ln:37 PRINT +7.8100000000000005 +Ln:38 PRINT +26.27 +Ln:39 PRINT +50.41 +Ln:41 PRINT +0.71 +Ln:42 PRINT +6.454545454545454 +Ln:43 PRINT +1.9189189189189186 +Ln:44 PRINT +1.0 \ No newline at end of file