merged from asterix_lsm_stabilization -r1505:1510

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_lsm_stabilization_interval@1511 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/src/test/resources/runtimets/queries/constructor/interval/interval.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/constructor/interval/interval.3.query.aql
index ebb3d2d..f30fdd7 100644
--- a/asterix-app/src/test/resources/runtimets/queries/constructor/interval/interval.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/constructor/interval/interval.3.query.aql
@@ -1,11 +1,41 @@
 use dataverse test;
 
-let $itv1 := interval-from-date("2010-10-30", "2012-10-21")
-let $itv2 := interval-from-time("03:04:05.678-11:00", "232425267+0200")
-let $itv3 := interval-from-datetime("-1987-11-19T02:43:57.938+08:00", "19991112T124935948-0700")
-let $itv4 := interval-start-from-date("0001-12-27", "P3Y394DT48H398.483S")
-let $itv5 := interval-start-from-time("20:03:20.948", "P60DT48M389.938S")
-let $itv6 := interval-start-from-datetime("-2043-11-19T15:32:39.293", "P439Y3M20DT20H39M58.949S")
+let $itv11 := interval-from-date(date("2010-10-30"), date("2012-10-21"))
+let $itv12 := interval-from-date("2010-10-30", date("2012-10-21"))
+let $itv13 := interval-from-date(date("2010-10-30"), "2012-10-21")
+let $itv14 := interval-from-date("2010-10-30", "2012-10-21")
+let $itv15 := interval-from-date(null, "2012-10-21")
+let $itv16 := interval-from-date("2010-10-30", null)
+let $itv21 := interval-from-time(time("03:04:05.678-11:00"), time("232425267+0200"))
+let $itv22 := interval-from-time("03:04:05.678-11:00", time("232425267+0200"))
+let $itv23 := interval-from-time(time("03:04:05.678-11:00"), "232425267+0200")
+let $itv24 := interval-from-time("03:04:05.678-11:00", "232425267+0200")
+let $itv25 := interval-from-time(null, time("232425267+0200"))
+let $itv26 := interval-from-time(time("03:04:05.678-11:00"), null)
+let $itv31 := interval-from-datetime(datetime("-1987-11-19T02:43:57.938+08:00"), datetime("19991112T124935948-0700"))
+let $itv32 := interval-from-datetime("-1987-11-19T02:43:57.938+08:00", datetime("19991112T124935948-0700"))
+let $itv33 := interval-from-datetime(datetime("-1987-11-19T02:43:57.938+08:00"), "19991112T124935948-0700")
+let $itv34 := interval-from-datetime("-1987-11-19T02:43:57.938+08:00", "19991112T124935948-0700")
+let $itv35 := interval-from-datetime(null, datetime("19991112T124935948-0700"))
+let $itv36 := interval-from-datetime(datetime("-1987-11-19T02:43:57.938+08:00"), null)
+let $itv41 := interval-start-from-date(date("0001-12-27"), duration("P3Y394DT48H398.483S"))
+let $itv42 := interval-start-from-date("0001-12-27", duration("P3Y394DT48H398.483S"))
+let $itv43 := interval-start-from-date(date("0001-12-27"), "P3Y394DT48H398.483S")
+let $itv44 := interval-start-from-date("0001-12-27", "P3Y394DT48H398.483S")
+let $itv45 := interval-start-from-date(null, duration("P3Y394DT48H398.483S"))
+let $itv46 := interval-start-from-date(date("0001-12-27"), null)
+let $itv51 := interval-start-from-time(time("20:03:20.948"), duration("P60DT48M389.938S"))
+let $itv52 := interval-start-from-time("20:03:20.948", duration("P60DT48M389.938S"))
+let $itv53 := interval-start-from-time(time("20:03:20.948"), "P60DT48M389.938S")
+let $itv54 := interval-start-from-time("20:03:20.948", "P60DT48M389.938S")
+let $itv55 := interval-start-from-time(null, duration("P60DT48M389.938S"))
+let $itv56 := interval-start-from-time(time("20:03:20.948"), null)
+let $itv61 := interval-start-from-datetime(datetime("-2043-11-19T15:32:39.293"), duration("P439Y3M20DT20H39M58.949S"))
+let $itv62 := interval-start-from-datetime("-2043-11-19T15:32:39.293", duration("P439Y3M20DT20H39M58.949S"))
+let $itv63 := interval-start-from-datetime(datetime("-2043-11-19T15:32:39.293"), "P439Y3M20DT20H39M58.949S")
+let $itv64 := interval-start-from-datetime("-2043-11-19T15:32:39.293", "P439Y3M20DT20H39M58.949S")
+let $itv65 := interval-start-from-datetime(null, duration("P439Y3M20DT20H39M58.949S"))
+let $itv66 := interval-start-from-datetime(datetime("-2043-11-19T15:32:39.293"), null)
 
-return {"interval1": $itv1, "interval2": $itv2, "interval3": $itv3, "interval4": $itv4, "interval5": $itv5, "interval6": $itv6}
+return {"interval11": $itv11, "interval12": $itv12, "interval13": $itv13, "interval14": $itv14, "interval15": $itv15, "interval16": $itv16, "interval21": $itv21, "interval22": $itv22, "interval23": $itv23, "interval24": $itv24, "interval25": $itv25, "interval26": $itv26, "interval31": $itv31, "interval32": $itv32, "interval33": $itv33, "interval34": $itv34, "interval35": $itv35, "interval36": $itv36, "interval41": $itv41, "interval42": $itv42, "interval43": $itv43, "interval44": $itv44, "interval45": $itv45, "interval46": $itv46, "interval51": $itv51, "interval52": $itv52, "interval53": $itv53, "interval54": $itv54, "interval55": $itv55, "interval56": $itv56, "interval61": $itv61, "interval62": $itv62, "interval63": $itv63, "interval64": $itv64, "interval65": $itv65, "interval66": $itv66}
 
diff --git a/asterix-app/src/test/resources/runtimets/results/constructor/interval/interval.1.adm b/asterix-app/src/test/resources/runtimets/results/constructor/interval/interval.1.adm
index 893c3ff..c99ade9 100644
--- a/asterix-app/src/test/resources/runtimets/results/constructor/interval/interval.1.adm
+++ b/asterix-app/src/test/resources/runtimets/results/constructor/interval/interval.1.adm
@@ -1 +1 @@
-{ "interval1": interval-date("2010-10-30, 2012-10-21"), "interval2": interval-time("14:04:05.678Z, 21:24:25.267Z"), "interval3": interval-datetime("-1987-11-18T18:43:57.938Z, 1999-11-12T19:49:35.948Z"), "interval4": interval-date("0001-12-27, 0006-01-27"), "interval5": interval-time("20:03:20.948Z, 20:57:50.886Z"), "interval6": interval-datetime("-2043-11-19T15:32:39.293Z, -1603-03-12T12:12:38.242Z") }
\ No newline at end of file
+{ "interval11": interval-date("2010-10-30, 2012-10-21"), "interval12": interval-date("2010-10-30, 2012-10-21"), "interval13": interval-date("2010-10-30, 2012-10-21"), "interval14": interval-date("2010-10-30, 2012-10-21"), "interval15": null, "interval16": null, "interval21": interval-time("14:04:05.678Z, 21:24:25.267Z"), "interval22": interval-time("14:04:05.678Z, 21:24:25.267Z"), "interval23": interval-time("14:04:05.678Z, 21:24:25.267Z"), "interval24": interval-time("14:04:05.678Z, 21:24:25.267Z"), "interval25": null, "interval26": null, "interval31": interval-datetime("-1987-11-18T18:43:57.938Z, 1999-11-12T19:49:35.948Z"), "interval32": interval-datetime("-1987-11-18T18:43:57.938Z, 1999-11-12T19:49:35.948Z"), "interval33": interval-datetime("-1987-11-18T18:43:57.938Z, 1999-11-12T19:49:35.948Z"), "interval34": interval-datetime("-1987-11-18T18:43:57.938Z, 1999-11-12T19:49:35.948Z"), "interval35": null, "interval36": null, "interval41": interval-date("0001-12-27, 0006-01-27"), "interval42": interval-date("0001-12-27, 0006-01-27"), "interval43": interval-date("0001-12-27, 0006-01-27"), "interval44": interval-date("0001-12-27, 0006-01-27"), "interval45": null, "interval46": null, "interval51": interval-time("20:03:20.948Z, 20:57:50.886Z"), "interval52": interval-time("20:03:20.948Z, 20:57:50.886Z"), "interval53": interval-time("20:03:20.948Z, 20:57:50.886Z"), "interval54": interval-time("20:03:20.948Z, 20:57:50.886Z"), "interval55": null, "interval56": null, "interval61": interval-datetime("-2043-11-19T15:32:39.293Z, -1603-03-12T12:12:38.242Z"), "interval62": interval-datetime("-2043-11-19T15:32:39.293Z, -1603-03-12T12:12:38.242Z"), "interval63": interval-datetime("-2043-11-19T15:32:39.293Z, -1603-03-12T12:12:38.242Z"), "interval64": interval-datetime("-2043-11-19T15:32:39.293Z, -1603-03-12T12:12:38.242Z"), "interval65": null, "interval66": null }
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
index 0414874..8daf9a6 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateConstructorDescriptor.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
@@ -28,6 +29,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -45,6 +47,7 @@
             "interval-from-date", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -90,34 +93,45 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                return;
+                            }
 
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_DATE_TYPE_TAG) {
+                                intervalStart = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
-
-                                // start date
-                                long intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
+                                intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
                                         stringLength) / GregorianCalendarSystem.CHRONON_OF_DAY;
-
-                                // end date
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
-                                        + (argOut1.getByteArray()[2] & 0xff << 0);
-
-                                long intervalEnd = ADateParserFactory.parseDatePart(argOut1.getByteArray(), 3,
-                                        stringLength) / GregorianCalendarSystem.CHRONON_OF_DAY;
-
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATE.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
-                                throw new AlgebricksException("Wrong format for interval constructor from dates.");
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATE for the first argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
                             }
 
+                            if (argOut1.getByteArray()[0] == SER_DATE_TYPE_TAG) {
+                                intervalEnd = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                                        + (argOut1.getByteArray()[2] & 0xff << 0);
+                                intervalEnd = ADateParserFactory.parseDatePart(argOut1.getByteArray(), 3, stringLength)
+                                        / GregorianCalendarSystem.CHRONON_OF_DAY;
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATE for the second argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
+                            }
+                            
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATE.serialize());
+                            intervalSerde.serialize(aInterval, out);
+
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
                         } catch (Exception e2) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
index 6b3e2b6..78d2e4a 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromDateTimeConstructorDescriptor.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
@@ -28,6 +29,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -45,6 +47,7 @@
             "interval-from-datetime", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -67,7 +70,7 @@
                     private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
                     private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
                     private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
-                    private String errorMessage = "This can not be an instance of interval (from Date)";
+                    private String errorMessage = "This can not be an instance of interval (from DateTime)";
                     //TODO: Where to move and fix these?
                     private AMutableInterval aInterval = new AMutableInterval(0L, 0L, (byte) 0);
                     @SuppressWarnings("unchecked")
@@ -90,12 +93,17 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                return;
+                            }
+
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_DATETIME_TYPE_TAG) {
+                                intervalStart = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 // start datetime
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
-
                                 // get offset for time part: +1 if it is negative (-)
                                 short timeOffset = (short) ((argOut0.getByteArray()[3] == '-') ? 1 : 0);
                                 timeOffset += 8;
@@ -105,18 +113,23 @@
                                         throw new AlgebricksException(errorMessage + ": missing T");
                                     }
                                 }
-
-                                long intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
-                                        timeOffset);
+                                intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3, timeOffset);
                                 intervalStart += ATimeParserFactory.parseTimePart(argOut0.getByteArray(),
                                         3 + timeOffset + 1, stringLength - timeOffset - 1);
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATETIME for the first argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+                            }
 
-                                // end datetime
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                            if (argOut1.getByteArray()[0] == SER_DATETIME_TYPE_TAG) {
+                                intervalEnd = ADateTimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                // start datetime
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
-
                                 // get offset for time part: +1 if it is negative (-)
-                                timeOffset = (short) ((argOut1.getByteArray()[3] == '-') ? 1 : 0);
+                                short timeOffset = (short) ((argOut1.getByteArray()[3] == '-') ? 1 : 0);
                                 timeOffset += 8;
                                 if (argOut1.getByteArray()[3 + timeOffset] != 'T') {
                                     timeOffset += 2;
@@ -124,22 +137,22 @@
                                         throw new AlgebricksException(errorMessage + ": missing T");
                                     }
                                 }
-
-                                long intervalEnd = ADateParserFactory.parseDatePart(argOut1.getByteArray(), 3,
-                                        timeOffset);
+                                intervalEnd = ADateParserFactory.parseDatePart(argOut1.getByteArray(), 3, timeOffset);
                                 intervalEnd += ATimeParserFactory.parseTimePart(argOut1.getByteArray(),
                                         3 + timeOffset + 1, stringLength - timeOffset - 1);
-
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATETIME.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
-                                throw new AlgebricksException("Wrong format for interval constructor from dates.");
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATETIME for the second argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
                             }
+                            
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATETIME.serialize());
+                            intervalSerde.serialize(aInterval, out);
 
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
index 042a33b..8816160 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalFromTimeConstructorDescriptor.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableInterval;
@@ -28,6 +29,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -45,6 +47,7 @@
             "interval-from-time", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_TIME_TYPE_TAG = ATypeTag.TIME.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -90,39 +93,57 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                return;
+                            }
+
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_TIME_TYPE_TAG) {
+                                intervalStart = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 // start date
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
-                                long intervalStart = ATimeParserFactory.parseTimePart(argOut0.getByteArray(), 3,
+                                intervalStart = ATimeParserFactory.parseTimePart(argOut0.getByteArray(), 3,
                                         stringLength);
-                                if (intervalStart < 0) {
-                                    intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
-                                }
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/TIME for the first argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+                            }
 
-                                // end date
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                            if (intervalStart < 0) {
+                                intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
+                            }
+                            
+                            if (argOut1.getByteArray()[0] == SER_TIME_TYPE_TAG) {
+                                intervalEnd = ATimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                // start date
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
-                                long intervalEnd = ATimeParserFactory.parseTimePart(argOut1.getByteArray(), 3,
-                                        stringLength);
-                                if (intervalEnd < 0) {
-                                    intervalEnd += GregorianCalendarSystem.CHRONON_OF_DAY;
-                                }
+                                intervalEnd = ATimeParserFactory.parseTimePart(argOut1.getByteArray(), 3, stringLength);
 
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.TIME.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
-                                throw new AlgebricksException("Wrong format for interval constructor from dates.");
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/TIME for the second argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
                             }
 
+                            if (intervalEnd < 0) {
+                                intervalEnd += GregorianCalendarSystem.CHRONON_OF_DAY;
+                            }
+                            
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+                            
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.TIME.serialize());
+                            intervalSerde.serialize(aInterval, out);
+
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
                         } catch (Exception e2) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
index d5a0db9..7ea8e90 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
@@ -18,6 +18,8 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableDuration;
@@ -31,6 +33,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -48,6 +51,8 @@
             "interval-start-from-date", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
+    private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -94,40 +99,56 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
+                                return;
+                            }
 
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_DATE_TYPE_TAG) {
+                                intervalStart = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+                                        * GregorianCalendarSystem.CHRONON_OF_DAY;
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 // start date
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
-
-                                long intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
+                                intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
                                         stringLength);
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATE for the first argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+                            }
 
+                            if (argOut1.getByteArray()[0] == SER_DURATION_TYPE_TAG) {
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
+                                        ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1),
+                                        ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 // duration
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 ADurationParserFactory
                                         .parseDuration(argOut1.getByteArray(), 3, stringLength, aDuration);
-
-                                long intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
                                         aDuration.getMonths(), aDuration.getMilliseconds());
-
-                                intervalStart = GregorianCalendarSystem.getChrononInDays(intervalStart);
-                                intervalEnd = GregorianCalendarSystem.getChrononInDays(intervalEnd);
-
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATE.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
-                                throw new AlgebricksException("Wrong format for interval constructor from dates.");
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DURATION for the second argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
                             }
 
+                            intervalStart = GregorianCalendarSystem.getChrononInDays(intervalStart);
+                            intervalEnd = GregorianCalendarSystem.getChrononInDays(intervalEnd);
+
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATE.serialize());
+                            intervalSerde.serialize(aInterval, out);
+
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
                         } catch (Exception e2) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
index d821fc3..f16dccb 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
@@ -18,6 +18,8 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableDuration;
@@ -31,6 +33,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -48,6 +51,8 @@
             "interval-start-from-datetime", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
+    private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -94,10 +99,14 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
-                                // start date
+                                return;
+                            }
 
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_DATETIME_TYPE_TAG) {
+                                intervalStart = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
@@ -113,32 +122,44 @@
                                     }
                                 }
 
-                                long intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3,
-                                        timeOffset);
+                                intervalStart = ADateParserFactory.parseDatePart(argOut0.getByteArray(), 3, timeOffset);
                                 intervalStart += ATimeParserFactory.parseTimePart(argOut0.getByteArray(),
                                         3 + timeOffset + 1, stringLength - timeOffset - 1);
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DATETIME for the first argument but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+                            }
+
+                            if (argOut1.getByteArray()[0] == SER_DURATION_TYPE_TAG) {
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
+                                        ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1),
+                                        ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
 
                                 // duration
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 ADurationParserFactory
                                         .parseDuration(argOut1.getByteArray(), 3, stringLength, aDuration);
 
-                                long intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
                                         aDuration.getMonths(), aDuration.getMilliseconds());
-
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATETIME.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
-                                throw new AlgebricksException("Wrong format for interval constructor from dates.");
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/DURATION for the second argument but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
                             }
 
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.DATETIME.serialize());
+                            intervalSerde.serialize(aInterval, out);
+
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
                         } catch (Exception e2) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
index 8135598..35bfe17 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
@@ -18,6 +18,8 @@
 import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AInterval;
 import edu.uci.ics.asterix.om.base.AMutableDuration;
@@ -31,6 +33,7 @@
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -48,6 +51,8 @@
             "interval-start-from-time", 2);
     private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
     private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_TIME_TYPE_TAG = ATypeTag.TIME.serialize();
+    private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
 
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
         public IFunctionDescriptor createFunctionDescriptor() {
@@ -94,51 +99,71 @@
                             if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
                                     || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
                                 nullSerde.serialize(ANull.NULL, out);
-                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG
-                                    && argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
-                                // start time
+                                return;
+                            }
 
+                            long intervalStart = 0, intervalEnd = 0;
+
+                            if (argOut0.getByteArray()[0] == SER_TIME_TYPE_TAG) {
+                                intervalStart = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+                            } else if (argOut0.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 int stringLength = (argOut0.getByteArray()[1] & 0xff << 8)
                                         + (argOut0.getByteArray()[2] & 0xff << 0);
 
-                                int intervalStart = ATimeParserFactory.parseTimePart(argOut0.getByteArray(), 3,
+                                intervalStart = ATimeParserFactory.parseTimePart(argOut0.getByteArray(), 3,
                                         stringLength);
+                            } else {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": expects NULL/STRING/TIME for the first argument, but got "
+                                        + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+                            }
 
-                                if (intervalStart < 0) {
-                                    intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
+                            if (intervalStart < 0) {
+                                intervalStart += GregorianCalendarSystem.CHRONON_OF_DAY;
+                            }
+
+                            if (argOut1.getByteArray()[0] == SER_DURATION_TYPE_TAG) {
+
+                                if (ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1) != 0) {
+                                    throw new AlgebricksException(FID.getName()
+                                            + ": cannot add a year-month duration to a time value.");
                                 }
 
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart, 0,
+                                        ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+
+                            } else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
                                 // duration
 
-                                stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
+                                int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
                                         + (argOut1.getByteArray()[2] & 0xff << 0);
 
                                 ADurationParserFactory
                                         .parseDuration(argOut1.getByteArray(), 3, stringLength, aDuration);
 
                                 if (aDuration.getMonths() != 0) {
-                                    throw new AlgebricksException("Cannot add a year-month duration to a time value.");
+                                    throw new AlgebricksException(FID.getName()
+                                            + ": cannot add a year-month duration to a time value.");
                                 }
 
-                                int intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
+                                intervalEnd = DurationArithmeticOperations.addDuration(intervalStart, 0,
                                         aDuration.getMilliseconds());
-
-                                if (intervalEnd > GregorianCalendarSystem.CHRONON_OF_DAY) {
-
-                                    intervalEnd = intervalEnd - (int) (GregorianCalendarSystem.CHRONON_OF_DAY);
-                                }
-
-                                if (intervalEnd < intervalStart) {
-                                    throw new AlgebricksException(
-                                            "Interval end must not be less than the interval start.");
-                                }
-
-                                aInterval.setValue(intervalStart, intervalEnd, ATypeTag.TIME.serialize());
-                                intervalSerde.serialize(aInterval, out);
                             } else {
                                 throw new AlgebricksException("Wrong format for interval constructor from dates.");
                             }
 
+                            if (intervalEnd > GregorianCalendarSystem.CHRONON_OF_DAY) {
+                                intervalEnd = intervalEnd % (int) (GregorianCalendarSystem.CHRONON_OF_DAY);
+                            }
+
+                            if (intervalEnd < intervalStart) {
+                                throw new AlgebricksException(FID.getName()
+                                        + ": interval end must not be less than the interval start.");
+                            }
+
+                            aInterval.setValue(intervalStart, intervalEnd, ATypeTag.TIME.serialize());
+                            intervalSerde.serialize(aInterval, out);
+
                         } catch (IOException e1) {
                             throw new AlgebricksException(errorMessage);
                         } catch (Exception e2) {