You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/08/01 10:23:15 UTC
git commit: TAJO-979: Dividing float value by zero should throw
"Divide by zero Exception" (Hyoungjun Kim via hyunsik)
Repository: tajo
Updated Branches:
refs/heads/master 650157c59 -> 072b5a3ad
TAJO-979: Dividing float value by zero should throw "Divide by zero Exception" (Hyoungjun Kim via hyunsik)
Closes #100
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/072b5a3a
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/072b5a3a
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/072b5a3a
Branch: refs/heads/master
Commit: 072b5a3ad2f21189ab3bdf159e666086957401d6
Parents: 650157c
Author: Hyunsik Choi <hy...@apache.org>
Authored: Fri Aug 1 17:16:20 2014 +0900
Committer: Hyunsik Choi <hy...@apache.org>
Committed: Fri Aug 1 17:18:00 2014 +0900
----------------------------------------------------------------------
CHANGES | 3 +
.../java/org/apache/tajo/conf/TajoConf.java | 5 +-
.../main/java/org/apache/tajo/datum/Datum.java | 72 ++++
.../java/org/apache/tajo/datum/Float4Datum.java | 60 ++-
.../java/org/apache/tajo/datum/Float8Datum.java | 78 +++-
.../java/org/apache/tajo/datum/Int2Datum.java | 76 +++-
.../java/org/apache/tajo/datum/Int4Datum.java | 78 +++-
.../java/org/apache/tajo/datum/Int8Datum.java | 78 +++-
.../org/apache/tajo/datum/IntervalDatum.java | 16 +-
.../tajo/datum/TestArithmeticOperator.java | 377 +++++++++++++++++++
.../tajo/engine/function/TestMathFunctions.java | 15 +-
11 files changed, 759 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 76cfff7..705e91e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -97,6 +97,9 @@ Release 0.9.0 - unreleased
BUG FIXES
+ TAJO-979: Dividing float value by zero should throw "Divide by zero
+ Exception" (Hyoungjun Kim via hyunsik)
+
TAJO-978: RoundFloat8 should return Float8Datum type. (Hyoungjun Kim via
hyunsik)
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
index a8e6d8d..d5e8bc4 100644
--- a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
+++ b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
@@ -344,7 +344,10 @@ public class TajoConf extends Configuration {
TAJO_DEBUG("tajo.debug", false),
// ONLY FOR TESTCASE
- TESTCASE_MIN_TASK_NUM("tajo.testcase.min.task.num", -1)
+ TESTCASE_MIN_TASK_NUM("tajo.testcase.min.task.num", -1),
+
+ // behavior control
+ BEHAVIOR_ARITHMETIC_ABORT("tajo.behavior.arithmetic-abort", false);
;
public final String varname;
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Datum.java
index af88ebe..19acafc 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Datum.java
@@ -19,6 +19,8 @@
package org.apache.tajo.datum;
import com.google.gson.annotations.Expose;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
import org.apache.tajo.exception.InvalidCastException;
import org.apache.tajo.exception.InvalidOperationException;
import org.apache.tajo.json.CommonGsonHelper;
@@ -27,6 +29,12 @@ import org.apache.tajo.json.GsonObject;
import static org.apache.tajo.common.TajoDataTypes.Type;
public abstract class Datum implements Comparable<Datum>, GsonObject {
+ static boolean abortWhenDivideByZero;
+
+ static {
+ initAbortWhenDivideByZero(new TajoConf());
+ }
+
@Expose private final Type type;
public Datum(Type type) {
@@ -105,6 +113,10 @@ public abstract class Datum implements Comparable<Datum>, GsonObject {
this.type == Type.FLOAT8;
}
+ protected static void initAbortWhenDivideByZero(TajoConf tajoConf) {
+ abortWhenDivideByZero = tajoConf.getBoolVar(ConfVars.BEHAVIOR_ARITHMETIC_ABORT);
+ }
+
public abstract int size();
public Datum and(Datum datum) {
@@ -190,4 +202,64 @@ public abstract class Datum implements Comparable<Datum>, GsonObject {
public String toString() {
return asChars();
}
+
+ protected boolean validateDivideZero(short value) {
+ if (value == (short)0) {
+ if (abortWhenDivideByZero) {
+ throw new ArithmeticException("/ by zero");
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ protected boolean validateDivideZero(int value) {
+ if (value == 0) {
+ if (abortWhenDivideByZero) {
+ throw new ArithmeticException("/ by zero");
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ protected boolean validateDivideZero(long value) {
+ if (value == 0L) {
+ if (abortWhenDivideByZero) {
+ throw new ArithmeticException("/ by zero");
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ protected boolean validateDivideZero(float value) {
+ if (value == 0.0f) {
+ if (abortWhenDivideByZero) {
+ throw new ArithmeticException("/ by zero");
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ protected boolean validateDivideZero(double value) {
+ if (value == 0.0) {
+ if (abortWhenDivideByZero) {
+ throw new ArithmeticException("/ by zero");
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java
index 610ea95..8b16528 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Float4Datum.java
@@ -277,15 +277,35 @@ public class Float4Datum extends NumericDatum {
public Datum divide(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createFloat4(val / datum.asInt2());
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueI2);
case INT4:
- return DatumFactory.createFloat4(val / datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueI4);
case INT8:
- return DatumFactory.createFloat4(val / datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat4(val / datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueF4);
case FLOAT8:
- return DatumFactory.createFloat8(val / datum.asFloat8());
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF8);
case NULL_TYPE:
return datum;
default:
@@ -297,15 +317,35 @@ public class Float4Datum extends NumericDatum {
public Datum modular(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createFloat4(val % datum.asInt2());
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueI2);
case INT4:
- return DatumFactory.createFloat4(val % datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueI4);
case INT8:
- return DatumFactory.createFloat4(val % datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat4(val % datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueF4);
case FLOAT8:
- return DatumFactory.createFloat8(val % datum.asFloat8());
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF8);
case NULL_TYPE:
return datum;
default:
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java
index 90adcc7..d41af2d 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Float8Datum.java
@@ -265,20 +265,40 @@ public class Float8Datum extends NumericDatum {
@Override
public Datum divide(Datum datum) {
switch (datum.type()) {
- case INT2:
- return DatumFactory.createFloat8(val / datum.asInt2());
- case INT4:
- return DatumFactory.createFloat8(val / datum.asInt4());
- case INT8:
- return DatumFactory.createFloat8(val / datum.asInt8());
- case FLOAT4:
- return DatumFactory.createFloat8(val / datum.asFloat4());
- case FLOAT8:
- return DatumFactory.createFloat8(val / datum.asFloat8());
- case NULL_TYPE:
- return datum;
- default:
- throw new InvalidOperationException(datum.type());
+ case INT2:
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueI2);
+ case INT4:
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueI4);
+ case INT8:
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueI8);
+ case FLOAT4:
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF4);
+ case FLOAT8:
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF8);
+ case NULL_TYPE:
+ return datum;
+ default:
+ throw new InvalidOperationException(datum.type());
}
}
@@ -286,15 +306,35 @@ public class Float8Datum extends NumericDatum {
public Datum modular(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createFloat8(val % datum.asInt2());
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueI2);
case INT4:
- return DatumFactory.createFloat8(val % datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueI4);
case INT8:
- return DatumFactory.createFloat8(val % datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat8(val % datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF4);
case FLOAT8:
- return DatumFactory.createFloat8(val % datum.asFloat8());
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF8);
case NULL_TYPE:
return datum;
default:
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java
index ab17bdc..2a6c691 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int2Datum.java
@@ -267,20 +267,40 @@ public class Int2Datum extends NumericDatum {
@Override
public Datum divide(Datum datum) {
switch (datum.type()) {
- case INT2:
- return DatumFactory.createInt2((short) (val / datum.asInt2()));
- case INT4:
- return DatumFactory.createInt4(val / datum.asInt4());
- case INT8:
- return DatumFactory.createInt8(val / datum.asInt8());
- case FLOAT4:
- return DatumFactory.createFloat4(val / datum.asFloat4());
- case FLOAT8:
- return DatumFactory.createFloat8(val / datum.asFloat8());
- case NULL_TYPE:
- return datum;
- default:
- throw new InvalidOperationException(datum.type());
+ case INT2:
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt2((short) (val / paramValueI2));
+ case INT4:
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val / paramValueI4);
+ case INT8:
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val / paramValueI8);
+ case FLOAT4:
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueF4);
+ case FLOAT8:
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF8);
+ case NULL_TYPE:
+ return datum;
+ default:
+ throw new InvalidOperationException(datum.type());
}
}
@@ -288,14 +308,34 @@ public class Int2Datum extends NumericDatum {
public Datum modular(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createInt2((short) (val % datum.asInt2()));
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt2((short) (val % paramValueI2));
case INT4:
- return DatumFactory.createInt4(val % datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val % paramValueI4);
case INT8:
- return DatumFactory.createInt8(val % datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val % paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat4(val % datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueF4);
case FLOAT8:
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
return DatumFactory.createFloat8(val % datum.asFloat8());
case NULL_TYPE:
return datum;
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java
index 9a60863..26201fb 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int4Datum.java
@@ -271,20 +271,40 @@ public class Int4Datum extends NumericDatum {
@Override
public Datum divide(Datum datum) {
switch (datum.type()) {
- case INT2:
- return DatumFactory.createInt4(val / datum.asInt2());
- case INT4:
- return DatumFactory.createInt4(val / datum.asInt4());
- case INT8:
- return DatumFactory.createInt8(val / datum.asInt8());
- case FLOAT4:
- return DatumFactory.createFloat4(val / datum.asFloat4());
- case FLOAT8:
- return DatumFactory.createFloat8(val / datum.asFloat8());
- case NULL_TYPE:
- return datum;
- default:
- throw new InvalidOperationException(datum.type());
+ case INT2:
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val / paramValueI2);
+ case INT4:
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val / paramValueI4);
+ case INT8:
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val / paramValueI8);
+ case FLOAT4:
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val / paramValueF4);
+ case FLOAT8:
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF8);
+ case NULL_TYPE:
+ return datum;
+ default:
+ throw new InvalidOperationException(datum.type());
}
}
@@ -292,15 +312,35 @@ public class Int4Datum extends NumericDatum {
public Datum modular(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createInt4(val % datum.asInt2());
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val % paramValueI2);
case INT4:
- return DatumFactory.createInt4(val % datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt4(val % paramValueI4);
case INT8:
- return DatumFactory.createInt8(val % datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val % paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat4(val % datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat4(val % paramValueF4);
case FLOAT8:
- return DatumFactory.createFloat8(val % datum.asFloat8());
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF8);
case NULL_TYPE:
return datum;
default:
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java b/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java
index db8a12b..9fa41d1 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/Int8Datum.java
@@ -280,20 +280,40 @@ public class Int8Datum extends NumericDatum {
@Override
public Datum divide(Datum datum) {
switch (datum.type()) {
- case INT2:
- return DatumFactory.createInt8(val / datum.asInt2());
- case INT4:
- return DatumFactory.createInt8(val / datum.asInt4());
- case INT8:
- return DatumFactory.createInt8(val / datum.asInt8());
- case FLOAT4:
- return DatumFactory.createFloat8(val / datum.asFloat4());
- case FLOAT8:
- return DatumFactory.createFloat8(val / datum.asFloat8());
- case NULL_TYPE:
- return datum;
- default:
- throw new InvalidOperationException(datum.type());
+ case INT2:
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val / paramValueI2);
+ case INT4:
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val / paramValueI4);
+ case INT8:
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val / paramValueI8);
+ case FLOAT4:
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF4);
+ case FLOAT8:
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val / paramValueF8);
+ case NULL_TYPE:
+ return datum;
+ default:
+ throw new InvalidOperationException(datum.type());
}
}
@@ -301,15 +321,35 @@ public class Int8Datum extends NumericDatum {
public Datum modular(Datum datum) {
switch (datum.type()) {
case INT2:
- return DatumFactory.createInt8(val % datum.asInt2());
+ short paramValueI2 = datum.asInt2();
+ if (!validateDivideZero(paramValueI2)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val % paramValueI2);
case INT4:
- return DatumFactory.createInt8(val % datum.asInt4());
+ int paramValueI4 = datum.asInt4();
+ if (!validateDivideZero(paramValueI4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val % paramValueI4);
case INT8:
- return DatumFactory.createInt8(val % datum.asInt8());
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createInt8(val % paramValueI8);
case FLOAT4:
- return DatumFactory.createFloat8(val % datum.asFloat4());
+ float paramValueF4 = datum.asFloat4();
+ if (!validateDivideZero(paramValueF4)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF4);
case FLOAT8:
- return DatumFactory.createFloat8(val % datum.asFloat8());
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return DatumFactory.createFloat8(val % paramValueF8);
case NULL_TYPE:
return datum;
default:
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java b/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java
index 28a0a47..c6f3922 100644
--- a/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java
+++ b/tajo-common/src/main/java/org/apache/tajo/datum/IntervalDatum.java
@@ -289,16 +289,22 @@ public class IntervalDatum extends Datum {
@Override
public Datum divide(Datum datum) {
- switch(datum.type()) {
+ switch (datum.type()) {
case INT2:
case INT4:
case INT8:
- long int8Val = datum.asInt8();
- return createIntervalDatum((double)months / int8Val, (double) millieconds / int8Val);
+ long paramValueI8 = datum.asInt8();
+ if (!validateDivideZero(paramValueI8)) {
+ return NullDatum.get();
+ }
+ return createIntervalDatum((double) months / paramValueI8, (double) millieconds / paramValueI8);
case FLOAT4:
case FLOAT8:
- double float8Val = datum.asFloat8();
- return createIntervalDatum((double)months / float8Val, (double) millieconds / float8Val);
+ double paramValueF8 = datum.asFloat8();
+ if (!validateDivideZero(paramValueF8)) {
+ return NullDatum.get();
+ }
+ return createIntervalDatum((double) months / paramValueF8, (double) millieconds / paramValueF8);
default:
throw new InvalidOperationException(datum.type());
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-common/src/test/java/org/apache/tajo/datum/TestArithmeticOperator.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/test/java/org/apache/tajo/datum/TestArithmeticOperator.java b/tajo-common/src/test/java/org/apache/tajo/datum/TestArithmeticOperator.java
new file mode 100644
index 0000000..adf80b0
--- /dev/null
+++ b/tajo-common/src/test/java/org/apache/tajo/datum/TestArithmeticOperator.java
@@ -0,0 +1,377 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.datum;
+
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public class TestArithmeticOperator {
+ String option;
+
+ public TestArithmeticOperator(String option) {
+ this.option = option;
+ }
+
+ @Parameters
+ public static Collection<Object[]> generateParameters() {
+ return Arrays.asList(new Object[][]{
+ {"Zero_Null"},
+ {"Zero_Exception"},
+ });
+ }
+
+ @Before
+ public void setUp() {
+ TajoConf tajoConf = new TajoConf();
+ if ("Zero_Exception".equals(option)) {
+ tajoConf.setBoolVar(ConfVars.BEHAVIOR_ARITHMETIC_ABORT, true);
+ } else {
+ tajoConf.setBoolVar(ConfVars.BEHAVIOR_ARITHMETIC_ABORT, false);
+ }
+ Datum.initAbortWhenDivideByZero(tajoConf);
+ }
+
+ @Test
+ public void testInt2Datum() throws Exception {
+ //plus
+ runAndAssert("plus", new Int2Datum((short)10), new Int2Datum((short)5), new Int2Datum((short)15));
+ runAndAssert("plus", new Int2Datum((short)10), new Int4Datum(5), new Int4Datum(15));
+ runAndAssert("plus", new Int2Datum((short)10), new Int8Datum(5), new Int8Datum(15));
+ runAndAssert("plus", new Int2Datum((short)10), new Float4Datum(5.0f), new Float4Datum(15.0f));
+ runAndAssert("plus", new Int2Datum((short)10), new Float8Datum(5.0), new Float8Datum(15.0));
+
+ //minus
+ runAndAssert("minus", new Int2Datum((short)10), new Int2Datum((short)5), new Int2Datum((short)5));
+ runAndAssert("minus", new Int2Datum((short)10), new Int4Datum(5), new Int4Datum(5));
+ runAndAssert("minus", new Int2Datum((short)10), new Int8Datum(5), new Int8Datum(5));
+ runAndAssert("minus", new Int2Datum((short)10), new Float4Datum(5.0f), new Float4Datum(5.0f));
+ runAndAssert("minus", new Int2Datum((short)10), new Float8Datum(5.0), new Float8Datum(5.0));
+
+ runAndAssert("minus", new Int2Datum((short)5), new Int2Datum((short)10), new Int2Datum((short)-5));
+ runAndAssert("minus", new Int2Datum((short)5), new Int4Datum(10), new Int4Datum(-5));
+ runAndAssert("minus", new Int2Datum((short)5), new Int8Datum(10), new Int8Datum(-5));
+ runAndAssert("minus", new Int2Datum((short)5), new Float4Datum(10.0f), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Int2Datum((short)5), new Float8Datum(10.0), new Float8Datum(-5.0));
+
+ //multiply
+ runAndAssert("multiply", new Int2Datum((short)10), new Int2Datum((short)5), new Int4Datum(50));
+ runAndAssert("multiply", new Int2Datum((short)10), new Int4Datum(5), new Int4Datum(50));
+ runAndAssert("multiply", new Int2Datum((short)10), new Int8Datum(5), new Int8Datum(50));
+ runAndAssert("multiply", new Int2Datum((short)10), new Float4Datum(5.0f), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Int2Datum((short)10), new Float8Datum(5.0), new Float8Datum(50.0));
+
+ //divide
+ runAndAssert("divide", new Int2Datum((short)10), new Int2Datum((short)5), new Int2Datum((short)2));
+ runAndAssert("divide", new Int2Datum((short)10), new Int4Datum(5), new Int4Datum(2));
+ runAndAssert("divide", new Int2Datum((short)10), new Int8Datum(5), new Int8Datum(2));
+ runAndAssert("divide", new Int2Datum((short)10), new Float4Datum(5.0f), new Float4Datum(2.0f));
+ runAndAssert("divide", new Int2Datum((short)10), new Float8Datum(5.0), new Float8Datum(2.0));
+
+ runAndAssert("divide", new Int2Datum((short)10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("divide", new Int2Datum((short)10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int2Datum((short)10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int2Datum((short)10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("divide", new Int2Datum((short)10), new Float8Datum(0.0), NullDatum.get());
+
+ //modular
+ runAndAssert("modular", new Int2Datum((short)10), new Int2Datum((short)3), new Int2Datum((short)1));
+ runAndAssert("modular", new Int2Datum((short)10), new Int4Datum(3), new Int4Datum(1));
+ runAndAssert("modular", new Int2Datum((short)10), new Int8Datum(3), new Int8Datum(1));
+ runAndAssert("modular", new Int2Datum((short)10), new Float4Datum(3.0f), new Float4Datum(1.0f));
+ runAndAssert("modular", new Int2Datum((short)10), new Float8Datum(3.0), new Float8Datum(1.0));
+
+ runAndAssert("modular", new Int2Datum((short)10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("modular", new Int2Datum((short)10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int2Datum((short)10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int2Datum((short)10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("modular", new Int2Datum((short)10), new Float8Datum(0.0), NullDatum.get());
+ }
+
+ @Test
+ public void testInt4Datum() throws Exception {
+ //plus
+ runAndAssert("plus", new Int4Datum(10), new Int2Datum((short)5), new Int4Datum(15));
+ runAndAssert("plus", new Int4Datum(10), new Int4Datum(5), new Int4Datum(15));
+ runAndAssert("plus", new Int4Datum(10), new Int8Datum(5), new Int8Datum(15));
+ runAndAssert("plus", new Int4Datum(10), new Float4Datum(5.0f), new Float4Datum(15.0f));
+ runAndAssert("plus", new Int4Datum(10), new Float8Datum(5.0), new Float8Datum(15.0));
+
+ //minus
+ runAndAssert("minus", new Int4Datum(10), new Int2Datum((short)5), new Int4Datum(5));
+ runAndAssert("minus", new Int4Datum(10), new Int4Datum(5), new Int4Datum(5));
+ runAndAssert("minus", new Int4Datum(10), new Int8Datum(5), new Int8Datum(5));
+ runAndAssert("minus", new Int4Datum(10), new Float4Datum(5.0f), new Float4Datum(5.0f));
+ runAndAssert("minus", new Int4Datum(10), new Float8Datum(5.0), new Float8Datum(5.0));
+
+ runAndAssert("minus", new Int4Datum(5), new Int2Datum((short)10), new Int4Datum(-5));
+ runAndAssert("minus", new Int4Datum(5), new Int4Datum(10), new Int4Datum(-5));
+ runAndAssert("minus", new Int4Datum(5), new Int8Datum(10), new Int8Datum(-5));
+ runAndAssert("minus", new Int4Datum(5), new Float4Datum(10.0f), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Int4Datum(5), new Float8Datum(10.0), new Float8Datum(-5.0));
+
+ //multiply
+ runAndAssert("multiply", new Int4Datum(10), new Int2Datum((short)5), new Int4Datum(50));
+ runAndAssert("multiply", new Int4Datum(10), new Int4Datum(5), new Int4Datum(50));
+ runAndAssert("multiply", new Int4Datum(10), new Int8Datum(5), new Int8Datum(50));
+ runAndAssert("multiply", new Int4Datum(10), new Float4Datum(5.0f), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Int4Datum(10), new Float8Datum(5.0), new Float8Datum(50.0));
+
+ //divide
+ runAndAssert("divide", new Int4Datum(10), new Int2Datum((short)5), new Int4Datum(2));
+ runAndAssert("divide", new Int4Datum(10), new Int4Datum(5), new Int4Datum(2));
+ runAndAssert("divide", new Int4Datum(10), new Int8Datum(5), new Int8Datum(2));
+ runAndAssert("divide", new Int4Datum(10), new Float4Datum(5.0f), new Float4Datum(2.0f));
+ runAndAssert("divide", new Int4Datum(10), new Float8Datum(5.0), new Float8Datum(2.0));
+
+ runAndAssert("divide", new Int4Datum(10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("divide", new Int4Datum(10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int4Datum(10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int4Datum(10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("divide", new Int4Datum(10), new Float8Datum(0.0), NullDatum.get());
+
+ //modular
+ runAndAssert("modular", new Int4Datum(10), new Int2Datum((short)3), new Int4Datum(1));
+ runAndAssert("modular", new Int4Datum(10), new Int4Datum(3), new Int4Datum(1));
+ runAndAssert("modular", new Int4Datum(10), new Int8Datum(3), new Int8Datum(1));
+ runAndAssert("modular", new Int4Datum(10), new Float4Datum(3.0f), new Float4Datum(1.0f));
+ runAndAssert("modular", new Int4Datum(10), new Float8Datum(3.0), new Float8Datum(1.0));
+
+ runAndAssert("modular", new Int4Datum(10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("modular", new Int4Datum(10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int4Datum(10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int4Datum(10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("modular", new Int4Datum(10), new Float8Datum(0.0), NullDatum.get());
+ }
+
+ @Test
+ public void testInt8Datum() throws Exception {
+ //plus
+ runAndAssert("plus", new Int8Datum(10), new Int2Datum((short)5), new Int8Datum(15));
+ runAndAssert("plus", new Int8Datum(10), new Int4Datum(5), new Int8Datum(15));
+ runAndAssert("plus", new Int8Datum(10), new Int8Datum(5), new Int8Datum(15));
+ runAndAssert("plus", new Int8Datum(10), new Float4Datum(5.0f), new Float8Datum(15.0f));
+ runAndAssert("plus", new Int8Datum(10), new Float8Datum(5.0), new Float8Datum(15.0));
+
+ //minus
+ runAndAssert("minus", new Int8Datum(10), new Int2Datum((short)5), new Int8Datum(5));
+ runAndAssert("minus", new Int8Datum(10), new Int4Datum(5), new Int8Datum(5));
+ runAndAssert("minus", new Int8Datum(10), new Int8Datum(5), new Int8Datum(5));
+ runAndAssert("minus", new Int8Datum(10), new Float4Datum(5.0f), new Float8Datum(5.0f));
+ runAndAssert("minus", new Int8Datum(10), new Float8Datum(5.0), new Float8Datum(5.0));
+
+ runAndAssert("minus", new Int8Datum(5), new Int2Datum((short)10), new Int8Datum(-5));
+ runAndAssert("minus", new Int8Datum(5), new Int4Datum(10), new Int8Datum(-5));
+ runAndAssert("minus", new Int8Datum(5), new Int8Datum(10), new Int8Datum(-5));
+ runAndAssert("minus", new Int8Datum(5), new Float4Datum(10.0f), new Float8Datum(-5.0f));
+ runAndAssert("minus", new Int8Datum(5), new Float8Datum(10.0), new Float8Datum(-5.0));
+
+ //multiply
+ runAndAssert("multiply", new Int8Datum(10), new Int2Datum((short)5), new Int8Datum(50));
+ runAndAssert("multiply", new Int8Datum(10), new Int4Datum(5), new Int8Datum(50));
+ runAndAssert("multiply", new Int8Datum(10), new Int8Datum(5), new Int8Datum(50));
+ runAndAssert("multiply", new Int8Datum(10), new Float4Datum(5.0f), new Float8Datum(50.0f));
+ runAndAssert("multiply", new Int8Datum(10), new Float8Datum(5.0), new Float8Datum(50.0));
+
+ //divide
+ runAndAssert("divide", new Int8Datum(10), new Int2Datum((short)5), new Int8Datum(2));
+ runAndAssert("divide", new Int8Datum(10), new Int4Datum(5), new Int8Datum(2));
+ runAndAssert("divide", new Int8Datum(10), new Int8Datum(5), new Int8Datum(2));
+ runAndAssert("divide", new Int8Datum(10), new Float4Datum(5.0f), new Float8Datum(2.0f));
+ runAndAssert("divide", new Int8Datum(10), new Float8Datum(5.0), new Float8Datum(2.0));
+
+ runAndAssert("divide", new Int8Datum(10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("divide", new Int8Datum(10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int8Datum(10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("divide", new Int8Datum(10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("divide", new Int8Datum(10), new Float8Datum(0.0), NullDatum.get());
+
+ //modular
+ runAndAssert("modular", new Int8Datum(10), new Int2Datum((short)3), new Int8Datum(1));
+ runAndAssert("modular", new Int8Datum(10), new Int4Datum(3), new Int8Datum(1));
+ runAndAssert("modular", new Int8Datum(10), new Int8Datum(3), new Int8Datum(1));
+ runAndAssert("modular", new Int8Datum(10), new Float4Datum(3.0f), new Float8Datum(1.0f));
+ runAndAssert("modular", new Int8Datum(10), new Float8Datum(3.0), new Float8Datum(1.0));
+
+ runAndAssert("modular", new Int8Datum(10), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("modular", new Int8Datum(10), new Int4Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int8Datum(10), new Int8Datum(0), NullDatum.get());
+ runAndAssert("modular", new Int8Datum(10), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("modular", new Int8Datum(10), new Float8Datum(0.0), NullDatum.get());
+ }
+
+ @Test
+ public void testFloat4Datum() throws Exception {
+ //plus
+ runAndAssert("plus", new Float4Datum(10.0f), new Int2Datum((short)5), new Float4Datum(15.0f));
+ runAndAssert("plus", new Float4Datum(10.0f), new Int4Datum(5), new Float4Datum(15.0f));
+ runAndAssert("plus", new Float4Datum(10.0f), new Int8Datum(5), new Float4Datum(15.0f));
+ runAndAssert("plus", new Float4Datum(10.0f), new Float4Datum(5.0f), new Float4Datum(15.0f));
+ runAndAssert("plus", new Float4Datum(10.0f), new Float8Datum(5.0), new Float8Datum(15.0));
+
+ //minus
+ runAndAssert("minus", new Float4Datum(10.0f), new Int2Datum((short)5), new Float4Datum(5.0f));
+ runAndAssert("minus", new Float4Datum(10.0f), new Int4Datum(5), new Float4Datum(5.0f));
+ runAndAssert("minus", new Float4Datum(10.0f), new Int8Datum(5), new Float4Datum(5.0f));
+ runAndAssert("minus", new Float4Datum(10.0f), new Float4Datum(5.0f), new Float4Datum(5.0f));
+ runAndAssert("minus", new Float4Datum(10.0f), new Float8Datum(5.0), new Float8Datum(5.0));
+
+ runAndAssert("minus", new Float4Datum(5.0f), new Int2Datum((short)10), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Float4Datum(5.0f), new Int4Datum(10), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Float4Datum(5.0f), new Float4Datum(10.0f), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Float4Datum(5.0f), new Float4Datum(10.0f), new Float4Datum(-5.0f));
+ runAndAssert("minus", new Float4Datum(5.0f), new Float8Datum(10.0), new Float8Datum(-5.0));
+
+ //multiply
+ runAndAssert("multiply", new Float4Datum(10.0f), new Int2Datum((short)5), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Float4Datum(10.0f), new Int4Datum(5), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Float4Datum(10.0f), new Int8Datum(5), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Float4Datum(10.0f), new Float4Datum(5.0f), new Float4Datum(50.0f));
+ runAndAssert("multiply", new Float4Datum(10.0f), new Float8Datum(5.0), new Float8Datum(50.0));
+
+ //divide
+ runAndAssert("divide", new Float4Datum(10.0f), new Int2Datum((short)5), new Float4Datum(2.0f));
+ runAndAssert("divide", new Float4Datum(10.0f), new Int4Datum(5), new Float4Datum(2.0f));
+ runAndAssert("divide", new Float4Datum(10.0f), new Int8Datum(5), new Float4Datum(2.0f));
+ runAndAssert("divide", new Float4Datum(10.0f), new Float4Datum(5.0f), new Float4Datum(2.0f));
+ runAndAssert("divide", new Float4Datum(10.0f), new Float8Datum(5.0), new Float8Datum(2.0));
+
+ runAndAssert("divide", new Float4Datum(10.0f), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("divide", new Float4Datum(10.0f), new Int4Datum(0), NullDatum.get());
+ runAndAssert("divide", new Float4Datum(10.0f), new Int8Datum(0), NullDatum.get());
+ runAndAssert("divide", new Float4Datum(10.0f), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("divide", new Float4Datum(10.0f), new Float8Datum(0.0), NullDatum.get());
+
+ //modular
+ runAndAssert("modular", new Float4Datum(10.0f), new Int2Datum((short)3), new Float4Datum(1.0f));
+ runAndAssert("modular", new Float4Datum(10.0f), new Int4Datum(3), new Float4Datum(1.0f));
+ runAndAssert("modular", new Float4Datum(10.0f), new Int8Datum(3), new Float4Datum(1.0f));
+ runAndAssert("modular", new Float4Datum(10.0f), new Float4Datum(3.0f), new Float4Datum(1.0f));
+ runAndAssert("modular", new Float4Datum(10.0f), new Float8Datum(3.0), new Float8Datum(1.0));
+
+ runAndAssert("modular", new Float4Datum(10.0f), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("modular", new Float4Datum(10.0f), new Int4Datum(0), NullDatum.get());
+ runAndAssert("modular", new Float4Datum(10.0f), new Int8Datum(0), NullDatum.get());
+ runAndAssert("modular", new Float4Datum(10.0f), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("modular", new Float4Datum(10.0f), new Float8Datum(0.0), NullDatum.get());
+ }
+
+ @Test
+ public void testFloat8Datum() throws Exception {
+ //plus
+ runAndAssert("plus", new Float8Datum(10.0), new Int2Datum((short)5), new Float8Datum(15.0));
+ runAndAssert("plus", new Float8Datum(10.0), new Int4Datum(5), new Float8Datum(15.0));
+ runAndAssert("plus", new Float8Datum(10.0), new Int8Datum(5), new Float8Datum(15.0));
+ runAndAssert("plus", new Float8Datum(10.0), new Float4Datum(5.0f), new Float8Datum(15.0));
+ runAndAssert("plus", new Float8Datum(10.0), new Float8Datum(5.0), new Float8Datum(15.0));
+
+ //minus
+ runAndAssert("minus", new Float8Datum(10.0), new Int2Datum((short)5), new Float8Datum(5.0));
+ runAndAssert("minus", new Float8Datum(10.0), new Int4Datum(5), new Float8Datum(5.0));
+ runAndAssert("minus", new Float8Datum(10.0), new Int8Datum(5), new Float8Datum(5.0));
+ runAndAssert("minus", new Float8Datum(10.0), new Float4Datum(5.0f), new Float8Datum(5.0));
+ runAndAssert("minus", new Float8Datum(10.0), new Float8Datum(5.0), new Float8Datum(5.0));
+
+ runAndAssert("minus", new Float8Datum(5.0), new Int2Datum((short)10), new Float8Datum(-5.0));
+ runAndAssert("minus", new Float8Datum(5.0), new Int4Datum(10), new Float8Datum(-5.0));
+ runAndAssert("minus", new Float8Datum(5.0), new Float8Datum(10.0), new Float8Datum(-5.0));
+ runAndAssert("minus", new Float8Datum(5.0), new Float8Datum(10.0), new Float8Datum(-5.0));
+ runAndAssert("minus", new Float8Datum(5.0), new Float8Datum(10.0), new Float8Datum(-5.0));
+
+ //multiply
+ runAndAssert("multiply", new Float8Datum(10.0), new Int2Datum((short)5), new Float8Datum(50.0));
+ runAndAssert("multiply", new Float8Datum(10.0), new Int4Datum(5), new Float8Datum(50.0));
+ runAndAssert("multiply", new Float8Datum(10.0), new Int8Datum(5), new Float8Datum(50.0));
+ runAndAssert("multiply", new Float8Datum(10.0), new Float4Datum(5.0f), new Float8Datum(50.0));
+ runAndAssert("multiply", new Float8Datum(10.0), new Float8Datum(5.0), new Float8Datum(50.0));
+
+ //divide
+ runAndAssert("divide", new Float8Datum(10.0), new Int2Datum((short)5), new Float8Datum(2.0));
+ runAndAssert("divide", new Float8Datum(10.0), new Int4Datum(5), new Float8Datum(2.0));
+ runAndAssert("divide", new Float8Datum(10.0), new Int8Datum(5), new Float8Datum(2.0));
+ runAndAssert("divide", new Float8Datum(10.0), new Float4Datum(5.0f), new Float8Datum(2.0));
+ runAndAssert("divide", new Float8Datum(10.0), new Float8Datum(5.0), new Float8Datum(2.0));
+
+ runAndAssert("divide", new Float8Datum(10.0), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("divide", new Float8Datum(10.0), new Int4Datum(0), NullDatum.get());
+ runAndAssert("divide", new Float8Datum(10.0), new Int8Datum(0), NullDatum.get());
+ runAndAssert("divide", new Float8Datum(10.0), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("divide", new Float8Datum(10.0), new Float8Datum(0.0), NullDatum.get());
+
+ //modular
+ runAndAssert("modular", new Float8Datum(10.0), new Int2Datum((short)3), new Float8Datum(1.0));
+ runAndAssert("modular", new Float8Datum(10.0), new Int4Datum(3), new Float8Datum(1.0));
+ runAndAssert("modular", new Float8Datum(10.0), new Int8Datum(3), new Float8Datum(1.0));
+ runAndAssert("modular", new Float8Datum(10.0), new Float4Datum(3.0f), new Float8Datum(1.0));
+ runAndAssert("modular", new Float8Datum(10.0), new Float8Datum(3.0), new Float8Datum(1.0));
+
+ //modular by zero
+ runAndAssert("modular", new Float8Datum(10.0), new Int2Datum((short) 0), NullDatum.get());
+ runAndAssert("modular", new Float8Datum(10.0), new Int4Datum(0), NullDatum.get());
+ runAndAssert("modular", new Float8Datum(10.0), new Int8Datum(0), NullDatum.get());
+ runAndAssert("modular", new Float8Datum(10.0), new Float4Datum(0.0f), NullDatum.get());
+ runAndAssert("modular", new Float8Datum(10.0), new Float8Datum(0.0), NullDatum.get());
+ }
+
+ private void runAndAssert(String op, Datum left, Datum right, Datum expected) throws Exception {
+ Datum result = null;
+ try {
+ if ("plus".equals(op)) {
+ result = left.plus(right);
+ } else if ("minus".equals(op)) {
+ result = left.minus(right);
+ } else if ("multiply".equals(op)) {
+ result = left.multiply(right);
+ } else if ("divide".equals(op)) {
+ result = left.divide(right);
+ if (right.asFloat8() == 0) {
+ if (Datum.abortWhenDivideByZero) {
+ fail("should throw DivideByZeroException in the case of nullIfZero false");
+ }
+ }
+ } else if ("modular".equals(op)) {
+ result = left.modular(right);
+ if (right.asFloat8() == 0) {
+ if (Datum.abortWhenDivideByZero) {
+ fail("should throw DivideByZeroException in the case of nullIfZero false");
+ }
+ }
+ }
+ assertEquals(expected.type(), result.type());
+ assertEquals(expected, result);
+ } catch (ArithmeticException e) {
+ if (!Datum.abortWhenDivideByZero) {
+ fail(op + " throws DivideByZeroException");
+ } else {
+ //success
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/072b5a3a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
index 8068180..e54c40c 100644
--- a/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
+++ b/tajo-core/src/test/java/org/apache/tajo/engine/function/TestMathFunctions.java
@@ -20,13 +20,11 @@ package org.apache.tajo.engine.function;
import org.apache.tajo.catalog.Schema;
import org.apache.tajo.engine.eval.ExprTestBase;
-import org.apache.tajo.exception.InvalidOperationException;
import org.junit.Test;
import java.io.IOException;
import static org.apache.tajo.common.TajoDataTypes.Type.*;
-import static org.junit.Assert.fail;
public class TestMathFunctions extends ExprTestBase {
@Test
@@ -440,13 +438,14 @@ public class TestMathFunctions extends ExprTestBase {
@Test
public void testRoundWithSpecifiedPrecision() throws IOException {
+ // TODO - in order to make this test possible, testSimpleEval should take session variables. Now, we disable it.
// divide zero
- try {
- testSimpleEval("select round(10.0/0.0,2) ", new String[]{""});
- fail("10.0/0 should throw InvalidOperationException");
- } catch (InvalidOperationException e) {
- //success
- }
+// try {
+// testSimpleEval("select round(10.0/0.0,2) ", new String[]{""});
+// fail("10.0/0 should throw InvalidOperationException");
+// } catch (InvalidOperationException e) {
+// //success
+// }
testSimpleEval("select round(42.4382,2) ", new String[]{"42.44"});
testSimpleEval("select round(-42.4382,2) ", new String[]{"-42.44"});