You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by ji...@apache.org on 2014/08/11 10:11:31 UTC

[02/17] git commit: TAJO-979: Dividing float value by zero should throw "Divide by zero Exception" (Hyoungjun Kim via hyunsik)

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/index_support
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"});