Added comparison feature for ADate and ATime

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_temporal_functionality@620 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/src/test/resources/runtimets/queries/comparison/date_order.aql b/asterix-app/src/test/resources/runtimets/queries/comparison/date_order.aql
new file mode 100644
index 0000000..d38d386
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/comparison/date_order.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+
+create dataverse test;
+
+write output to nc1:"rttest/comparison_date_order.adm";
+
+let $d1 := date("2049-04-23")
+let $d2 := date("2012-02-29")
+let $d3 := date("2021-03-01")
+let $d4 := date("1362-02-28")
+let $d5 := date("1600-02-29")
+let $d6 := date("-0500-03-21")
+
+for $d in [$d1, $d2, $d3, $d4, $d5, $d6]
+order by $d
+return $d
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/comparison/time_order.aql b/asterix-app/src/test/resources/runtimets/queries/comparison/time_order.aql
new file mode 100644
index 0000000..ba0d211
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/comparison/time_order.aql
@@ -0,0 +1,16 @@
+drop dataverse test if exists;
+
+create dataverse test;
+
+write output to nc1:"rttest/comparison_time_order.adm";
+
+let $t1 := time("13:00:00.382-10:00")
+let $t2 := time("23:59:59.999Z")
+let $t3 := time("22:00:00+03:00")
+let $t4 := time("00:00:00.00Z")
+let $t5 := time("00:00:00.00-02:00")
+let $t6 := time("00:00:00.47+04:00")
+
+for $t in [$t1, $t2, $t3, $t4, $t5, $t6]
+order by $t
+return $t
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/comparison/date_order.adm b/asterix-app/src/test/resources/runtimets/results/comparison/date_order.adm
new file mode 100644
index 0000000..3fd4c19
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/comparison/date_order.adm
@@ -0,0 +1,6 @@
+date("-0500-03-21")
+date("1362-02-28")
+date("1600-02-29")
+date("2012-02-29")
+date("2021-03-01")
+date("2049-04-23")
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/comparison/time_order.adm b/asterix-app/src/test/resources/runtimets/results/comparison/time_order.adm
new file mode 100644
index 0000000..c937bdd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/comparison/time_order.adm
@@ -0,0 +1,6 @@
+time("00:00:00.000Z")
+time("02:00:00.000Z")
+time("19:00:00.000Z")
+time("20:00:00.470Z")
+time("23:00:00.382Z")
+time("23:59:59.999Z")
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java
new file mode 100644
index 0000000..464a03c
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ADateOrTimeAscBinaryComparatorFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.dataflow.data.nontagged.comparators;
+
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+
+public class ADateOrTimeAscBinaryComparatorFactory implements IBinaryComparatorFactory {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final ADateOrTimeAscBinaryComparatorFactory INSTANCE = new ADateOrTimeAscBinaryComparatorFactory();
+
+    private ADateOrTimeAscBinaryComparatorFactory() {
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory#createBinaryComparator()
+     */
+    @Override
+    public IBinaryComparator createBinaryComparator() {
+        return new IBinaryComparator() {
+
+            @Override
+            public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+                int chrononTime1 = getInt(b1, s1);
+                int chrononTime2 = getInt(b2, s2);
+
+                if (chrononTime1 > chrononTime2) {
+                    return 1;
+                } else if (chrononTime1 < chrononTime2) {
+                    return -1;
+                } else {
+                    return 0;
+                }
+            }
+
+            private int getInt(byte[] bytes, int start) {
+                return ((bytes[start] & 0xff) << 24) + ((bytes[start + 1] & 0xff) << 16)
+                        + ((bytes[start + 2] & 0xff) << 8) + ((bytes[start + 3] & 0xff) << 0);
+            }
+        };
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
index 881590d..0e486e7 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
@@ -24,15 +24,21 @@
     public IBinaryComparator createBinaryComparator() {
         return new IBinaryComparator() {
             final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-            final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY).createBinaryComparator();
+            final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY)
+                    .createBinaryComparator();
             final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();
-            final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY).createBinaryComparator();
-            final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY).createBinaryComparator();
-            final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY).createBinaryComparator();
+            final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY)
+                    .createBinaryComparator();
             final IBinaryComparator ascRectangleComp = RectangleBinaryComparatorFactory.INSTANCE
                     .createBinaryComparator();
             final IBinaryComparator ascDateTimeComp = ADateTimeAscBinaryComparatorFactory.INSTANCE
                     .createBinaryComparator();
+            final IBinaryComparator ascDateOrTimeComp = ADateOrTimeAscBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
 
             @Override
             public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
@@ -73,6 +79,10 @@
                     case DATETIME: {
                         return ascDateTimeComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                     }
+                    case TIME:
+                    case DATE: {
+                        return ascDateOrTimeComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
+                    }
                     default: {
                         throw new NotImplementedException("Comparison for type " + tag + " is not implemented");
                     }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
index 149a1d2..7b8d709 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -258,6 +258,7 @@
 
         switch (startField) {
             case YEAR:
+            default:
                 sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
                 if (untilField == Fields.YEAR) {
                     return;
@@ -328,6 +329,7 @@
 
         switch (startField) {
             case YEAR:
+            default:
                 sbder.append(String.format(year < 0 ? "%05d" : "%04d", year));
                 if (untilField == Fields.YEAR) {
                     return;
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java
index 18fc2d7..2b4ea3a 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/comparisons/AbstractComparisonEvaluator.java
@@ -2,6 +2,7 @@
 
 import java.io.DataOutput;
 
+import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateOrTimeAscBinaryComparatorFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateTimeAscBinaryComparatorFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
@@ -50,6 +51,8 @@
             .createBinaryComparator();
     protected IBinaryComparator dateTimeBinaryComp = ADateTimeAscBinaryComparatorFactory.INSTANCE
             .createBinaryComparator();
+    protected IBinaryComparator dateOrTimeBinaryComp = ADateOrTimeAscBinaryComparatorFactory.INSTANCE
+            .createBinaryComparator();
 
     public AbstractComparisonEvaluator(DataOutput out, ICopyEvaluatorFactory evalLeftFactory,
             ICopyEvaluatorFactory evalRightFactory) throws AlgebricksException {
@@ -119,6 +122,10 @@
             case DATETIME: {
                 return compareDateTimeWithArg(typeTag2);
             }
+            case DATE:
+            case TIME: {
+                return compareDateOrTimeWithArg(typeTag2);
+            }
             default: {
                 throw new AlgebricksException("Comparison is undefined between types " + typeTag1 + " and " + typeTag2
                         + " .");
@@ -126,6 +133,22 @@
         }
     }
 
+    private ComparisonResult compareDateOrTimeWithArg(ATypeTag typeTag2) throws AlgebricksException {
+        if (typeTag2 == ATypeTag.NULL) {
+            return ComparisonResult.GREATER_THAN;
+        } else if (typeTag2 == ATypeTag.DATETIME) {
+            int result = dateOrTimeBinaryComp.compare(outLeft.getByteArray(), 1, outLeft.getLength() - 1,
+                    outRight.getByteArray(), 1, outRight.getLength() - 1);
+            if (result == 0)
+                return ComparisonResult.EQUAL;
+            else if (result < 0)
+                return ComparisonResult.LESS_THAN;
+            else
+                return ComparisonResult.GREATER_THAN;
+        }
+        throw new AlgebricksException("Comparison is undefined between types ADateTime and " + typeTag2 + " .");
+    }
+
     private ComparisonResult compareDateTimeWithArg(ATypeTag typeTag2) throws AlgebricksException {
         if (typeTag2 == ATypeTag.NULL) {
             return ComparisonResult.GREATER_THAN;
@@ -153,8 +176,8 @@
 
     private ComparisonResult compareStringWithArg(ATypeTag typeTag2) throws AlgebricksException {
         if (typeTag2 == ATypeTag.STRING) {
-            int result = strBinaryComp.compare(outLeft.getByteArray(), 1, outLeft.getLength() - 1, outRight.getByteArray(), 1,
-                    outRight.getLength() - 1);
+            int result = strBinaryComp.compare(outLeft.getByteArray(), 1, outLeft.getLength() - 1,
+                    outRight.getByteArray(), 1, outRight.getLength() - 1);
             if (result == 0)
                 return ComparisonResult.EQUAL;
             else if (result < 0)
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
index 48c06b0..c13c4ae 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
@@ -24,6 +24,7 @@
 import edu.uci.ics.asterix.om.base.ATime;
 import edu.uci.ics.asterix.om.base.temporal.ByteArrayCharSequenceAccessor;
 import edu.uci.ics.asterix.om.base.temporal.ADateAndTimeParser;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -85,6 +86,10 @@
                                 charAccessor.reset(serString, 3, 0);
                                 int chrononTimeInMs = ADateAndTimeParser.parseTimePart(charAccessor);
 
+                                if (chrononTimeInMs < 0) {
+                                    chrononTimeInMs += GregorianCalendarSystem.CHRONON_OF_DAY;
+                                }
+
                                 aTime.setValue(chrononTimeInMs);
                                 timeSerde.serialize(aTime, out);