Dmitry Lychagin has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/1800

Change subject: Clean up numeric type conversion code
......................................................................

Clean up numeric type conversion code

- Add new conversion methods to ITypeConvertorComputer interface
- Move remaining type conversion code from ATypeHierarchy
  to ITypeConvertorComputer implementations
- Add type demotion parameter to chose whether it fails
  if input value is out of range for the target type ('strict' mode)
  or not ('lax' mode)
- Clean up error messages

Change-Id: I68b78e2dc9ebf78799698a1c90bcd7cb5150137d
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SimilarityCheckRule.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
M 
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
M asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
M 
asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalFunction.java
M 
asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ADMDataParser.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/hash/AMurmurHash3BinaryHashFunctionFamily.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ACastVisitor.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ATypeHierarchy.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/AbstractIntegerTypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToFloatTypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt16TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt32TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt64TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt8TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToDoubleTypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt16TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt32TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt64TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt8TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ITypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToDoubleTypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToFloatTypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt16TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt32TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt64TypeConvertComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt8TypeConvertComputer.java
28 files changed, 1,027 insertions(+), 725 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/00/1800/1

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SimilarityCheckRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SimilarityCheckRule.java
index 585bc71..1e445e5 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SimilarityCheckRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/SimilarityCheckRule.java
@@ -21,7 +21,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.lang.common.util.FunctionUtil;
 import org.apache.asterix.om.base.ADouble;
 import org.apache.asterix.om.base.AFloat;
@@ -50,6 +49,7 @@
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 /**
  * Looks for a select operator, containing a condition:
@@ -289,7 +289,7 @@
             AInt32 aInt = new AInt32(0);
             try {
                 aInt = (AInt32) 
ATypeHierarchy.convertNumericTypeObject(constVal.getObject(), ATypeTag.INTEGER);
-            } catch (AsterixException e) {
+            } catch (HyracksDataException e) {
                 throw new AlgebricksException(e);
             }
 
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index 59cb373..48367a7 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -80,6 +80,7 @@
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import 
org.apache.hyracks.storage.am.lsm.invertedindex.tokenizers.DelimitedUTF8StringBinaryTokenizer;
 
 /**
@@ -419,8 +420,12 @@
 
             // if the constant type and target type does not match, we do a 
type conversion
             if (constantValueTag != fieldType.getTypeTag() && constantValue != 
null) {
-                replacedConstantValue = 
ATypeHierarchy.getAsterixConstantValueFromNumericTypeObject(
-                        constantValue.getObject(), fieldType.getTypeTag());
+                try {
+                    replacedConstantValue = 
ATypeHierarchy.getAsterixConstantValueFromNumericTypeObject(
+                            constantValue.getObject(), fieldType.getTypeTag(), 
true);
+                } catch (HyracksDataException e) {
+                    throw new AlgebricksException(e);
+                }
                 if (replacedConstantValue != null) {
                     typeCastingApplied = true;
                 }
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
index 0752979..341bda3 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
@@ -27,7 +27,6 @@
 
 import 
org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
-import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.dataflow.data.common.ExpressionTypeComputer;
@@ -82,6 +81,7 @@
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 import 
org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import 
org.apache.hyracks.storage.am.lsm.invertedindex.api.IInvertedIndexSearchModifierFactory;
 import 
org.apache.hyracks.storage.am.lsm.invertedindex.search.ConjunctiveEditDistanceSearchModifierFactory;
 import 
org.apache.hyracks.storage.am.lsm.invertedindex.search.ConjunctiveListEditDistanceSearchModifierFactory;
@@ -989,7 +989,7 @@
         // Apply type casting based on numeric types of the input to INTEGER 
type.
         try {
             edThresh = (AInt32) 
ATypeHierarchy.convertNumericTypeObject(intObj, ATypeTag.INTEGER);
-        } catch (AsterixException e) {
+        } catch (HyracksDataException e) {
             throw new AlgebricksException(e);
         }
         int mergeThreshold = 0;
@@ -1243,7 +1243,7 @@
                 try {
                     edThresh = ((AInt32) 
ATypeHierarchy.convertNumericTypeObject(simThresh, ATypeTag.INTEGER))
                             .getIntegerValue();
-                } catch (AsterixException e) {
+                } catch (HyracksDataException e) {
                     throw new AlgebricksException(e);
                 }
 
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 35b7d4c..171b278 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -58,6 +58,10 @@
     public static final int ROOT_LOCAL_RESOURCE_EXISTS = 15;
     public static final int ROOT_LOCAL_RESOURCE_COULD_NOT_BE_CREATED = 16;
     public static final int UNKNOWN_EXTERNAL_FILE_PENDING_OP = 17;
+    public static final int TYPE_CONVERT = 18;
+    public static final int TYPE_CONVERT_INTEGER_SOURCE = 19;
+    public static final int TYPE_CONVERT_INTEGER_TARGET = 20;
+    public static final int TYPE_CONVERT_OUT_OF_BOUND = 21;
     public static final int INSTANTIATION_ERROR = 100;
 
     // Compilation errors
diff --git 
a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties 
b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index 1f80fad..f192034 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -51,6 +51,10 @@
 15 = Storage metadata directory of %1$s in %2$s already exists
 16 = Storage metadata directory of %1$s in %2$s couldn't be created
 17 = Unknown external file pending operation %1$s
+18 = Cannot convert the %1$s type to the %2$s type.
+19 = Can't convert integer types. The source type should be one of %1$s.
+20 = Can't convert integer types. The target type should be one of %1$s.
+21 = Source value %1$s is out of range that %2$s can hold - %2$s.MAX_VALUE: 
%3$s, %2$s.MIN_VALUE: %4$s
 100 = Unable to instantiate class %1$s
 
 # Compile-time check errors
diff --git 
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalFunction.java
 
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalFunction.java
index 493a0bf..c644413 100755
--- 
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalFunction.java
+++ 
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalFunction.java
@@ -102,7 +102,7 @@
             if (sourceTypeTag != targetTypeTag) {
                 castBuffer.reset();
                 
ATypeHierarchy.convertNumericTypeByteArray(inputVal.getByteArray(), 
inputVal.getStartOffset(),
-                        inputVal.getLength(), targetTypeTag, 
castBuffer.getDataOutput());
+                        inputVal.getLength(), targetTypeTag, 
castBuffer.getDataOutput(), true);
                 functionHelper.setArgument(i, castBuffer);
             } else {
                 functionHelper.setArgument(i, inputVal);
diff --git 
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ADMDataParser.java
 
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ADMDataParser.java
index 18bf52c..9bb6ba9 100644
--- 
a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ADMDataParser.java
+++ 
b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ADMDataParser.java
@@ -850,7 +850,7 @@
                         castBuffer.getLength() - 1, out);
             } else if (ATypeHierarchy.canDemote(typeTag, targetTypeTag)) {
                 // can demote source type to the target type
-                ITypeConvertComputer demoteComputer = 
ATypeHierarchy.getTypeDemoteComputer(typeTag, targetTypeTag);
+                ITypeConvertComputer demoteComputer = 
ATypeHierarchy.getTypeDemoteComputer(typeTag, targetTypeTag, true);
                 if (demoteComputer == null) {
                     throw new 
ParseException(ErrorCode.PARSER_ADM_DATA_PARSER_CAST_ERROR, typeTag, 
targetTypeTag);
                 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/hash/AMurmurHash3BinaryHashFunctionFamily.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/hash/AMurmurHash3BinaryHashFunctionFamily.java
index 5a43d21..5f5ff76 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/hash/AMurmurHash3BinaryHashFunctionFamily.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/hash/AMurmurHash3BinaryHashFunctionFamily.java
@@ -66,7 +66,7 @@
                     case INTEGER:
                     case BIGINT:
                         try {
-                            
IntegerToDoubleTypeConvertComputer.INSTANCE.convertType(bytes, offset + 1, 
length - 1,
+                            
IntegerToDoubleTypeConvertComputer.getInstance().convertType(bytes, offset + 1, 
length - 1,
                                     fieldValueBufferOutput);
                         } catch (IOException e) {
                             throw new HyracksDataException(
@@ -78,7 +78,7 @@
 
                     case FLOAT:
                         try {
-                            
FloatToDoubleTypeConvertComputer.INSTANCE.convertType(bytes, offset + 1, length 
- 1,
+                            
FloatToDoubleTypeConvertComputer.getInstance().convertType(bytes, offset + 1, 
length - 1,
                                     fieldValueBufferOutput);
                         } catch (IOException e) {
                             throw new HyracksDataException(
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ACastVisitor.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ACastVisitor.java
index 5f0b0a9..b161365 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ACastVisitor.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ACastVisitor.java
@@ -110,7 +110,7 @@
             try {
                 castBuffer.reset();
                 
ATypeHierarchy.convertNumericTypeByteArray(accessor.getByteArray(), 
accessor.getStartOffset(),
-                        accessor.getLength(), reqTypeTag, 
castBuffer.getDataOutput());
+                        accessor.getLength(), reqTypeTag, 
castBuffer.getDataOutput(), true);
                 arg.first.set(castBuffer);
             } catch (IOException e1) {
                 throw new HyracksDataException(
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ATypeHierarchy.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ATypeHierarchy.java
index 8b0c041..af8420a 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ATypeHierarchy.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ATypeHierarchy.java
@@ -20,38 +20,31 @@
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.RuntimeDataException;
-import org.apache.asterix.om.base.ADouble;
-import org.apache.asterix.om.base.AFloat;
-import org.apache.asterix.om.base.AInt16;
-import org.apache.asterix.om.base.AInt32;
-import org.apache.asterix.om.base.AInt64;
-import org.apache.asterix.om.base.AInt8;
 import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.constants.AsterixConstantValue;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
-import org.apache.hyracks.data.std.primitive.FloatPointable;
 import org.apache.hyracks.data.std.primitive.IntegerPointable;
 import org.apache.hyracks.data.std.primitive.LongPointable;
-import org.apache.hyracks.data.std.primitive.ShortPointable;
 
 public class ATypeHierarchy {
 
-    private static BitSet typePromotionHierachyMap = new 
BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
-    private static BitSet typeDemotionHierachyMap = new 
BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
-    private static HashMap<Integer, ITypeConvertComputer> promoteComputerMap = 
new HashMap<Integer, ITypeConvertComputer>();
-    private static HashMap<Integer, ITypeConvertComputer> demoteComputerMap = 
new HashMap<Integer, ITypeConvertComputer>();
-    private static Map<ATypeTag, Domain> hierarchyDomains = new 
HashMap<ATypeTag, Domain>();
+    private static final BitSet typePromotionHierachyMap = new 
BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
+    private static final BitSet typeDemotionHierachyMap = new 
BitSet(ATypeTag.TYPE_COUNT * ATypeTag.TYPE_COUNT);
+    private static final Map<Integer, ITypeConvertComputer> promoteComputerMap 
= new HashMap<>();
+    private static final Map<Integer, Pair<ITypeConvertComputer, 
ITypeConvertComputer>> demoteComputerMap =
+            new HashMap<>();
+    private static Map<ATypeTag, Domain> hierarchyDomains = new HashMap<>();
 
     // allow type promotion or demotion to the type itself
     static {
@@ -65,42 +58,58 @@
     static {
         // Promotion (widening): TINYINT -> SMALLINT -> INTEGER -> BIGINT -> 
FLOAT -> DOUBLE
         // No precision and range loss
-        addPromotionRule(ATypeTag.TINYINT, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.TINYINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.TINYINT, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.INTEGER, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.TINYINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.INTEGER, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.BIGINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.FLOAT, ATypeTag.DOUBLE, 
FloatToDoubleTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.TINYINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.INTEGER, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.INSTANCE);
-        addPromotionRule(ATypeTag.BIGINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.INSTANCE);
+        addPromotionRule(ATypeTag.TINYINT, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.getInstance(true));
+        addPromotionRule(ATypeTag.TINYINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.getInstance(true));
+        addPromotionRule(ATypeTag.TINYINT, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.getInstance(true));
+        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.INTEGER, ATypeTag.BIGINT, 
IntegerToInt64TypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.TINYINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.INTEGER, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.BIGINT, ATypeTag.DOUBLE, 
IntegerToDoubleTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.FLOAT, ATypeTag.DOUBLE, 
FloatToDoubleTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.TINYINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.SMALLINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.INTEGER, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.getInstance());
+        addPromotionRule(ATypeTag.BIGINT, ATypeTag.FLOAT, 
IntegerToFloatTypeConvertComputer.getInstance());
     }
 
     static {
         // Demotion (narrowing): DOUBLE -> FLOAT -> BIGINT -> INTEGER -> 
SMALLINT -> TINYINT
         // Possible precision loss (e.g., FLOAT to INT)
-        // This may produce an exception (if source value is greater than 
target.MAX or less than target.MIN)
-        addDemotionRule(ATypeTag.SMALLINT, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.INTEGER, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.BIGINT, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.INTEGER, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.BIGINT, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.BIGINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.FLOAT, ATypeTag.TINYINT, 
FloatToInt8TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.FLOAT, ATypeTag.SMALLINT, 
FloatToInt16TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.FLOAT, ATypeTag.INTEGER, 
FloatToInt32TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.FLOAT, ATypeTag.BIGINT, 
FloatToInt64TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.TINYINT, 
DoubleToInt8TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.SMALLINT, 
DoubleToInt16TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.INTEGER, 
DoubleToInt32TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.BIGINT, 
DoubleToInt64TypeConvertComputer.INSTANCE);
-        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.FLOAT, 
DoubleToFloatTypeConvertComputer.INSTANCE);
+        // 'strict' mode produces an exception if source value is greater than 
target.MAX or less than target.MIN
+        // 'lax' mode does not fail. it returns target.MAX/target.MIN if 
source value is out of range
+        addDemotionRule(ATypeTag.SMALLINT, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.getInstance(true),
+                IntegerToInt8TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.INTEGER, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.getInstance(true),
+                IntegerToInt8TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.BIGINT, ATypeTag.TINYINT, 
IntegerToInt8TypeConvertComputer.getInstance(true),
+                IntegerToInt8TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.INTEGER, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.getInstance(true),
+                IntegerToInt16TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.BIGINT, ATypeTag.SMALLINT, 
IntegerToInt16TypeConvertComputer.getInstance(true),
+                IntegerToInt16TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.BIGINT, ATypeTag.INTEGER, 
IntegerToInt32TypeConvertComputer.getInstance(true),
+                IntegerToInt32TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.FLOAT, ATypeTag.TINYINT, 
FloatToInt8TypeConvertComputer.getInstance(true),
+                FloatToInt8TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.FLOAT, ATypeTag.SMALLINT, 
FloatToInt16TypeConvertComputer.getInstance(true),
+                FloatToInt16TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.FLOAT, ATypeTag.INTEGER, 
FloatToInt32TypeConvertComputer.getInstance(true),
+                FloatToInt32TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.FLOAT, ATypeTag.BIGINT, 
FloatToInt64TypeConvertComputer.getInstance(true),
+                FloatToInt64TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.TINYINT, 
DoubleToInt8TypeConvertComputer.getInstance(true),
+                DoubleToInt8TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.SMALLINT, 
DoubleToInt16TypeConvertComputer.getInstance(true),
+                DoubleToInt16TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.INTEGER, 
DoubleToInt32TypeConvertComputer.getInstance(true),
+                DoubleToInt32TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.BIGINT, 
DoubleToInt64TypeConvertComputer.getInstance(true),
+                DoubleToInt64TypeConvertComputer.getInstance(false));
+        addDemotionRule(ATypeTag.DOUBLE, ATypeTag.FLOAT, 
DoubleToFloatTypeConvertComputer.getInstance(true),
+                DoubleToFloatTypeConvertComputer.getInstance(false));
     }
 
     static {
@@ -135,16 +144,17 @@
         return tagHierarchy1.equals(tagHierarchy2) && !useListDomain;
     }
 
-    public static void addPromotionRule(ATypeTag type1, ATypeTag type2, 
ITypeConvertComputer promoteComputer) {
+    private static void addPromotionRule(ATypeTag type1, ATypeTag type2, 
ITypeConvertComputer promoteComputer) {
         int index = type1.ordinal() * ATypeTag.TYPE_COUNT + type2.ordinal();
         typePromotionHierachyMap.set(index);
         promoteComputerMap.put(index, promoteComputer);
     }
 
-    public static void addDemotionRule(ATypeTag type1, ATypeTag type2, 
ITypeConvertComputer demoteComputer) {
+    private static void addDemotionRule(ATypeTag type1, ATypeTag type2, 
ITypeConvertComputer demoteStrictComputer,
+            ITypeConvertComputer demoteLenientComputer) {
         int index = type1.ordinal() * ATypeTag.TYPE_COUNT + type2.ordinal();
         typeDemotionHierachyMap.set(index);
-        demoteComputerMap.put(index, demoteComputer);
+        demoteComputerMap.put(index, Pair.of(demoteStrictComputer, 
demoteLenientComputer));
     }
 
     public static ITypeConvertComputer getTypePromoteComputer(ATypeTag type1, 
ATypeTag type2) {
@@ -154,9 +164,11 @@
         return null;
     }
 
-    public static ITypeConvertComputer getTypeDemoteComputer(ATypeTag type1, 
ATypeTag type2) {
+    public static ITypeConvertComputer getTypeDemoteComputer(ATypeTag type1, 
ATypeTag type2, boolean strict) {
         if (canDemote(type1, type2)) {
-            return demoteComputerMap.get(type1.ordinal() * ATypeTag.TYPE_COUNT 
+ type2.ordinal());
+            Pair<ITypeConvertComputer, ITypeConvertComputer> pair =
+                    demoteComputerMap.get(type1.ordinal() * 
ATypeTag.TYPE_COUNT + type2.ordinal());
+            return strict ? pair.getLeft() : pair.getRight();
         }
         return null;
     }
@@ -179,559 +191,167 @@
 
     // Get an AsterixConstantValue from a source Object
     public static AsterixConstantValue 
getAsterixConstantValueFromNumericTypeObject(IAObject sourceObject,
-            ATypeTag targetTypeTag) throws AlgebricksException {
+            ATypeTag targetTypeTag) throws HyracksDataException {
+        return getAsterixConstantValueFromNumericTypeObject(sourceObject, 
targetTypeTag, false);
+    }
+
+    // Get an AsterixConstantValue from a source Object
+    public static AsterixConstantValue 
getAsterixConstantValueFromNumericTypeObject(IAObject sourceObject,
+            ATypeTag targetTypeTag, boolean strictDemote) throws 
HyracksDataException {
         ATypeTag sourceTypeTag = sourceObject.getType().getTypeTag();
-        AsterixConstantValue asterixNewConstantValue = null;
-        short tmpShortValue;
-        int tmpIntValue;
-        long tmpLongValue;
-        float tmpFloatValue;
-        double tmpDoubleValue;
-
-        // if the constant type and target type does not match, we do a type 
conversion
-        if (sourceTypeTag != targetTypeTag) {
-
-            switch (targetTypeTag) {
-                //Target Field Type:BIGINT
-                case BIGINT:
-
-                    // Change the Constant Type to BIGINT Type
-                    switch (sourceTypeTag) {
-                        case TINYINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt64((long) ((AInt8) 
sourceObject).getByteValue()));
-                            break;
-
-                        case SMALLINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt64((long) ((AInt16) 
sourceObject).getShortValue()));
-                            break;
-
-                        case INTEGER:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt64((long) ((AInt32) 
sourceObject).getIntegerValue()));
-                            break;
-
-                        case FLOAT:
-                            tmpFloatValue = ((AFloat) 
sourceObject).getFloatValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.FLOAT, ATypeTag.BIGINT, 
tmpFloatValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt64((long) tmpFloatValue));
-                            break;
-
-                        case DOUBLE:
-                            tmpDoubleValue = ((ADouble) 
sourceObject).getDoubleValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.DOUBLE, ATypeTag.BIGINT, 
tmpDoubleValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt64((long) tmpDoubleValue));
-                            break;
-
-                        default:
-                            break;
-                    }
-
-                    break;
-
-                //Target Field Type:INTEGER
-                case INTEGER:
-
-                    // Change the Constant Type to INTEGER Type
-                    switch (sourceTypeTag) {
-                        case TINYINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt32(((AInt8) 
sourceObject).getByteValue()));
-                            break;
-
-                        case SMALLINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt32(((AInt16) 
sourceObject).getShortValue()));
-                            break;
-
-                        case BIGINT:
-                            tmpLongValue = ((AInt64) 
sourceObject).getLongValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.BIGINT, 
ATypeTag.INTEGER, tmpLongValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt32((int) tmpLongValue));
-                            break;
-
-                        case FLOAT:
-                            tmpFloatValue = ((AFloat) 
sourceObject).getFloatValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.FLOAT, ATypeTag.INTEGER, 
tmpFloatValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt32((int) tmpFloatValue));
-                            break;
-
-                        case DOUBLE:
-                            tmpDoubleValue = ((ADouble) 
sourceObject).getDoubleValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.FLOAT, ATypeTag.INTEGER, 
tmpDoubleValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt32((int) tmpDoubleValue));
-                            break;
-
-                        default:
-                            break;
-                    }
-
-                    break;
-
-                //Target Field Type:TINYINT
-                case TINYINT:
-
-                    // Change the Constant Type to TINYINT Type
-                    switch (sourceTypeTag) {
-                        case SMALLINT:
-                            tmpShortValue = ((AInt16) 
sourceObject).getShortValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.SMALLINT, 
ATypeTag.TINYINT, tmpShortValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt8((byte) tmpShortValue));
-                            break;
-
-                        case INTEGER:
-                            tmpIntValue = ((AInt32) 
sourceObject).getIntegerValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.INTEGER, 
ATypeTag.TINYINT, tmpIntValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt8((byte) tmpIntValue));
-                            break;
-
-                        case BIGINT:
-                            tmpLongValue = ((AInt64) 
sourceObject).getLongValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.BIGINT, 
ATypeTag.TINYINT, tmpLongValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt8((byte) tmpLongValue));
-                            break;
-
-                        case FLOAT:
-                            tmpFloatValue = ((AFloat) 
sourceObject).getFloatValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.FLOAT, ATypeTag.TINYINT, 
tmpFloatValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt8((byte) tmpFloatValue));
-                            break;
-
-                        case DOUBLE:
-                            tmpDoubleValue = ((ADouble) 
sourceObject).getDoubleValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.DOUBLE, 
ATypeTag.TINYINT, tmpDoubleValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt8((byte) tmpDoubleValue));
-                            break;
-
-                        default:
-                            break;
-                    }
-                    break;
-
-                //Target Field Type:SMALLINT
-                case SMALLINT:
-                    // Change the Constant Type to SMALLINT Type
-                    switch (sourceTypeTag) {
-                        case TINYINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AInt16(((AInt8) 
sourceObject).getByteValue()));
-                            break;
-
-                        case INTEGER:
-                            tmpIntValue = ((AInt32) 
sourceObject).getIntegerValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.INTEGER, 
ATypeTag.SMALLINT, tmpIntValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt16((short) tmpIntValue));
-                            break;
-
-                        case BIGINT:
-                            tmpLongValue = ((AInt64) 
sourceObject).getLongValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.BIGINT, 
ATypeTag.SMALLINT, tmpLongValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt16((short) tmpLongValue));
-                            break;
-
-                        case FLOAT:
-                            tmpFloatValue = ((AFloat) 
sourceObject).getFloatValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.FLOAT, 
ATypeTag.SMALLINT, tmpFloatValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt16((short) tmpFloatValue));
-                            break;
-
-                        case DOUBLE:
-                            tmpDoubleValue = ((ADouble) 
sourceObject).getDoubleValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.DOUBLE, 
ATypeTag.SMALLINT, tmpDoubleValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AInt16((short) tmpDoubleValue));
-                            break;
-
-                        default:
-                            break;
-                    }
-                    break;
-
-                //Target Field Type:FLOAT
-                case FLOAT:
-                    // Change the Constant Type to FLOAT Type
-                    switch (sourceTypeTag) {
-                        case TINYINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AFloat(((AInt8) 
sourceObject).getByteValue()));
-                            break;
-
-                        case SMALLINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AFloat(((AInt16) 
sourceObject).getShortValue()));
-                            break;
-
-                        case INTEGER:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AFloat(((AInt32) 
sourceObject).getIntegerValue()));
-                            break;
-
-                        case BIGINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new AFloat(((AInt64) 
sourceObject).getLongValue()));
-                            break;
-
-                        case DOUBLE:
-                            tmpDoubleValue = ((ADouble) 
sourceObject).getDoubleValue();
-                            // Check whether this value is within the range of 
the field type
-                            valueSanitycheck(ATypeTag.DOUBLE, ATypeTag.FLOAT, 
tmpDoubleValue);
-                            asterixNewConstantValue = new 
AsterixConstantValue(new AFloat((float) tmpDoubleValue));
-                            break;
-
-                        default:
-                            break;
-                    }
-                    break;
-
-                //Target Field Type:DOUBLE
-                case DOUBLE:
-                    // Change the Constant Type to DOUBLE Type
-                    switch (sourceTypeTag) {
-                        case TINYINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new ADouble(((AInt8) 
sourceObject).getByteValue()));
-                            break;
-
-                        case SMALLINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new ADouble(((AInt16) 
sourceObject).getShortValue()));
-                            break;
-
-                        case INTEGER:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new ADouble(((AInt32) 
sourceObject).getIntegerValue()));
-                            break;
-
-                        case BIGINT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new ADouble(((AInt64) 
sourceObject).getLongValue()));
-                            break;
-
-                        case FLOAT:
-                            asterixNewConstantValue = new AsterixConstantValue(
-                                    new ADouble(((AFloat) 
sourceObject).getFloatValue()));
-                            break;
-
-                        default:
-                            break;
-                    }
-                    break;
-
-                default:
-                    break;
-            }
-
-            return asterixNewConstantValue;
-
-        } else {
-
+        if (sourceTypeTag == targetTypeTag) {
             return new AsterixConstantValue(sourceObject);
         }
 
-    }
-
-    // checks whether the source value is within the range of the target type
-    private static void valueSanitycheck(ATypeTag sourceType, ATypeTag 
targetType, double sourceValue)
-            throws AlgebricksException {
-        boolean canConvert = true;
-
-        switch (targetType) {
-            case TINYINT:
-                if (sourceValue > Byte.MAX_VALUE || sourceValue < 
Byte.MIN_VALUE) {
-                    canConvert = false;
-                }
-                break;
-
-            case SMALLINT:
-                if (sourceValue > Short.MAX_VALUE || sourceValue < 
Short.MIN_VALUE) {
-                    canConvert = false;
-                }
-                break;
-            case INTEGER:
-                if (sourceValue > Integer.MAX_VALUE || sourceValue < 
Integer.MIN_VALUE) {
-                    canConvert = false;
-                }
-                break;
-            case BIGINT:
-                if (sourceValue > Long.MAX_VALUE || sourceValue < 
Long.MIN_VALUE) {
-                    canConvert = false;
-                }
-                break;
-            case FLOAT:
-                if (sourceValue > Float.MAX_VALUE || sourceValue < 
Float.MIN_VALUE) {
-                    canConvert = false;
-                }
-                break;
-            default:
-                break;
+        // if the constant type and target type does not match, we do a type 
conversion
+        ITypeConvertComputer convertComputer;
+        if (canPromote(sourceTypeTag, targetTypeTag)) {
+            convertComputer = 
ATypeHierarchy.getTypePromoteComputer(sourceTypeTag, targetTypeTag);
+        } else if (canDemote(sourceTypeTag, targetTypeTag)) {
+            convertComputer = 
ATypeHierarchy.getTypeDemoteComputer(sourceTypeTag, targetTypeTag, 
strictDemote);
+        } else {
+            return null;
         }
 
-        if (!canConvert) {
-            throw new AlgebricksException("Can't cast a value: " + sourceValue 
+ " from " + sourceType + " type to "
-                    + targetType + " type because of the out-of-range error.");
-        }
+        IAObject targetObject = convertComputer.convertType(sourceObject);
+        return new AsterixConstantValue(targetObject);
     }
 
     // Type Casting from source Object to an Object with Target type
     public static IAObject convertNumericTypeObject(IAObject sourceObject, 
ATypeTag targetTypeTag)
-            throws AsterixException {
+            throws HyracksDataException {
+        return convertNumericTypeObject(sourceObject, targetTypeTag, false);
+    }
+
+    // Type Casting from source Object to an Object with Target type
+    public static IAObject convertNumericTypeObject(IAObject sourceObject, 
ATypeTag targetTypeTag, boolean strictDemote)
+            throws HyracksDataException {
         ATypeTag sourceTypeTag = sourceObject.getType().getTypeTag();
-
-        switch (sourceTypeTag) {
-            case TINYINT:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        return sourceObject;
-                    case SMALLINT:
-                        return new AInt16(((AInt8) 
sourceObject).getByteValue());
-                    case INTEGER:
-                        return new AInt32(((AInt8) 
sourceObject).getByteValue());
-                    case BIGINT:
-                        return new AInt64((long) ((AInt8) 
sourceObject).getByteValue());
-                    case FLOAT:
-                        return new AFloat(((AInt8) 
sourceObject).getByteValue());
-                    case DOUBLE:
-                        return new ADouble(((AInt8) 
sourceObject).getByteValue());
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-            case SMALLINT:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        // an exception can happen because of a type demotion 
from SMALLINT to TINYINT
-                        return new AInt8((byte) ((AInt16) 
sourceObject).getShortValue());
-                    case SMALLINT:
-                        return sourceObject;
-                    case INTEGER:
-                        return new AInt32(((AInt16) 
sourceObject).getShortValue());
-                    case BIGINT:
-                        return new AInt64((long) ((AInt16) 
sourceObject).getShortValue());
-                    case FLOAT:
-                        return new AFloat(((AInt16) 
sourceObject).getShortValue());
-                    case DOUBLE:
-                        return new ADouble(((AInt16) 
sourceObject).getShortValue());
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-
-            case INTEGER:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        // an exception can happen because of a type demotion 
from INTEGER to TINYINT
-                        return new AInt8(((AInt32) 
sourceObject).getIntegerValue().byteValue());
-                    case SMALLINT:
-                        // an exception can happen because of a type demotion 
from INTEGER to SMALLINT
-                        return new AInt16(((AInt32) 
sourceObject).getIntegerValue().shortValue());
-                    case INTEGER:
-                        return sourceObject;
-                    case BIGINT:
-                        return new AInt64((long) ((AInt32) 
sourceObject).getIntegerValue());
-                    case FLOAT:
-                        return new AFloat(((AInt32) 
sourceObject).getIntegerValue());
-                    case DOUBLE:
-                        return new ADouble(((AInt32) 
sourceObject).getIntegerValue());
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-
-            case BIGINT:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        // an exception can happen because of a type demotion 
from BIGINT to TINYINT
-                        return new AInt8((byte) ((AInt64) 
sourceObject).getLongValue());
-                    case SMALLINT:
-                        // an exception can happen because of a type demotion 
from BIGINT to SMALLINT
-                        return new AInt16((short) ((AInt64) 
sourceObject).getLongValue());
-                    case INTEGER:
-                        // an exception can happen because of a type demotion 
from BIGINT to INTEGER
-                        return new AInt32((int) ((AInt64) 
sourceObject).getLongValue());
-                    case BIGINT:
-                        return sourceObject;
-                    case FLOAT:
-                        return new AFloat(((AInt64) 
sourceObject).getLongValue());
-                    case DOUBLE:
-                        return new ADouble(((AInt64) 
sourceObject).getLongValue());
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-            case FLOAT:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        // an exception can happen because of a type demotion 
from FLOAT to TINYINT
-                        return new AInt8((byte) ((AFloat) 
sourceObject).getFloatValue());
-                    case SMALLINT:
-                        // an exception can happen because of a type demotion 
from FLOAT to SMALLINT
-                        return new AInt16((short) ((AFloat) 
sourceObject).getFloatValue());
-                    case INTEGER:
-                        // an exception can happen because of a type demotion 
from FLOAT to INTEGER
-                        return new AInt32((int) ((AFloat) 
sourceObject).getFloatValue());
-                    case BIGINT:
-                        // an exception can happen because of a type demotion 
from FLOAT to BIGINT
-                        return new AInt64((long) ((AFloat) 
sourceObject).getFloatValue());
-                    case FLOAT:
-                        return sourceObject;
-                    case DOUBLE:
-                        return new ADouble(((AFloat) 
sourceObject).getFloatValue());
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-            case DOUBLE:
-                switch (targetTypeTag) {
-                    case TINYINT:
-                        // an exception can happen because of a type demotion 
from DOUBLE to TINYINT
-                        return new AInt8((byte) ((ADouble) 
sourceObject).getDoubleValue());
-                    case SMALLINT:
-                        // an exception can happen because of a type demotion 
from DOUBLE to SMALLINT
-                        return new AInt16((short) ((ADouble) 
sourceObject).getDoubleValue());
-                    case INTEGER:
-                        // an exception can happen because of a type demotion 
from DOUBLE to INTEGER
-                        return new AInt32((int) ((ADouble) 
sourceObject).getDoubleValue());
-                    case BIGINT:
-                        // an exception can happen because of a type demotion 
from DOUBLE to BIGINT
-                        return new AInt64((long) ((ADouble) 
sourceObject).getDoubleValue());
-                    case FLOAT:
-                        // an exception can happen because of a type demotion 
from DOUBLE to FLOAT
-                        return new AFloat((float) ((ADouble) 
sourceObject).getDoubleValue());
-                    case DOUBLE:
-                        return sourceObject;
-                    default:
-                        throw new AsterixException(
-                                "Can't convert the " + sourceTypeTag + " type 
to the " + targetTypeTag + " type.");
-                }
-            default:
-                throw new AsterixException("Source type is not a numeric 
type.");
-
+        if (sourceTypeTag == targetTypeTag) {
+            return sourceObject;
         }
 
+        ITypeConvertComputer convertComputer;
+        if (canPromote(sourceTypeTag, targetTypeTag)) {
+            convertComputer = 
ATypeHierarchy.getTypePromoteComputer(sourceTypeTag, targetTypeTag);
+        } else if (canDemote(sourceTypeTag, targetTypeTag)) {
+            convertComputer = 
ATypeHierarchy.getTypeDemoteComputer(sourceTypeTag, targetTypeTag, 
strictDemote);
+        } else {
+            throw new RuntimeDataException(ErrorCode.TYPE_CONVERT, 
sourceTypeTag, targetTypeTag);
+        }
+
+        return convertComputer.convertType(sourceObject);
     }
 
     // convert a numeric value in a byte array to the target type value
     public static void convertNumericTypeByteArray(byte[] sourceByteArray, int 
s1, int l1, ATypeTag targetTypeTag,
             DataOutput out) throws IOException {
+        convertNumericTypeByteArray(sourceByteArray, s1, l1, targetTypeTag, 
out, false);
+    }
+
+    // convert a numeric value in a byte array to the target type value
+    public static void convertNumericTypeByteArray(byte[] sourceByteArray, int 
s1, int l1, ATypeTag targetTypeTag,
+            DataOutput out, boolean strictDemote) throws IOException {
         ATypeTag sourceTypeTag = 
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(sourceByteArray[s1]);
 
         if (sourceTypeTag != targetTypeTag) {
             // source tag can be promoted to target tag (e.g. tag1: SMALLINT, 
tag2: INTEGER)
-            if (ATypeHierarchy.canPromote(sourceTypeTag, targetTypeTag)) {
+            if (canPromote(sourceTypeTag, targetTypeTag)) {
                 ITypeConvertComputer convertComputer =
                         ATypeHierarchy.getTypePromoteComputer(sourceTypeTag, 
targetTypeTag);
                 convertComputer.convertType(sourceByteArray, s1 + 1, l1 - 1, 
out);
                 // source tag can be demoted to target tag
-            } else if (ATypeHierarchy.canDemote(sourceTypeTag, targetTypeTag)) 
{
+            } else if (canDemote(sourceTypeTag, targetTypeTag)) {
                 ITypeConvertComputer convertComputer =
-                        ATypeHierarchy.getTypeDemoteComputer(sourceTypeTag, 
targetTypeTag);
+                        ATypeHierarchy.getTypeDemoteComputer(sourceTypeTag, 
targetTypeTag, strictDemote);
                 convertComputer.convertType(sourceByteArray, s1 + 1, l1 - 1, 
out);
             } else {
-                throw new IOException(
-                        "Can't convert the " + sourceTypeTag + " type to the " 
+ targetTypeTag + " type.");
+                throw new RuntimeDataException(ErrorCode.TYPE_CONVERT, 
sourceTypeTag, targetTypeTag);
             }
         }
-
     }
-
 
     // Get an INT value from numeric types array. We assume the first byte 
contains the type tag.
     public static int getIntegerValue(String name, int argIndex, byte[] bytes, 
int offset) throws HyracksDataException {
-        return getIntegerValueWithDifferentTypeTagPosition(name, argIndex, 
bytes, offset + 1, offset);
+        return getIntegerValue(name, argIndex, bytes, offset, false);
+    }
+
+    // Get an INT value from numeric types array. We assume the first byte 
contains the type tag.
+    public static int getIntegerValue(String name, int argIndex, byte[] bytes, 
int offset, boolean strictDemote)
+            throws HyracksDataException {
+        return getIntegerValueWithDifferentTypeTagPosition(name, argIndex, 
bytes, offset + 1, offset, strictDemote);
     }
 
     // Get an INT value from numeric types array. We assume the specific 
location of a byte array contains the type tag.
     public static int getIntegerValueWithDifferentTypeTagPosition(String name, 
int argIndex, byte[] bytes, int offset,
             int typeTagPosition) throws HyracksDataException {
-        int value;
-        ATypeTag sourceTypeTag = 
ATypeTag.VALUE_TYPE_MAPPING[bytes[typeTagPosition]];
+        return getIntegerValueWithDifferentTypeTagPosition(name, argIndex, 
bytes, offset, typeTagPosition, false);
+    }
 
+    // Get an INT value from numeric types array. We assume the specific 
location of a byte array contains the type tag.
+    public static int getIntegerValueWithDifferentTypeTagPosition(String name, 
int argIndex, byte[] bytes, int offset,
+            int typeTagPosition, boolean strictDemote) throws 
HyracksDataException {
+        ATypeTag sourceTypeTag = 
ATypeTag.VALUE_TYPE_MAPPING[bytes[typeTagPosition]];
         if (sourceTypeTag == null) {
             throw new RuntimeDataException(ErrorCode.INVALID_FORMAT, name, 
argIndex);
         }
         switch (sourceTypeTag) {
-            case BIGINT:
-                value = (int) LongPointable.getLong(bytes, offset);
-                break;
             case INTEGER:
-                value = IntegerPointable.getInteger(bytes, offset);
-                break;
+                return IntegerPointable.getInteger(bytes, offset);
             case TINYINT:
-                value = bytes[offset];
-                break;
             case SMALLINT:
-                value = ShortPointable.getShort(bytes, offset);
-                break;
+            case BIGINT:
+                return (int) 
IntegerToInt32TypeConvertComputer.getInstance(strictDemote).convertIntegerType(bytes,
+                        offset, sourceTypeTag, ATypeTag.INTEGER);
             case FLOAT:
-                value = (int) FloatPointable.getFloat(bytes, offset);
-                break;
+                return 
FloatToInt32TypeConvertComputer.getInstance(strictDemote).convertType(bytes, 
offset);
             case DOUBLE:
-                value = (int) DoublePointable.getDouble(bytes, offset);
-                break;
+                return 
DoubleToInt32TypeConvertComputer.getInstance(strictDemote).convertType(bytes, 
offset);
             default:
-                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex, sourceTypeTag,
-                        ATypeTag.TINYINT, ATypeTag.SMALLINT, ATypeTag.INTEGER, 
ATypeTag.BIGINT, ATypeTag.FLOAT,
-                        ATypeTag.DOUBLE);
-
+                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex,
+                        Arrays.toString(new Object[] { ATypeTag.TINYINT, 
ATypeTag.SMALLINT, ATypeTag.INTEGER,
+                                ATypeTag.BIGINT, ATypeTag.FLOAT, 
ATypeTag.DOUBLE }),
+                        sourceTypeTag);
         }
-
-        return value;
     }
 
     // Get a LONG (bigint) value from numeric types array. We assume the first 
byte contains the type tag.
     public static long getLongValue(String name, int argIndex, byte[] bytes, 
int offset) throws HyracksDataException {
-        return getLongValueWithDifferentTypeTagPosition(name, argIndex, bytes, 
offset + 1, offset);
+        return getLongValue(name, argIndex, bytes, offset, false);
+    }
+
+    // Get a LONG (bigint) value from numeric types array. We assume the first 
byte contains the type tag.
+    public static long getLongValue(String name, int argIndex, byte[] bytes, 
int offset, boolean strictDemote)
+            throws HyracksDataException {
+        return getLongValueWithDifferentTypeTagPosition(name, argIndex, bytes, 
offset + 1, offset, strictDemote);
     }
 
     // Get a LONG (bigint) value from numeric types array. We assume the 
specific location of a byte array
     // contains the type tag.
     private static long getLongValueWithDifferentTypeTagPosition(String name, 
int argIndex, byte[] bytes, int offset,
-            int typeTagPosition) throws HyracksDataException {
-        long value;
+            int typeTagPosition, boolean strictDemote) throws 
HyracksDataException {
         ATypeTag sourceTypeTag = 
ATypeTag.VALUE_TYPE_MAPPING[bytes[typeTagPosition]];
         if (sourceTypeTag == null) {
             throw new RuntimeDataException(ErrorCode.INVALID_FORMAT, name, 
argIndex);
         }
         switch (sourceTypeTag) {
             case BIGINT:
-                value = LongPointable.getLong(bytes, offset);
-                break;
-            case INTEGER:
-                value = IntegerPointable.getInteger(bytes, offset);
-                break;
+                return LongPointable.getLong(bytes, offset);
             case TINYINT:
-                value = bytes[offset];
-                break;
             case SMALLINT:
-                value = ShortPointable.getShort(bytes, offset);
-                break;
+            case INTEGER:
+                return 
IntegerToInt64TypeConvertComputer.getInstance().convertIntegerType(bytes, 
offset, sourceTypeTag,
+                        ATypeTag.BIGINT);
             case FLOAT:
-                value = (long) FloatPointable.getFloat(bytes, offset);
-                break;
+                return 
FloatToInt64TypeConvertComputer.getInstance(strictDemote).convertType(bytes, 
offset);
             case DOUBLE:
-                value = (long) DoublePointable.getDouble(bytes, offset);
-                break;
+                return 
DoubleToInt64TypeConvertComputer.getInstance(strictDemote).convertType(bytes, 
offset);
             default:
-                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex, sourceTypeTag,
-                        ATypeTag.TINYINT, ATypeTag.SMALLINT, ATypeTag.INTEGER, 
ATypeTag.BIGINT, ATypeTag.FLOAT,
-                        ATypeTag.DOUBLE);
+                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex,
+                        Arrays.toString(new Object[] { ATypeTag.TINYINT, 
ATypeTag.SMALLINT, ATypeTag.INTEGER,
+                                ATypeTag.BIGINT, ATypeTag.FLOAT, 
ATypeTag.DOUBLE }),
+                        sourceTypeTag);
         }
-
-        return value;
     }
 
     // Get a DOUBLE value from numeric types array. We assume the first byte 
contains the type tag.
@@ -742,46 +362,33 @@
 
     // Get a DOUBLE value from numeric types array. We assume the specific 
location of a byte array contains the type tag.
     private static double getDoubleValueWithDifferentTypeTagPosition(String 
name, int argIndex, byte[] bytes,
-            int offset, int typeTagPosition)
-            throws HyracksDataException {
-        double value;
+            int offset, int typeTagPosition) throws HyracksDataException {
         ATypeTag sourceTypeTag = 
ATypeTag.VALUE_TYPE_MAPPING[bytes[typeTagPosition]];
         if (sourceTypeTag == null) {
             throw new RuntimeDataException(ErrorCode.INVALID_FORMAT, name, 
argIndex);
         }
         switch (sourceTypeTag) {
-            case BIGINT:
-                value = LongPointable.getLong(bytes, offset);
-                break;
-            case INTEGER:
-                value = IntegerPointable.getInteger(bytes, offset);
-                break;
-            case TINYINT:
-                value = bytes[offset];
-                break;
-            case SMALLINT:
-                value = ShortPointable.getShort(bytes, offset);
-                break;
-            case FLOAT:
-                value = FloatPointable.getFloat(bytes, offset);
-                break;
             case DOUBLE:
-                value = DoublePointable.getDouble(bytes, offset);
-                break;
+                return DoublePointable.getDouble(bytes, offset);
+            case FLOAT:
+                return 
FloatToDoubleTypeConvertComputer.getInstance().convertType(bytes, offset);
+            case TINYINT:
+            case SMALLINT:
+            case INTEGER:
+            case BIGINT:
+                return 
IntegerToDoubleTypeConvertComputer.getInstance().convertType(bytes, offset, 
sourceTypeTag);
             default:
-                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex, sourceTypeTag,
-                        ATypeTag.TINYINT, ATypeTag.SMALLINT, ATypeTag.INTEGER, 
ATypeTag.BIGINT, ATypeTag.FLOAT,
-                        ATypeTag.DOUBLE);
+                throw new RuntimeDataException(ErrorCode.TYPE_MISMATCH, name, 
argIndex,
+                        Arrays.toString(new ATypeTag[] { ATypeTag.TINYINT, 
ATypeTag.SMALLINT, ATypeTag.INTEGER,
+                                ATypeTag.BIGINT, ATypeTag.FLOAT, 
ATypeTag.DOUBLE }),
+                        sourceTypeTag);
         }
-
-        return value;
     }
 
-    public static enum Domain {
+    public enum Domain {
         SPATIAL,
         NUMERIC,
         LIST,
         ANY
     }
-
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/AbstractIntegerTypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/AbstractIntegerTypeConvertComputer.java
index c646288..7fdc5da 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/AbstractIntegerTypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/AbstractIntegerTypeConvertComputer.java
@@ -20,20 +20,36 @@
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Arrays;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.primitive.BytePointable;
+import org.apache.hyracks.data.std.primitive.IntegerPointable;
+import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.primitive.ShortPointable;
 
 public abstract class AbstractIntegerTypeConvertComputer implements 
ITypeConvertComputer {
+
+    private final boolean strict;
+
+    protected AbstractIntegerTypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
 
     // Refer to the following to convert byte array to integer types, and vice 
versa.
     // https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html
     // https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html
-    public void convertIntegerType(byte[] data, int start, int length, 
DataOutput out, ATypeTag targetType,
+    protected void convertIntegerType(byte[] data, int start, int length, 
DataOutput out, ATypeTag targetType,
             int targetTypeLength) throws IOException {
-        long num = 0;
-        //        for (int i = start; i < start + length; i++) {
-        //            num += (data[i] & 0xff) << ((length - 1 - (i - start)) * 
8);
-        //        }
+        long num;
 
         // Read source values
         switch (length) {
@@ -63,41 +79,11 @@
                 break;
 
             default:
-                throw new IOException("Can't convert integer types. The source 
type should be one of "
-                        + "tinyint/smallint/integer/bigint.");
-
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
         }
 
-        // Boundary check
-        switch (targetType) {
-            case TINYINT:
-                if (num > Byte.MAX_VALUE || num < Byte.MIN_VALUE) {
-                    throw new IOException("Source value " + num
-                            + " is out of range that TINYINT can hold - 
TINYINT.MAX_VALUE:" + Byte.MAX_VALUE
-                            + ", TINYINT.MIN_VALUE:" + Byte.MIN_VALUE);
-                }
-                break;
-
-            case SMALLINT:
-                if (num > Short.MAX_VALUE || num < Short.MIN_VALUE) {
-                    throw new IOException("Source value " + num
-                            + " is out of range that SMALLINT can hold - 
SMALLINT.MAX_VALUE:" + Short.MAX_VALUE
-                            + ", SMALLINT.MIN_VALUE:" + Short.MIN_VALUE);
-                }
-                break;
-
-            case INTEGER:
-                if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
-                    throw new IOException("Source value " + num
-                            + " is out of range that INTEGER can hold - 
INTEGER.MAX_VALUE:" + Integer.MAX_VALUE
-                            + ", INTEGER.MIN_VALUE:" + Integer.MIN_VALUE);
-                }
-                break;
-
-            case BIGINT:
-            default:
-                break;
-        }
+        num = validate(num, targetType);
 
         out.writeByte(targetType.serialize());
 
@@ -135,13 +121,134 @@
                 break;
 
             default:
-                throw new IOException("Can't convert integer types. The target 
type should be one of "
-                        + "tinyint/smallint/integer/bigint.");
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_TARGET, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+    }
 
+    protected IAObject convertIntegerType(IAObject sourceObject, ATypeTag 
targetType) throws HyracksDataException {
+        long num;
+
+        switch (sourceObject.getType().getTypeTag()) {
+            case TINYINT:
+                num = ((AInt8) sourceObject).getByteValue();
+                break;
+            case SMALLINT:
+                num = ((AInt16) sourceObject).getShortValue();
+                break;
+            case INTEGER:
+                num = ((AInt32) sourceObject).getIntegerValue();
+                break;
+            case BIGINT:
+                num = ((AInt64) sourceObject).getLongValue();
+                break;
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
         }
 
-//        for (int i = targetTypeLength - 1; i >= 0; i--) {
-//            out.writeByte((byte) ((num >>> (i * 8)) & 0xFF));
-//        }
+        num = validate(num, targetType);
+
+        switch (targetType) {
+            case TINYINT:
+                return new AInt8((byte) num);
+            case SMALLINT:
+                return new AInt16((short) num);
+            case INTEGER:
+                return new AInt32((int) num);
+            case BIGINT:
+                return new AInt64(num);
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_TARGET, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+    }
+
+    protected long convertIntegerType(byte[] data, int start, ATypeTag 
sourceTypeTag, ATypeTag targetType)
+            throws HyracksDataException {
+        long num;
+        switch (sourceTypeTag) {
+            case TINYINT:
+                num = BytePointable.getByte(data, start);
+                break;
+            case SMALLINT:
+                num = ShortPointable.getShort(data, start);
+                break;
+            case INTEGER:
+                num = IntegerPointable.getInteger(data, start);
+                break;
+            case BIGINT:
+                num = LongPointable.getLong(data, start);
+                break;
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+
+        return validate(num, targetType);
+    }
+
+    private long validate(long num, ATypeTag targetType) throws 
HyracksDataException {
+        // Boundary check
+        switch (targetType) {
+            case TINYINT:
+                if (num > Byte.MAX_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Byte.MAX_VALUE, Byte.MIN_VALUE);
+                    } else {
+                        return Byte.MAX_VALUE;
+                    }
+                } else if (num < Byte.MIN_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Byte.MAX_VALUE, Byte.MIN_VALUE);
+                    } else {
+                        return Byte.MIN_VALUE;
+                    }
+                }
+                break;
+
+            case SMALLINT:
+                if (num > Short.MAX_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Short.MAX_VALUE, Short.MIN_VALUE);
+                    } else {
+                        return Short.MAX_VALUE;
+                    }
+                } else if (num < Short.MIN_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Short.MAX_VALUE, Short.MIN_VALUE);
+                    } else {
+                        return Short.MIN_VALUE;
+                    }
+                }
+                break;
+
+            case INTEGER:
+                if (num > Integer.MAX_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Integer.MAX_VALUE, Integer.MIN_VALUE);
+                    } else {
+                        return Integer.MAX_VALUE;
+                    }
+                } else if (num < Integer.MIN_VALUE) {
+                    if (strict) {
+                        raiseBoundaryException(num, targetType, 
Integer.MAX_VALUE, Integer.MIN_VALUE);
+                    } else {
+                        return Integer.MIN_VALUE;
+                    }
+                }
+                break;
+
+            case BIGINT:
+            default:
+                break;
+        }
+
+        return num;
+    }
+
+    private void raiseBoundaryException(long num, ATypeTag targetType, long 
maxValue, long minValue)
+            throws HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
num, targetType, maxValue, minValue);
     }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToFloatTypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToFloatTypeConvertComputer.java
index e6c450c..a12859d 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToFloatTypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToFloatTypeConvertComputer.java
@@ -21,28 +21,67 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
 
 public class DoubleToFloatTypeConvertComputer implements ITypeConvertComputer {
 
-    public static final DoubleToFloatTypeConvertComputer INSTANCE = new 
DoubleToFloatTypeConvertComputer();
+    private static final DoubleToFloatTypeConvertComputer STRICT = new 
DoubleToFloatTypeConvertComputer(true);
 
-    private DoubleToFloatTypeConvertComputer() {
+    private static final DoubleToFloatTypeConvertComputer LAX = new 
DoubleToFloatTypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private DoubleToFloatTypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static DoubleToFloatTypeConvertComputer getInstance(boolean strict) 
{
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
         double sourceValue = DoublePointable.getDouble(data, start);
-        // Boundary check
-        if (sourceValue > Float.MAX_VALUE || sourceValue < Float.MIN_VALUE) {
-            throw new IOException("Cannot convert Double to Float - Double 
value " + sourceValue
-                    + " is out of range that Float type can hold: 
Float.MAX_VALUE:" + Float.MAX_VALUE
-                    + ", Float.MIN_VALUE: " + Float.MIN_VALUE);
-        }
+        float targetValue = convert(sourceValue);
         out.writeByte(ATypeTag.FLOAT.serialize());
-        out.writeFloat((float) sourceValue);
+        out.writeFloat(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double sourceValue = ((ADouble) sourceObject).getDoubleValue();
+        float targetValue = convert(sourceValue);
+        return new AFloat(targetValue);
+    }
+
+    private float convert(double sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (sourceValue > Float.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Float.MAX_VALUE;
+            }
+        } else if (sourceValue < Float.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Float.MIN_VALUE;
+            }
+        }
+
+        return (float) sourceValue;
+    }
+
+    private void raiseBoundaryCheckException(double sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.FLOAT,
+                Float.MAX_VALUE, Float.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt16TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt16TypeConvertComputer.java
index f610bfe..2e57389 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt16TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt16TypeConvertComputer.java
@@ -21,30 +21,75 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
 
 public class DoubleToInt16TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final DoubleToInt16TypeConvertComputer INSTANCE = new 
DoubleToInt16TypeConvertComputer();
+    private static final DoubleToInt16TypeConvertComputer STRICT = new 
DoubleToInt16TypeConvertComputer(true);
 
-    private DoubleToInt16TypeConvertComputer() {
+    private static final DoubleToInt16TypeConvertComputer LAX = new 
DoubleToInt16TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private DoubleToInt16TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static DoubleToInt16TypeConvertComputer getInstance(boolean strict) 
{
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
         double sourceValue = DoublePointable.getDouble(data, start);
-        // Boundary check
-        if (sourceValue > Short.MAX_VALUE || sourceValue < Short.MIN_VALUE) {
-            throw new IOException("Cannot convert Double to SMALLINT - Double 
value " + sourceValue
-                    + " is out of range that SMALLINT type can hold: 
SMALLINT.MAX_VALUE:" + Short.MAX_VALUE
-                    + ", SMALLINT.MIN_VALUE: " + Short.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        short targetValue = (short) Math.floor(sourceValue);
+        short targetValue = convert(sourceValue);
         out.writeByte(ATypeTag.SMALLINT.serialize());
         out.writeShort(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double sourceValue = ((ADouble) sourceObject).getDoubleValue();
+        short targetValue = convert(sourceValue);
+        return new AInt16(targetValue);
+    }
+
+    private short convert(double sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Double.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        }
+        if (sourceValue > Short.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Short.MAX_VALUE;
+            }
+        } else if (sourceValue < Short.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Short.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (short) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryCheckException(double sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.SMALLINT,
+                Short.MAX_VALUE, Short.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt32TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt32TypeConvertComputer.java
index da974bb..e0eea44 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt32TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt32TypeConvertComputer.java
@@ -21,30 +21,78 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
 
 public class DoubleToInt32TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final DoubleToInt32TypeConvertComputer INSTANCE = new 
DoubleToInt32TypeConvertComputer();
+    private static final DoubleToInt32TypeConvertComputer STRICT = new 
DoubleToInt32TypeConvertComputer(true);
 
-    private DoubleToInt32TypeConvertComputer() {
+    private static final DoubleToInt32TypeConvertComputer LAX = new 
DoubleToInt32TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private DoubleToInt32TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static DoubleToInt32TypeConvertComputer getInstance(boolean strict) 
{
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        double sourceValue = DoublePointable.getDouble(data, start);
-        // Boundary check
-        if (sourceValue > Integer.MAX_VALUE || sourceValue < 
Integer.MIN_VALUE) {
-            throw new IOException("Cannot convert Double to INTEGER - Double 
value " + sourceValue
-                    + " is out of range that INTEGER type can hold: 
INTEGER.MAX_VALUE:" + Integer.MAX_VALUE
-                    + ", INTEGER.MIN_VALUE: " + Integer.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        int targetValue = (int) Math.floor(sourceValue);
+        int targetValue = convertType(data, start);
         out.writeByte(ATypeTag.INTEGER.serialize());
         out.writeInt(targetValue);
     }
 
+    int convertType(byte[] data, int start) throws HyracksDataException {
+        double sourceValue = DoublePointable.getDouble(data, start);
+        return convert(sourceValue);
+    }
+
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double sourceValue = ((ADouble) sourceObject).getDoubleValue();
+        int targetValue = convert(sourceValue);
+        return new AInt32(targetValue);
+    }
+
+    private int convert(double sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Double.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        } else if (sourceValue > Integer.MAX_VALUE) {
+            if (strict) {
+                return raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Integer.MAX_VALUE;
+            }
+        } else if (sourceValue < Integer.MIN_VALUE) {
+            if (strict) {
+                return raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Integer.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (int) Math.floor(sourceValue);
+    }
+
+    private int raiseBoundaryCheckException(double sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.INTEGER,
+                Integer.MAX_VALUE, Integer.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt64TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt64TypeConvertComputer.java
index 26daa94..a82f571 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt64TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt64TypeConvertComputer.java
@@ -21,30 +21,83 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
 
 public class DoubleToInt64TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final DoubleToInt64TypeConvertComputer INSTANCE = new 
DoubleToInt64TypeConvertComputer();
+    private static final DoubleToInt64TypeConvertComputer STRICT = new 
DoubleToInt64TypeConvertComputer(true);
 
-    private DoubleToInt64TypeConvertComputer() {
+    private static final DoubleToInt64TypeConvertComputer LAX = new 
DoubleToInt64TypeConvertComputer(false);
 
+    static DoubleToInt64TypeConvertComputer getInstance() {
+        return STRICT;
+    }
+
+    private final boolean strict;
+
+    private DoubleToInt64TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static DoubleToInt64TypeConvertComputer getInstance(boolean strict) 
{
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        double sourceValue = DoublePointable.getDouble(data, start);
-        // Boundary check
-        if (sourceValue > Long.MAX_VALUE || sourceValue < Long.MIN_VALUE) {
-            throw new IOException("Cannot convert Double to BIGINT - Double 
value " + sourceValue
-                    + " is out of range that BIGINT type can hold: 
BIGINT.MAX_VALUE:" + Long.MAX_VALUE
-                    + ", BIGINT.MIN_VALUE: " + Long.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        long targetValue = (long) Math.floor(sourceValue);
+        long targetValue = convertType(data, start);
         out.writeByte(ATypeTag.BIGINT.serialize());
         out.writeLong(targetValue);
     }
 
+    long convertType(byte[] data, int start) throws HyracksDataException {
+        double sourceValue = DoublePointable.getDouble(data, start);
+        return convert(sourceValue);
+    }
+
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double sourceValue = ((ADouble) sourceObject).getDoubleValue();
+        long targetValue = convert(sourceValue);
+        return new AInt64(targetValue);
+    }
+
+    private long convert(double sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Double.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        }
+        if (sourceValue > Long.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Long.MAX_VALUE;
+            }
+        } else if (sourceValue < Long.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Long.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (long) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryCheckException(double sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.BIGINT,
+                Long.MAX_VALUE, Long.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt8TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt8TypeConvertComputer.java
index 9b9fe12..42e22bc 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt8TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/DoubleToInt8TypeConvertComputer.java
@@ -21,30 +21,75 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.DoublePointable;
 
 public class DoubleToInt8TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final DoubleToInt8TypeConvertComputer INSTANCE = new 
DoubleToInt8TypeConvertComputer();
+    private static final DoubleToInt8TypeConvertComputer STRICT = new 
DoubleToInt8TypeConvertComputer(true);
 
-    private DoubleToInt8TypeConvertComputer() {
+    private static final DoubleToInt8TypeConvertComputer LAX = new 
DoubleToInt8TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private DoubleToInt8TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static DoubleToInt8TypeConvertComputer getInstance(boolean strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
         double sourceValue = DoublePointable.getDouble(data, start);
-        // Boundary check
-        if (sourceValue > Byte.MAX_VALUE || sourceValue < Byte.MIN_VALUE) {
-            throw new IOException("Cannot convert Double to TINYINT - Double 
value " + sourceValue
-                    + " is out of range that TINYINT type can hold: 
TINYINT.MAX_VALUE:" + Byte.MAX_VALUE
-                    + ", TINYINT.MIN_VALUE: " + Byte.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        byte targetValue = (byte) Math.floor(sourceValue);
+        byte targetValue = convert(sourceValue);
         out.writeByte(ATypeTag.TINYINT.serialize());
         out.writeByte(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double sourceValue = ((ADouble) sourceObject).getDoubleValue();
+        byte targetValue = convert(sourceValue);
+        return new AInt8(targetValue);
+    }
+
+    private byte convert(double sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Double.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        }
+        if (sourceValue > Byte.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Byte.MAX_VALUE;
+            }
+        } else if (sourceValue < Byte.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Byte.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (byte) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryCheckException(double sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.TINYINT,
+                Byte.MAX_VALUE, Byte.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToDoubleTypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToDoubleTypeConvertComputer.java
index 3695174..eaddfff 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToDoubleTypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToDoubleTypeConvertComputer.java
@@ -21,23 +21,39 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.FloatPointable;
 import 
org.apache.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 
 public class FloatToDoubleTypeConvertComputer implements ITypeConvertComputer {
 
-    public static final FloatToDoubleTypeConvertComputer INSTANCE = new 
FloatToDoubleTypeConvertComputer();
+    private static final FloatToDoubleTypeConvertComputer INSTANCE = new 
FloatToDoubleTypeConvertComputer();
 
     private FloatToDoubleTypeConvertComputer() {
+    }
 
+    public static FloatToDoubleTypeConvertComputer getInstance() {
+        return INSTANCE;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
+        double targetValue = convertType(data, start);
         out.writeByte(ATypeTag.DOUBLE.serialize());
-        DoubleSerializerDeserializer.INSTANCE.serialize((double) 
(FloatPointable.getFloat(data, start)),
-                out);
+        DoubleSerializerDeserializer.INSTANCE.serialize(targetValue, out);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        double targetValue = ((AFloat) sourceObject).getFloatValue();
+        return new ADouble(targetValue);
+    }
+
+    double convertType(byte[] data, int start) {
+        return FloatPointable.getFloat(data, start);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt16TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt16TypeConvertComputer.java
index 6ed8d06..03c55b5 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt16TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt16TypeConvertComputer.java
@@ -21,30 +21,75 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.FloatPointable;
 
 public class FloatToInt16TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final FloatToInt16TypeConvertComputer INSTANCE = new 
FloatToInt16TypeConvertComputer();
+    private static final FloatToInt16TypeConvertComputer STRICT = new 
FloatToInt16TypeConvertComputer(true);
 
-    private FloatToInt16TypeConvertComputer() {
+    private static final FloatToInt16TypeConvertComputer LAX = new 
FloatToInt16TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private FloatToInt16TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static FloatToInt16TypeConvertComputer getInstance(boolean strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
         float sourceValue = FloatPointable.getFloat(data, start);
-        // Boundary check
-        if (sourceValue > Short.MAX_VALUE || sourceValue < Short.MIN_VALUE) {
-            throw new IOException("Cannot convert Float to SMALLINT - Float 
value " + sourceValue
-                    + " is out of range that SMALLINT type can hold: 
SMALLINT.MAX_VALUE:" + Short.MAX_VALUE
-                    + ", SMALLINT.MIN_VALUE: " + Short.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        short targetValue = (short) Math.floor(sourceValue);
+        short targetValue = convert(sourceValue);
         out.writeByte(ATypeTag.SMALLINT.serialize());
         out.writeShort(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        float sourceValue = ((AFloat) sourceObject).getFloatValue();
+        short targetValue = convert(sourceValue);
+        return new AInt16(targetValue);
+    }
+
+    private short convert(float sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Float.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return 0;
+            }
+        }
+        if (sourceValue > Short.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return Short.MAX_VALUE;
+            }
+        } else if (sourceValue < Short.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return Short.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (short) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryException(float sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.SMALLINT,
+                Short.MAX_VALUE, Short.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt32TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt32TypeConvertComputer.java
index 6c4751b..d31993e 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt32TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt32TypeConvertComputer.java
@@ -21,30 +21,78 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.FloatPointable;
 
 public class FloatToInt32TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final FloatToInt32TypeConvertComputer INSTANCE = new 
FloatToInt32TypeConvertComputer();
+    private static final FloatToInt32TypeConvertComputer STRICT = new 
FloatToInt32TypeConvertComputer(true);
 
-    private FloatToInt32TypeConvertComputer() {
+    private static final FloatToInt32TypeConvertComputer LAX = new 
FloatToInt32TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private FloatToInt32TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static FloatToInt32TypeConvertComputer getInstance(boolean strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        float sourceValue = FloatPointable.getFloat(data, start);
-        // Boundary check
-        if (sourceValue > Integer.MAX_VALUE || sourceValue < 
Integer.MIN_VALUE) {
-            throw new IOException("Cannot convert Float to INTEGER - Float 
value " + sourceValue
-                    + " is out of range that INTEGER type can hold: 
INTEGER.MAX_VALUE:" + Integer.MAX_VALUE
-                    + ", INTEGER.MIN_VALUE: " + Integer.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        int targetValue = (int) Math.floor(sourceValue);
+        int targetValue = convertType(data, start);
         out.writeByte(ATypeTag.INTEGER.serialize());
         out.writeInt(targetValue);
     }
 
+    int convertType(byte data[], int start) throws HyracksDataException {
+        float sourceValue = FloatPointable.getFloat(data, start);
+        return convert(sourceValue);
+    }
+
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        float sourceValue = ((AFloat) sourceObject).getFloatValue();
+        int targetValue = convert(sourceValue);
+        return new AInt32(targetValue);
+    }
+
+    private int convert(float sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Float.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        } else if (sourceValue > Integer.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Integer.MAX_VALUE;
+            }
+        } else if (sourceValue < Integer.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Integer.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (int) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryCheckException(float sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.INTEGER,
+                Integer.MAX_VALUE, Integer.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt64TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt64TypeConvertComputer.java
index 43adddf..1a04e00 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt64TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt64TypeConvertComputer.java
@@ -21,30 +21,78 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.FloatPointable;
 
 public class FloatToInt64TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final FloatToInt64TypeConvertComputer INSTANCE = new 
FloatToInt64TypeConvertComputer();
+    private static final FloatToInt64TypeConvertComputer STRICT = new 
FloatToInt64TypeConvertComputer(true);
 
-    private FloatToInt64TypeConvertComputer() {
+    private static final FloatToInt64TypeConvertComputer LAX = new 
FloatToInt64TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private FloatToInt64TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static FloatToInt64TypeConvertComputer getInstance(boolean strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        float sourceValue = FloatPointable.getFloat(data, start);
-        // Boundary check
-        if (sourceValue > Long.MAX_VALUE || sourceValue < Long.MIN_VALUE) {
-            throw new IOException("Cannot convert Float to BIGINT - Float 
value " + sourceValue
-                    + " is out of range that BIGINT type can hold: 
BIGINT.MAX_VALUE:" + Long.MAX_VALUE
-                    + ", BIGINT.MIN_VALUE: " + Long.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        long targetValue = (long) Math.floor(sourceValue);
+        long targetValue = convertType(data, start);
         out.writeByte(ATypeTag.BIGINT.serialize());
         out.writeLong(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        float sourceValue = ((AFloat) sourceObject).getFloatValue();
+        long targetValue = convert(sourceValue);
+        return new AInt64(targetValue);
+    }
+
+    long convertType(byte[] data, int start) throws HyracksDataException {
+        float sourceValue = FloatPointable.getFloat(data, start);
+        return convert(sourceValue);
+    }
+
+    private long convert(float sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Float.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return 0;
+            }
+        } else if (sourceValue > Long.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Long.MAX_VALUE;
+            }
+        } else if (sourceValue < Long.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryCheckException(sourceValue);
+            } else {
+                return Long.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (long) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryCheckException(float sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.BIGINT,
+                Long.MAX_VALUE, Long.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt8TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt8TypeConvertComputer.java
index 355fe4c..c01ea83 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt8TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/FloatToInt8TypeConvertComputer.java
@@ -21,30 +21,74 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.primitive.FloatPointable;
 
 public class FloatToInt8TypeConvertComputer implements ITypeConvertComputer {
 
-    public static final FloatToInt8TypeConvertComputer INSTANCE = new 
FloatToInt8TypeConvertComputer();
+    private static final FloatToInt8TypeConvertComputer STRICT = new 
FloatToInt8TypeConvertComputer(true);
 
-    private FloatToInt8TypeConvertComputer() {
+    private static final FloatToInt8TypeConvertComputer LAX = new 
FloatToInt8TypeConvertComputer(false);
 
+    private final boolean strict;
+
+    private FloatToInt8TypeConvertComputer(boolean strict) {
+        this.strict = strict;
+    }
+
+    public static FloatToInt8TypeConvertComputer getInstance(boolean strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
         float sourceValue = FloatPointable.getFloat(data, start);
-        // Boundary check
-        if (sourceValue > Byte.MAX_VALUE || sourceValue < Byte.MIN_VALUE) {
-            throw new IOException("Cannot convert Float to TINYINT - Float 
value " + sourceValue
-                    + " is out of range that TINYINT type can hold: 
TINYINT.MAX_VALUE:" + Byte.MAX_VALUE
-                    + ", TINYINT.MIN_VALUE: " + Byte.MIN_VALUE);
-        }
-        // Math.floor to truncate decimal portion
-        byte targetValue = (byte) Math.floor(sourceValue);
+        byte targetValue = convert(sourceValue);
         out.writeByte(ATypeTag.TINYINT.serialize());
         out.writeByte(targetValue);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        float sourceValue = ((AFloat) sourceObject).getFloatValue();
+        byte targetValue = convert(sourceValue);
+        return new AInt8(targetValue);
+    }
+
+    private byte convert(float sourceValue) throws HyracksDataException {
+        // Boundary check
+        if (Float.isNaN(sourceValue)) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return 0;
+            }
+        } else if (sourceValue > Byte.MAX_VALUE) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return Byte.MAX_VALUE;
+            }
+        } else if (sourceValue < Byte.MIN_VALUE) {
+            if (strict) {
+                raiseBoundaryException(sourceValue);
+            } else {
+                return Byte.MIN_VALUE;
+            }
+        }
+
+        // Math.floor to truncate decimal portion
+        return (byte) Math.floor(sourceValue);
+    }
+
+    private void raiseBoundaryException(float sourceValue) throws 
HyracksDataException {
+        throw new RuntimeDataException(ErrorCode.TYPE_CONVERT_OUT_OF_BOUND, 
sourceValue, ATypeTag.TINYINT,
+                Byte.MAX_VALUE, Byte.MIN_VALUE);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ITypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ITypeConvertComputer.java
index acc7e45..a13878d 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ITypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/ITypeConvertComputer.java
@@ -21,9 +21,14 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.IAObject;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
 public interface ITypeConvertComputer {
 
     // promote or demote a type to a different type
     void convertType(byte[] data, int start, int length, DataOutput out) 
throws IOException;
 
+    // promote or demote a type to a different type
+    IAObject convertType(IAObject sourceObject) throws HyracksDataException;
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToDoubleTypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToDoubleTypeConvertComputer.java
index 0227937..df22301 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToDoubleTypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToDoubleTypeConvertComputer.java
@@ -20,21 +20,38 @@
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Arrays;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.primitive.BytePointable;
+import org.apache.hyracks.data.std.primitive.IntegerPointable;
+import org.apache.hyracks.data.std.primitive.LongPointable;
+import org.apache.hyracks.data.std.primitive.ShortPointable;
 import 
org.apache.hyracks.dataflow.common.data.marshalling.DoubleSerializerDeserializer;
 
 public class IntegerToDoubleTypeConvertComputer implements 
ITypeConvertComputer {
 
-    public static final IntegerToDoubleTypeConvertComputer INSTANCE = new 
IntegerToDoubleTypeConvertComputer();
+    private static final IntegerToDoubleTypeConvertComputer INSTANCE = new 
IntegerToDoubleTypeConvertComputer();
 
     private IntegerToDoubleTypeConvertComputer() {
+    }
 
+    public static IntegerToDoubleTypeConvertComputer getInstance() {
+        return INSTANCE;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        long val = 0L;
+        long val;
 
         // In order to convert a negative number correctly,
         // proper casting per INT type is needed.
@@ -66,10 +83,50 @@
                 break;
 
             default:
-                break;
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
         }
+
         out.writeByte(ATypeTag.DOUBLE.serialize());
-        DoubleSerializerDeserializer.INSTANCE.serialize(Double.valueOf(val), 
out);
+        DoubleSerializerDeserializer.INSTANCE.serialize((double) val, out);
     }
 
+    double convertType(byte[] data, int start, ATypeTag sourceTypeTag) throws 
HyracksDataException {
+        switch (sourceTypeTag) {
+            case TINYINT:
+                return BytePointable.getByte(data, start);
+            case SMALLINT:
+                return ShortPointable.getShort(data, start);
+            case INTEGER:
+                return IntegerPointable.getInteger(data, start);
+            case BIGINT:
+                return LongPointable.getLong(data, start);
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+    }
+
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        long val;
+        switch (sourceObject.getType().getTypeTag()) {
+            case TINYINT:
+                val = ((AInt8) sourceObject).getByteValue();
+                break;
+            case SMALLINT:
+                val = ((AInt16) sourceObject).getShortValue();
+                break;
+            case INTEGER:
+                val = ((AInt32) sourceObject).getIntegerValue();
+                break;
+            case BIGINT:
+                val = ((AInt64) sourceObject).getLongValue();
+                break;
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+        return new ADouble(val);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToFloatTypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToFloatTypeConvertComputer.java
index 85c4202..cba83b6 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToFloatTypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToFloatTypeConvertComputer.java
@@ -20,21 +20,34 @@
 
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Arrays;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
+import org.apache.asterix.om.base.AFloat;
+import org.apache.asterix.om.base.AInt16;
+import org.apache.asterix.om.base.AInt32;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AInt8;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 import 
org.apache.hyracks.dataflow.common.data.marshalling.FloatSerializerDeserializer;
 
 public class IntegerToFloatTypeConvertComputer implements ITypeConvertComputer 
{
 
-    public static final IntegerToFloatTypeConvertComputer INSTANCE = new 
IntegerToFloatTypeConvertComputer();
+    private static final IntegerToFloatTypeConvertComputer INSTANCE = new 
IntegerToFloatTypeConvertComputer();
 
     private IntegerToFloatTypeConvertComputer() {
+    }
 
+    public static IntegerToFloatTypeConvertComputer getInstance() {
+        return INSTANCE;
     }
 
     @Override
     public void convertType(byte[] data, int start, int length, DataOutput 
out) throws IOException {
-        float val = 0;
+        float val;
         // In order to convert a negative number correctly,
         // proper casting per INT type is needed.
         //
@@ -61,15 +74,36 @@
                         | ((long) (data[start + 2] & 0xff) << 40) | ((long) 
(data[start + 3] & 0xff) << 32)
                         | ((long) (data[start + 4] & 0xff) << 24) | ((long) 
(data[start + 5] & 0xff) << 16)
                         | ((long) (data[start + 6] & 0xff) << 8) | ((long) 
(data[start + 7] & 0xff)));
-
                 break;
 
             default:
-                break;
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
         }
         out.writeByte(ATypeTag.FLOAT.serialize());
         FloatSerializerDeserializer.INSTANCE.serialize(val, out);
-
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        float val;
+        switch (sourceObject.getType().getTypeTag()) {
+            case TINYINT:
+                val = ((AInt8) sourceObject).getByteValue();
+                break;
+            case SMALLINT:
+                val = ((AInt16) sourceObject).getShortValue();
+                break;
+            case INTEGER:
+                val = ((AInt32) sourceObject).getIntegerValue();
+                break;
+            case BIGINT:
+                val = ((AInt64) sourceObject).getLongValue();
+                break;
+            default:
+                throw new 
RuntimeDataException(ErrorCode.TYPE_CONVERT_INTEGER_SOURCE, Arrays.toString(
+                        new ATypeTag[] { ATypeTag.TINYINT, ATypeTag.SMALLINT, 
ATypeTag.INTEGER, ATypeTag.BIGINT }));
+        }
+        return new AFloat(val);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt16TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt16TypeConvertComputer.java
index 948e554..13b62dc 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt16TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt16TypeConvertComputer.java
@@ -21,14 +21,22 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class IntegerToInt16TypeConvertComputer extends 
AbstractIntegerTypeConvertComputer {
 
-    public static final IntegerToInt16TypeConvertComputer INSTANCE = new 
IntegerToInt16TypeConvertComputer();
+    private static final IntegerToInt16TypeConvertComputer STRICT = new 
IntegerToInt16TypeConvertComputer(true);
 
-    private IntegerToInt16TypeConvertComputer() {
+    private static final IntegerToInt16TypeConvertComputer LAX = new 
IntegerToInt16TypeConvertComputer(false);
 
+    private IntegerToInt16TypeConvertComputer(boolean strict) {
+        super(strict);
+    }
+
+    public static IntegerToInt16TypeConvertComputer getInstance(boolean 
strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
@@ -36,4 +44,8 @@
         convertIntegerType(data, start, length, out, ATypeTag.SMALLINT, 2);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        return convertIntegerType(sourceObject, ATypeTag.SMALLINT);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt32TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt32TypeConvertComputer.java
index be370cb..e9fbdf1 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt32TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt32TypeConvertComputer.java
@@ -21,13 +21,22 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class IntegerToInt32TypeConvertComputer extends 
AbstractIntegerTypeConvertComputer {
 
-    public static final IntegerToInt32TypeConvertComputer INSTANCE = new 
IntegerToInt32TypeConvertComputer();
+    private static final IntegerToInt32TypeConvertComputer STRICT = new 
IntegerToInt32TypeConvertComputer(true);
 
-    private IntegerToInt32TypeConvertComputer() {
+    private static final IntegerToInt32TypeConvertComputer LAX = new 
IntegerToInt32TypeConvertComputer(false);
+
+    private IntegerToInt32TypeConvertComputer(boolean strict) {
+        super(strict);
+    }
+
+    public static IntegerToInt32TypeConvertComputer getInstance(boolean 
strict) {
+        return strict ? STRICT : LAX;
     }
 
     @Override
@@ -35,4 +44,8 @@
         convertIntegerType(data, start, length, out, ATypeTag.INTEGER, 4);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        return convertIntegerType(sourceObject, ATypeTag.INTEGER);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt64TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt64TypeConvertComputer.java
index 5234b59..bfe1625 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt64TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt64TypeConvertComputer.java
@@ -21,13 +21,20 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class IntegerToInt64TypeConvertComputer extends 
AbstractIntegerTypeConvertComputer {
 
-    public static final IntegerToInt64TypeConvertComputer INSTANCE = new 
IntegerToInt64TypeConvertComputer();
+    private static final IntegerToInt64TypeConvertComputer INSTANCE = new 
IntegerToInt64TypeConvertComputer();
 
     private IntegerToInt64TypeConvertComputer() {
+        super(true);
+    }
+
+    public static IntegerToInt64TypeConvertComputer getInstance() {
+        return INSTANCE;
     }
 
     @Override
@@ -35,4 +42,8 @@
         convertIntegerType(data, start, length, out, ATypeTag.BIGINT, 8);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        return convertIntegerType(sourceObject, ATypeTag.BIGINT);
+    }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt8TypeConvertComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt8TypeConvertComputer.java
index 271ad25..07f8e66 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt8TypeConvertComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/hierachy/IntegerToInt8TypeConvertComputer.java
@@ -21,14 +21,22 @@
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class IntegerToInt8TypeConvertComputer extends 
AbstractIntegerTypeConvertComputer {
 
-    public static final IntegerToInt8TypeConvertComputer INSTANCE = new 
IntegerToInt8TypeConvertComputer();
+    private static final IntegerToInt8TypeConvertComputer STRICT = new 
IntegerToInt8TypeConvertComputer(true);
 
-    private IntegerToInt8TypeConvertComputer() {
+    private static final IntegerToInt8TypeConvertComputer LAX = new 
IntegerToInt8TypeConvertComputer(false);
 
+    private IntegerToInt8TypeConvertComputer(boolean strict) {
+        super(strict);
+    }
+
+    public static IntegerToInt8TypeConvertComputer getInstance(boolean strict) 
{
+        return strict ? STRICT : LAX;
     }
 
     @Override
@@ -36,4 +44,8 @@
         convertIntegerType(data, start, length, out, ATypeTag.TINYINT, 1);
     }
 
+    @Override
+    public IAObject convertType(IAObject sourceObject) throws 
HyracksDataException {
+        return convertIntegerType(sourceObject, ATypeTag.TINYINT);
+    }
 }

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/1800
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I68b78e2dc9ebf78799698a1c90bcd7cb5150137d
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <[email protected]>

Reply via email to