integrate the record printer visitor

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_printerfix@917 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
index 7dc35fe..c8a8f26 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
@@ -58,22 +58,17 @@
  * recursive way. It enables: 1. bag-based fields in a record, 2. bidirectional
  * cast of a open field and a matched closed field, and 3. put in null fields
  * when necessary. It should be fired before the constant folding rule.
- * 
  * This rule is not responsible for type casting between primitive types.
- * 
  * Here is an example: A record { "hobby": {{"music", "coding"}}, "id": "001",
  * "name": "Person Three"} which confirms to closed type ( id: string, name:
  * string, hobby: {{string}}? ) can be cast to an open type (id: string ), or
  * vice versa.
- * 
  * Implementation wise: first, we match the record's type and its target dataset
  * type to see if it is "cast-able"; second, if the types are cast-able, we
  * embed the required type into the original producer expression. If the types
  * are not cast-able, we throw a compile time exception.
- * 
  * Then, at runtime (not in this rule), the corresponding record/list
  * constructors know what to do by checking the required output type.
- * 
  * TODO: right now record/list constructor of the cast result is not done in the
  * ConstantFoldingRule and has to go to the runtime, because the
  * ConstantFoldingRule uses ARecordSerializerDeserializer which seems to have
@@ -175,10 +170,19 @@
     private void rewriteFuncExpr(ScalarFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
             IVariableTypeEnvironment env) throws AlgebricksException {
         if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+            if (reqType.equals(BuiltinType.ANY)) {
+                reqType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+            }
             rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
         } else if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR) {
+            if (reqType.equals(BuiltinType.ANY)) {
+                reqType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
+            }
             rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
-        } else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
+        } else if (inputType.getTypeTag().equals(ATypeTag.RECORD)) {
+            if (reqType.equals(BuiltinType.ANY)) {
+                reqType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
+            }
             rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
         }
     }
@@ -225,8 +229,6 @@
         List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
 
         IAType itemType = requiredListType.getItemType();
-        if (itemType == null || itemType.getTypeTag().equals(ATypeTag.ANY))
-            return;
         IAType inputItemType = inputListType.getItemType();
         for (int j = 0; j < args.size(); j++) {
             ILogicalExpression arg = args.get(j).getValue();
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ARecordPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ARecordPrinterFactory.java
index fafe320..cc9e0bd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ARecordPrinterFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/ARecordPrinterFactory.java
@@ -2,16 +2,14 @@
 
 import java.io.PrintStream;
 
-import edu.uci.ics.asterix.common.exceptions.AsterixException;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
-import edu.uci.ics.asterix.formats.nontagged.AqlPrinterFactoryProvider;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.AUnionType;
-import edu.uci.ics.asterix.om.types.EnumDeserializer;
-import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.pointables.PointableAllocator;
+import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.runtime.pointables.printer.APrintVisitor;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
 import edu.uci.ics.hyracks.algebricks.data.IPrinter;
 import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
 
@@ -28,137 +26,29 @@
     @Override
     public IPrinter createPrinter() {
 
-        return new IPrinter() {
+        PointableAllocator allocator = new PointableAllocator();
+        final ARecordType inputType = recType == null ? (ARecordType) DefaultOpenFieldType
+                .getDefaultOpenFieldType(ATypeTag.RECORD) : recType;
+        final IVisitablePointable recAccessor = allocator.allocateRecordValue(inputType);
+        final APrintVisitor printVisitor = new APrintVisitor();
+        final Pair<PrintStream, ATypeTag> arg = new Pair<PrintStream, ATypeTag>(null, null);
 
-            private IPrinter[] fieldPrinters;
-            private IAType[] fieldTypes;
-            private int[] fieldOffsets;
-            private int numberOfSchemaFields, numberOfOpenFields, openPartOffset, fieldOffset, offsetArrayOffset,
-                    fieldValueLength, nullBitMapOffset, recordOffset;
-            private boolean isExpanded, hasNullableFields;
-            private ATypeTag tag;
+        return new IPrinter() {
 
             @Override
             public void init() throws AlgebricksException {
-
-                numberOfSchemaFields = 0;
-                if (recType != null) {
-                    numberOfSchemaFields = recType.getFieldNames().length;
-                    fieldPrinters = new IPrinter[numberOfSchemaFields];
-                    fieldTypes = new IAType[numberOfSchemaFields];
-                    fieldOffsets = new int[numberOfSchemaFields];
-                    for (int i = 0; i < numberOfSchemaFields; i++) {
-                        fieldTypes[i] = recType.getFieldTypes()[i];
-                        if (fieldTypes[i].getTypeTag() == ATypeTag.UNION
-                                && NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[i]))
-                            fieldPrinters[i] = (AqlPrinterFactoryProvider.INSTANCE
-                                    .getPrinterFactory(((AUnionType) fieldTypes[i]).getUnionList().get(
-                                            NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST))).createPrinter();
-                        else
-                            fieldPrinters[i] = (AqlPrinterFactoryProvider.INSTANCE.getPrinterFactory(fieldTypes[i]))
-                                    .createPrinter();
-                        fieldPrinters[i].init();
-                    }
-                }
+                arg.second = inputType.getTypeTag();
             }
 
             @Override
             public void print(byte[] b, int start, int l, PrintStream ps) throws AlgebricksException {
-                ps.print("{ ");
-                isExpanded = false;
-                openPartOffset = 0;
-                int s = start;
-                recordOffset = s;
-                if (recType == null) {
-                    openPartOffset = s + AInt32SerializerDeserializer.getInt(b, s + 6);
-                    s += 8;
-                    isExpanded = true;
-                } else {
-                    if (recType.isOpen()) {
-                        isExpanded = b[s + 5] == 1 ? true : false;
-                        if (isExpanded) {
-                            openPartOffset = s + AInt32SerializerDeserializer.getInt(b, s + 6);
-                            s += 10;
-                        } else
-                            s += 6;
-                    } else
-                        s += 5;
-                }
                 try {
-                    if (numberOfSchemaFields > 0) {
-                        s += 4;
-                        nullBitMapOffset = 0;
-                        hasNullableFields = NonTaggedFormatUtil.hasNullableField(recType);
-                        if (hasNullableFields) {
-                            nullBitMapOffset = s;
-                            offsetArrayOffset = s
-                                    + (this.numberOfSchemaFields % 8 == 0 ? numberOfSchemaFields / 8
-                                            : numberOfSchemaFields / 8 + 1);
-                        } else {
-                            offsetArrayOffset = s;
-                        }
-                        for (int i = 0; i < numberOfSchemaFields; i++) {
-                            fieldOffsets[i] = AInt32SerializerDeserializer.getInt(b, offsetArrayOffset) + recordOffset;
-                            offsetArrayOffset += 4;
-                        }
-                        for (int fieldNumber = 0; fieldNumber < numberOfSchemaFields; fieldNumber++) {
-                            if (fieldNumber != 0) {
-                                ps.print(", ");
-                            }
-                            ps.print("\"");
-                            ps.print(recType.getFieldNames()[fieldNumber]);
-                            ps.print("\": ");
-                            if (hasNullableFields) {
-                                byte b1 = b[nullBitMapOffset + fieldNumber / 8];
-                                int p = 1 << (7 - (fieldNumber % 8));
-                                if ((b1 & p) == 0) {
-                                    ps.print("null");
-                                    continue;
-                                }
-                            }
-                            if (fieldTypes[fieldNumber].getTypeTag() == ATypeTag.UNION) {
-                                if (NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[fieldNumber])) {
-                                    tag = ((AUnionType) fieldTypes[fieldNumber]).getUnionList()
-                                            .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
-                                    fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b,
-                                            fieldOffsets[fieldNumber], tag, false);
-                                    fieldPrinters[fieldNumber].print(b, fieldOffsets[fieldNumber] - 1,
-                                            fieldValueLength, ps);
-                                }
-                            } else {
-                                tag = fieldTypes[fieldNumber].getTypeTag();
-                                fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b,
-                                        fieldOffsets[fieldNumber], tag, false);
-                                fieldPrinters[fieldNumber]
-                                        .print(b, fieldOffsets[fieldNumber] - 1, fieldValueLength, ps);
-                            }
-                        }
-                        if (isExpanded)
-                            ps.print(", ");
-                    }
-                    if (isExpanded) {
-                        numberOfOpenFields = AInt32SerializerDeserializer.getInt(b, openPartOffset);
-                        fieldOffset = openPartOffset + 4 + (8 * numberOfOpenFields);
-                        for (int i = 0; i < numberOfOpenFields; i++) {
-                            // we print the field name
-                            fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, ATypeTag.STRING,
-                                    false);
-                            AStringPrinter.INSTANCE.print(b, fieldOffset - 1, fieldValueLength, ps);
-                            fieldOffset += fieldValueLength;
-                            ps.print(": ");
-                            // now we print the value
-                            tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[fieldOffset]);
-                            fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, tag, true) + 1;
-                            AObjectPrinter.INSTANCE.print(b, fieldOffset, fieldValueLength, ps);
-                            fieldOffset += fieldValueLength;
-                            if (i + 1 < numberOfOpenFields)
-                                ps.print(", ");
-                        }
-                    }
-                } catch (AsterixException e) {
-                    throw new AlgebricksException(e);
+                    recAccessor.set(b, start, l);
+                    arg.first = ps;
+                    recAccessor.accept(printVisitor, arg);
+                } catch (Exception ioe) {
+                    throw new AlgebricksException(ioe);
                 }
-                ps.print(" }");
             }
         };
     }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
index 6f85694..01874f0 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
@@ -21,6 +21,7 @@
 
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AbstractCollectionType;
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
@@ -35,7 +36,6 @@
  * This class interprets the binary data representation of a list, one can
  * call getItems and getItemTags to get pointable objects for items and item
  * type tags.
- * 
  */
 public class AListPointable extends AbstractVisitablePointable {
 
@@ -59,6 +59,7 @@
     private IAType itemType;
     private ATypeTag itemTag;
     private boolean typedItemList = false;
+    private boolean ordered = false;
 
     /**
      * private constructor, to prevent constructing it arbitrarily
@@ -66,6 +67,9 @@
      * @param inputType
      */
     private AListPointable(AbstractCollectionType inputType) {
+        if (inputType instanceof AOrderedListType) {
+            ordered = true;
+        }
         if (inputType != null && inputType.getItemType() != null) {
             itemType = inputType.getItemType();
             if (itemType.getTypeTag() == ATypeTag.ANY) {
@@ -136,7 +140,7 @@
                     itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
                     itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
                     IVisitablePointable tag = allocator.allocateEmpty();
-                    IVisitablePointable item = allocator.allocateFieldValue(itemType);
+                    IVisitablePointable item = allocator.allocateFieldValue(itemTag);
 
                     // set item type tag
                     int start = dataBos.size();
@@ -168,4 +172,8 @@
     public List<IVisitablePointable> getItemTags() {
         return itemTags;
     }
+
+    public boolean ordered() {
+        return ordered;
+    }
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AbstractVisitablePointable.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AbstractVisitablePointable.java
index 8cfe661..5aebabd 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AbstractVisitablePointable.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/AbstractVisitablePointable.java
@@ -21,13 +21,12 @@
 /**
  * This class implements several "routine" methods in IVisitablePointable
  * interface, so that subclasses do not need to repeat the same code.
- * 
  */
 public abstract class AbstractVisitablePointable implements IVisitablePointable {
 
     private byte[] data;
-    private int start;
-    private int len;
+    private int start = -1;
+    private int len = -1;
 
     @Override
     public byte[] getByteArray() {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ACastVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ACastVisitor.java
index 822e37c..f41f06b 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ACastVisitor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ACastVisitor.java
@@ -20,11 +20,13 @@
 
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AbstractCollectionType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.runtime.pointables.AFlatValuePointable;
 import edu.uci.ics.asterix.runtime.pointables.AListPointable;
 import edu.uci.ics.asterix.runtime.pointables.ARecordPointable;
+import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
 import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
 import edu.uci.ics.asterix.runtime.pointables.visitor.IVisitablePointableVisitor;
 import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
@@ -33,11 +35,9 @@
  * This class is a IVisitablePointableVisitor implementation which recursively
  * visit a given record, list or flat value of a given type, and cast it to a
  * specified type. For example:
- * 
  * A record { "hobby": {{"music", "coding"}}, "id": "001", "name":
  * "Person Three"} which confirms to closed type ( id: string, name: string,
  * hobby: {{string}}? ) can be casted to a open type (id: string )
- * 
  * Since the open/closed part of a record has a completely different underlying
  * memory/storage layout, the visitor will change the layout as specified at
  * runtime.
@@ -56,6 +56,9 @@
             laccessorToCaster.put(accessor, caster);
         }
         try {
+            if (arg.second.getTypeTag().equals(ATypeTag.ANY)) {
+                arg.second = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+            }
             caster.castList(accessor, arg.first, (AbstractCollectionType) arg.second, this);
         } catch (Exception e) {
             throw new AsterixException(e);
@@ -72,6 +75,9 @@
             raccessorToCaster.put(accessor, caster);
         }
         try {
+            if (arg.second.getTypeTag().equals(ATypeTag.ANY)) {
+                arg.second = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
+            }
             caster.castRecord(accessor, arg.first, (ARecordType) arg.second, this);
         } catch (Exception e) {
             throw new AsterixException(e);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
index e10fb72..d407cf1 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
@@ -64,9 +64,11 @@
             AbstractCollectionType reqType, ACastVisitor visitor) throws IOException, AsterixException {
         if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
             unOrderedListBuilder.reset((AUnorderedListType) reqType);
+            reqItemType = reqType.getItemType();
         }
         if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
             orderedListBuilder.reset((AOrderedListType) reqType);
+            reqItemType = reqType.getItemType();
         }
         dataBos.reset();
 
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/AListPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/AListPrinter.java
index 31ac74a..e20b1059a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/AListPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/AListPrinter.java
@@ -31,14 +31,21 @@
  * ACastVisitor.
  */
 class AListPrinter {
-    private static String LEFT_PAREN = "{";
-    private static String RIGHT_PAREN = "}";
-    private static String COMMA = ",";
+    private static String LEFT_PAREN = "{{ ";
+    private static String RIGHT_PAREN = " }}";
+    private static String LEFT_PAREN_ORDERED = "[ ";
+    private static String RIGHT_PAREN_ORDERED = " ]";
+    private static String COMMA = ", ";
 
     private final Pair<PrintStream, ATypeTag> itemVisitorArg = new Pair<PrintStream, ATypeTag>(null, null);
+    private String leftParen = LEFT_PAREN;
+    private String rightParen = RIGHT_PAREN;
 
-    public AListPrinter() {
-
+    public AListPrinter(boolean ordered) {
+        if (ordered) {
+            leftParen = LEFT_PAREN_ORDERED;
+            rightParen = RIGHT_PAREN_ORDERED;
+        }
     }
 
     public void printList(AListPointable listAccessor, PrintStream ps, APrintVisitor visitor) throws IOException,
@@ -46,31 +53,33 @@
         List<IVisitablePointable> itemTags = listAccessor.getItemTags();
         List<IVisitablePointable> items = listAccessor.getItems();
         itemVisitorArg.first = ps;
-        
+
         //print the beginning part
-        ps.print(LEFT_PAREN);
-        
+        ps.print(leftParen);
+
         // print record 0 to n-2
         for (int i = 0; i < items.size() - 1; i++) {
             IVisitablePointable itemTypeTag = itemTags.get(i);
             IVisitablePointable item = items.get(i);
             ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
                     .getStartOffset()]);
-            itemVisitorArg.second = typeTag;
+            itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
             item.accept(visitor, itemVisitorArg);
             //print the comma
             ps.print(COMMA);
         }
-        
+
         // print record n-1
-        IVisitablePointable itemTypeTag = itemTags.get(itemTags.size()-1);
-        IVisitablePointable item = items.get(items.size()-1);
-        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
-                .getStartOffset()]);
-        itemVisitorArg.second = typeTag;
-        item.accept(visitor, itemVisitorArg);
+        if (items.size() > 0) {
+            IVisitablePointable itemTypeTag = itemTags.get(itemTags.size() - 1);
+            IVisitablePointable item = items.get(items.size() - 1);
+            ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
+                    .getStartOffset()]);
+            itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
+            item.accept(visitor, itemVisitorArg);
+        }
 
         //print the end part
-        ps.print(RIGHT_PAREN);
+        ps.print(rightParen);
     }
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/APrintVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/APrintVisitor.java
index cff38b4..b674055 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/APrintVisitor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/APrintVisitor.java
@@ -36,6 +36,7 @@
 import edu.uci.ics.asterix.dataflow.data.nontagged.printers.APoint3DPrinter;
 import edu.uci.ics.asterix.dataflow.data.nontagged.printers.APointPrinter;
 import edu.uci.ics.asterix.dataflow.data.nontagged.printers.APolygonPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ARectanglePrinter;
 import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AStringPrinter;
 import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ATimePrinter;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -67,7 +68,7 @@
     public Void visit(AListPointable accessor, Pair<PrintStream, ATypeTag> arg) throws AsterixException {
         AListPrinter printer = laccessorToPrinter.get(accessor);
         if (printer == null) {
-            printer = new AListPrinter();
+            printer = new AListPrinter(accessor.ordered());
             laccessorToPrinter.put(accessor, printer);
         }
         try {
@@ -170,6 +171,10 @@
                     ACirclePrinter.INSTANCE.print(b, s, l, ps);
                     break;
                 }
+                case RECTANGLE: {
+                    ARectanglePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
                 case STRING: {
                     AStringPrinter.INSTANCE.print(b, s, l, ps);
                     break;
@@ -183,5 +188,4 @@
             throw new IllegalStateException(e);
         }
     }
-
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/ARecordPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/ARecordPrinter.java
index 8162066..b0b3dfa 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/ARecordPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/runtime/pointables/printer/ARecordPrinter.java
@@ -31,11 +31,12 @@
  * ACastVisitor.
  */
 class ARecordPrinter {
-    private static String LEFT_PAREN = "{";
-    private static String RIGHT_PAREN = "}";
-    private static String COMMA = ",";
-    private static String COLON = ":";
+    private static String LEFT_PAREN = "{ ";
+    private static String RIGHT_PAREN = " }";
+    private static String COMMA = ", ";
+    private static String COLON = ": ";
 
+    private final Pair<PrintStream, ATypeTag> nameVisitorArg = new Pair<PrintStream, ATypeTag>(null, ATypeTag.STRING);
     private final Pair<PrintStream, ATypeTag> itemVisitorArg = new Pair<PrintStream, ATypeTag>(null, null);
 
     public ARecordPrinter() {
@@ -47,9 +48,11 @@
         List<IVisitablePointable> fieldNames = recordAccessor.getFieldNames();
         List<IVisitablePointable> fieldTags = recordAccessor.getFieldTypeTags();
         List<IVisitablePointable> fieldValues = recordAccessor.getFieldValues();
+
+        nameVisitorArg.first = ps;
         itemVisitorArg.first = ps;
 
-        //print the beginning part
+        // print the beginning part
         ps.print(LEFT_PAREN);
 
         // print record 0 to n-2
@@ -58,32 +61,34 @@
             IVisitablePointable item = fieldValues.get(i);
             ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
                     .getStartOffset()]);
-            itemVisitorArg.second = typeTag;
+            itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
 
-            //print field name
-            ps.print(fieldNames.get(i));
+            // print field name
+            fieldNames.get(i).accept(visitor, nameVisitorArg);
             ps.print(COLON);
-            //print field value
+            // print field value
             item.accept(visitor, itemVisitorArg);
 
-            //print the comma
+            // print the comma
             ps.print(COMMA);
         }
 
         // print record n-1
-        IVisitablePointable itemTypeTag = fieldTags.get(fieldTags.size() - 1);
-        IVisitablePointable item = fieldValues.get(fieldValues.size() - 1);
-        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
-                .getStartOffset()]);
-        itemVisitorArg.second = typeTag;
+        if (fieldValues.size() > 0) {
+            IVisitablePointable itemTypeTag = fieldTags.get(fieldTags.size() - 1);
+            IVisitablePointable item = fieldValues.get(fieldValues.size() - 1);
+            ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
+                    .getStartOffset()]);
+            itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
 
-        //print field name
-        ps.print(fieldNames.get(fieldNames.size() - 1));
-        ps.print(COLON);
-        //print field value
-        item.accept(visitor, itemVisitorArg);
+            // print field name
+            fieldNames.get(fieldNames.size() - 1).accept(visitor, nameVisitorArg);
+            ps.print(COLON);
+            // print field value
+            item.accept(visitor, itemVisitorArg);
+        }
 
-        //print the end part
+        // print the end part
         ps.print(RIGHT_PAREN);
     }
 }