Fixed issue 159. Added regression test.

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization@598 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/length.aql b/asterix-app/src/test/resources/runtimets/queries/string/length_01.aql
similarity index 81%
rename from asterix-app/src/test/resources/runtimets/queries/string/length.aql
rename to asterix-app/src/test/resources/runtimets/queries/string/length_01.aql
index d78d986..8186f6b 100644
--- a/asterix-app/src/test/resources/runtimets/queries/string/length.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/string/length_01.aql
@@ -2,7 +2,7 @@
 create dataverse test;
 use dataverse test;
 
-write output to nc1:"rttest/string_length.adm";
+write output to nc1:"rttest/string_length_01.adm";
 
 let $c1 := string-length("hellow")
 let $c2 := string-length("")
diff --git a/asterix-app/src/test/resources/runtimets/queries/string/length_02.aql b/asterix-app/src/test/resources/runtimets/queries/string/length_02.aql
new file mode 100644
index 0000000..3cc33e7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/string/length_02.aql
@@ -0,0 +1,8 @@
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+write output to nc1:"rttest/string_length_02.adm";
+
+for $x in ["ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "ninety"]
+return string-length($x)
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/string/length.adm b/asterix-app/src/test/resources/runtimets/results/string/length_01.adm
similarity index 100%
rename from asterix-app/src/test/resources/runtimets/results/string/length.adm
rename to asterix-app/src/test/resources/runtimets/results/string/length_01.adm
diff --git a/asterix-app/src/test/resources/runtimets/results/string/length_02.adm b/asterix-app/src/test/resources/runtimets/results/string/length_02.adm
new file mode 100644
index 0000000..930236d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/string/length_02.adm
@@ -0,0 +1,8 @@
+3
+6
+6
+5
+5
+5
+7
+6
diff --git a/asterix-app/src/test/resources/runtimets/results/writers/serialized_01.adm b/asterix-app/src/test/resources/runtimets/results/writers/serialized_01.adm
index f2aee15..c503a33 100644
--- a/asterix-app/src/test/resources/runtimets/results/writers/serialized_01.adm
+++ b/asterix-app/src/test/resources/runtimets/results/writers/serialized_01.adm
Binary files differ
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
index ede7b99..93167cf 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
@@ -2,6 +2,7 @@
 
 import java.io.Serializable;
 
+import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateTimeAscBinaryComparatorFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectDescBinaryComparatorFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.BooleanBinaryComparatorFactory;
@@ -55,7 +56,7 @@
     public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending) {
         if (type == null) {
             return anyBinaryComparatorFactory(ascending);
-        }
+        }        
         IAType aqlType = (IAType) type;
         switch (aqlType.getTypeTag()) {
             case ANY:
@@ -100,6 +101,9 @@
             case RECTANGLE: {
                 return addOffset(RectangleBinaryComparatorFactory.INSTANCE, ascending);
             }
+            case DATETIME: {
+            	return addOffset(ADateTimeAscBinaryComparatorFactory.INSTANCE, ascending);
+            }
             default: {
                 throw new NotImplementedException("No binary comparator factory implemented for type "
                         + aqlType.getTypeTag() + " .");
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedCollectionMemberResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedCollectionMemberResultType.java
index 7caf99b..2a39d83 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedCollectionMemberResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedCollectionMemberResultType.java
@@ -1,8 +1,5 @@
 package edu.uci.ics.asterix.om.typecomputer.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AUnionType;
@@ -28,18 +25,13 @@
             IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
         AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
         IAType type = (IAType) env.getType(f.getArguments().get(0).getValue());
-        if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
+        if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type)) {
             type = ((AUnionType) type).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
-        if (type.getTypeTag() == ATypeTag.ANY)
-            return BuiltinType.ANY;
-        else {
-            if (((AbstractCollectionType) type).getItemType().getTypeTag() == ATypeTag.NULL)
-                return BuiltinType.ANULL;
-            List<IAType> unionList = new ArrayList<IAType>();
-            unionList.add(BuiltinType.ANULL);
-            unionList.add(((AbstractCollectionType) type).getItemType());
-            return new AUnionType(unionList, "CollectionMemberResult");
         }
+        if (type.getTypeTag() == ATypeTag.ANY) {
+            return BuiltinType.ANY;
+        }
+        return ((AbstractCollectionType) type).getItemType();
     }
 
 }
\ No newline at end of file
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
index 837b357..d94647b 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/aggregates/std/GlobalAvgAggregateDescriptor.java
@@ -123,12 +123,19 @@
                             throw new AlgebricksException("Global-Avg is not defined for values of type "
                                     + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serBytes[0]));
                         }
-                        int offset1 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 0, 1, false);
+                                               
+                        // The record length helps us determine whether the input record fields are nullable.
+                        int recordLength = ARecordSerializerDeserializer.getRecordLength(serBytes, 1);
+                        int nullBitmapSize = 1;
+                        if (recordLength == 29) {
+                            nullBitmapSize = 0;
+                        }
+                        int offset1 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 0, nullBitmapSize, false);
                         if (offset1 == 0) // the sum is null
                             metNull = true;
                         else
                             globalSum += ADoubleSerializerDeserializer.getDouble(serBytes, offset1);
-                        int offset2 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 1, 1, false);
+                        int offset2 = ARecordSerializerDeserializer.getFieldOffsetById(serBytes, 1, nullBitmapSize, false);
                         if (offset2 != 0) // the count is not null
                             globalCount += AInt32SerializerDeserializer.getInt(serBytes, offset2);