Issue 548: Initial implementation of CSV output method.

Can be selected via the HTTP interface by setting the Accept: header to
text/csv.

Displays strings, numerics, booleans, and a couple duration types. Detects
situations that cannot be respresented as CSV (list values, nested records)
and throws an exception.

Introduces "outputRecordType" set option to define a fixed RecordType that
all results will be coerced to, to ensure consistent CSV output.

Added test support for CSV output, with one test case for now.

Change-Id: Ib53da6b3c69e38095bdc684b0e8cd53b9f4b1543
Reviewed-on: http://fulliautomatix.ics.uci.edu:8443/165
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <westmann@gmail.com>
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
index 1314405..97f26f8 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
@@ -53,7 +53,7 @@
  * cast of a open field and a matched closed field, and 3. put in null fields
  * when necessary.
  * Here is an example: A record { "hobby": {{"music", "coding"}}, "id": "001",
- * "name": "Person Three"} which confirms to closed type ( id: string, name:
+ * "name": "Person Three"} which conforms to closed type ( id: string, name:
  * string, hobby: {{string}}? ) can be cast to an open type (id: string ), or
  * vice versa.
  * However, if the input record is a variable, then we don't know its exact
@@ -78,29 +78,80 @@
     @Override
     public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
-        /**
-         * pattern match: sink insert assign
-         * resulting plan: sink-insert-project-assign
-         */
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
-        if (op1.getOperatorTag() != LogicalOperatorTag.SINK)
-            return false;
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
-        if (op2.getOperatorTag() != LogicalOperatorTag.INSERT_DELETE)
-            return false;
-        InsertDeleteOperator insertDeleteOp = (InsertDeleteOperator) op2;
-        if (insertDeleteOp.getOperation() == InsertDeleteOperator.Kind.DELETE)
-            return false;
+        // Depending on the operator type, we need to extract the following pieces of information.
+        AbstractLogicalOperator op;
+        ARecordType requiredRecordType;
+        LogicalVariable recordVar;
 
-        InsertDeleteOperator insertDeleteOperator = (InsertDeleteOperator) op2;
-        AqlDataSource dataSource = (AqlDataSource) insertDeleteOperator.getDataSource();
-        IAType[] schemaTypes = (IAType[]) dataSource.getSchemaTypes();
-        ARecordType requiredRecordType = (ARecordType) schemaTypes[schemaTypes.length - 1];
-        ILogicalExpression expr = insertDeleteOperator.getPayloadExpression().getValue();
-        List<LogicalVariable> payloadVars = new ArrayList<LogicalVariable>();
-        expr.getUsedVariables(payloadVars);
-        LogicalVariable recordVar = payloadVars.get(0);
-        IVariableTypeEnvironment env = insertDeleteOperator.computeOutputTypeEnvironment(context);
+        // We identify INSERT and DISTRIBUTE_RESULT operators.
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
+        switch (op1.getOperatorTag()) {
+            case SINK: {
+                /**
+                 * pattern match: sink insert assign
+                 * resulting plan: sink-insert-project-assign
+                 */
+
+                AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
+                if (op2.getOperatorTag() == LogicalOperatorTag.INSERT_DELETE) {
+                    InsertDeleteOperator insertDeleteOp = (InsertDeleteOperator) op2;
+                    if (insertDeleteOp.getOperation() == InsertDeleteOperator.Kind.DELETE)
+                        return false;
+
+                    // Remember this is the operator we need to modify
+                    op = insertDeleteOp;
+
+                    // Derive the required ARecordType based on the schema of the AqlDataSource
+                    InsertDeleteOperator insertDeleteOperator = (InsertDeleteOperator) op2;
+                    AqlDataSource dataSource = (AqlDataSource) insertDeleteOperator.getDataSource();
+                    IAType[] schemaTypes = (IAType[]) dataSource.getSchemaTypes();
+                    requiredRecordType = (ARecordType) schemaTypes[schemaTypes.length - 1];
+
+                    // Derive the Variable which we will potentially wrap with cast/null functions
+                    ILogicalExpression expr = insertDeleteOperator.getPayloadExpression().getValue();
+                    List<LogicalVariable> payloadVars = new ArrayList<LogicalVariable>();
+                    expr.getUsedVariables(payloadVars);
+                    recordVar = payloadVars.get(0);
+                }
+                else {
+                    return false;
+                }
+
+                break;
+            }
+            case DISTRIBUTE_RESULT: {
+                // First, see if there was an outputRecordType specified
+                requiredRecordType = (ARecordType) op1.getAnnotations().get("outputRecordType");
+                if (requiredRecordType == null) {
+                    return false;
+                }
+
+                // Remember this is the operator we need to modify
+                op = op1;
+
+                // The Variable we want is the (hopefully singular, hopefully record-typed) live variable
+                // of the singular input operator of the DISTRIBUTE_RESULT
+                if (op.getInputs().size() > 1) {
+                    // Hopefully not possible?
+                    throw new AlgebricksException("outputRecordType defined for expression with multiple input operators");
+                }
+                AbstractLogicalOperator input = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
+                List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
+                VariableUtilities.getLiveVariables(input, liveVars);
+                if (liveVars.size() > 1) {
+                    throw new AlgebricksException("Expression with multiple fields cannot be cast to outputRecordType!");
+                }
+                recordVar = liveVars.get(0);
+
+                break;
+            }
+            default: {
+                return false;
+            }
+        }
+
+        // Derive the statically-computed type of the record
+        IVariableTypeEnvironment env = op.computeOutputTypeEnvironment(context);
         IAType inputRecordType = (IAType) env.getVarType(recordVar);
 
         /** the input record type can be an union type -- for the case when it comes from a subplan or left-outer join */
@@ -116,11 +167,11 @@
         boolean cast = !compatible(requiredRecordType, inputRecordType);
 
         if (checkNull) {
-            recordVar = addWrapperFunction(requiredRecordType, recordVar, insertDeleteOp, context,
+            recordVar = addWrapperFunction(requiredRecordType, recordVar, op, context,
                     AsterixBuiltinFunctions.NOT_NULL);
         }
         if (cast) {
-            addWrapperFunction(requiredRecordType, recordVar, insertDeleteOp, context,
+            addWrapperFunction(requiredRecordType, recordVar, op, context,
                     AsterixBuiltinFunctions.CAST_RECORD);
         }
         return cast || checkNull;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
index aab2664..be27c2e2 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
@@ -110,6 +110,7 @@
 import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.functions.AsterixFunctionInfo;
+import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.om.util.AsterixAppContextInfo;
@@ -290,6 +291,13 @@
             ResultSetDataSink sink = new ResultSetDataSink(rssId, null);
             topOp = new DistributeResultOperator(writeExprList, sink);
             topOp.getInputs().add(new MutableObject<ILogicalOperator>(project));
+
+            // Retrieve the Output RecordType (if any) and store it on
+            // the DistributeResultOperator
+            IAType outputRecordType = metadataProvider.findOutputRecordType();
+            if (outputRecordType != null) {
+                topOp.getAnnotations().put("outputRecordType", outputRecordType);
+            }
         } else {
             /** add the collection-to-sequence right before the final project, because dataset only accept non-collection records */
             LogicalVariable seqVar = context.newVar();
@@ -1567,4 +1575,4 @@
         // TODO Auto-generated method stub
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
index 0376e11..1ee9a3e 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
@@ -161,7 +161,8 @@
     public enum OutputFormat {
         ADM,
         HTML,
-        JSON
+        JSON,
+        CSV
     }
 
     public static Pair<Query, Integer> reWriteQuery(List<FunctionDecl> declaredFunctions,
@@ -362,6 +363,9 @@
             case JSON:
                 builder.setPrinterProvider(format.getJSONPrinterFactoryProvider());
                 break;
+            case CSV:
+                builder.setPrinterProvider(format.getCSVPrinterFactoryProvider());
+                break;
             default:
                 builder.setPrinterProvider(format.getPrinterFactoryProvider());
                 break;
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/QueryResultAPIServlet.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/QueryResultAPIServlet.java
index e60ebe1..5ccbfc8 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/QueryResultAPIServlet.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/QueryResultAPIServlet.java
@@ -92,6 +92,9 @@
             } else if (accept.contains("text/html")) {
                 format = APIFramework.OutputFormat.HTML;
                 response.setContentType("text/html");
+            } else if (accept.contains("text/csv")) {
+                format = APIFramework.OutputFormat.CSV;
+                response.setContentType("text/csv; header=present");
             } else {
                 // JSON output is the default; most generally useful for a
                 // programmatic HTTP API
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
index 6d66921..e783741 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/http/servlet/RESTAPIServlet.java
@@ -85,6 +85,9 @@
         } else if (accept.contains("text/html")) {
             format = OutputFormat.HTML;
             response.setContentType("text/html");
+        } else if (accept.contains("text/csv")) {
+            format = OutputFormat.CSV;
+            response.setContentType("text/csv; header=present");
         } else {
             // JSON output is the default; most generally useful for a
             // programmatic HTTP API
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
index 5bac705..25dc341 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/AqlTranslator.java
@@ -496,19 +496,19 @@
                             dataverseName, mdTxnCtx);
                     String filterField = ((InternalDetailsDecl) dd.getDatasetDetailsDecl()).getFilterField();
                     if (compactionPolicy == null) {
-    					if (filterField != null) {
-    						// If the dataset has a filter and the user didn't specify a merge policy, then we will pick the
-    						// correlated-prefix as the default merge policy.
-    						compactionPolicy = GlobalConfig.DEFAULT_FILTERED_DATASET_COMPACTION_POLICY_NAME;
-    						compactionPolicyProperties = GlobalConfig.DEFAULT_COMPACTION_POLICY_PROPERTIES;
-    					} else {
-    						compactionPolicy = GlobalConfig.DEFAULT_COMPACTION_POLICY_NAME;
-    						compactionPolicyProperties = GlobalConfig.DEFAULT_COMPACTION_POLICY_PROPERTIES;
-    					}
-    				} else {
-    					validateCompactionPolicy(compactionPolicy,
-    							compactionPolicyProperties, mdTxnCtx, false);
-    				}
+                        if (filterField != null) {
+                            // If the dataset has a filter and the user didn't specify a merge policy, then we will pick the
+                            // correlated-prefix as the default merge policy.
+                            compactionPolicy = GlobalConfig.DEFAULT_FILTERED_DATASET_COMPACTION_POLICY_NAME;
+                            compactionPolicyProperties = GlobalConfig.DEFAULT_COMPACTION_POLICY_PROPERTIES;
+                        } else {
+                            compactionPolicy = GlobalConfig.DEFAULT_COMPACTION_POLICY_NAME;
+                            compactionPolicyProperties = GlobalConfig.DEFAULT_COMPACTION_POLICY_PROPERTIES;
+                        }
+                    } else {
+                        validateCompactionPolicy(compactionPolicy,
+                                                 compactionPolicyProperties, mdTxnCtx, false);
+                    }
                     if (filterField != null) {
                         aRecordType.validateFilterField(filterField);
                     }
@@ -2058,6 +2058,9 @@
                         // In this case (the normal case), we don't use the
                         // "response" JSONObject - just stream the results
                         // to the "out" PrintWriter
+                        if (pdf == OutputFormat.CSV) {
+                            ResultUtils.displayCSVHeader(metadataProvider.findOutputRecordType(), out);
+                        }
                         ResultUtils.displayResults(resultReader, out, pdf);
 
                         hcc.waitForCompletion(jobId);
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
index 88d1e6d..1900d50 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
@@ -34,6 +34,7 @@
 
 import edu.uci.ics.asterix.api.common.APIFramework;
 import edu.uci.ics.asterix.api.http.servlet.APIServlet;
+import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
 import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -60,21 +61,41 @@
         return s;
     }
 
+    public static void displayCSVHeader(ARecordType recordType, PrintWriter out) {
+        String[] fieldNames = recordType.getFieldNames();
+        boolean notfirst = false;
+        for (String name : fieldNames) {
+            if (notfirst) {
+                out.print(',');
+            }
+            notfirst = true;
+            out.print('"');
+            out.print(name.replace("\"", "\"\""));
+            out.print('"');
+        }
+        out.print("\r\n");
+    }
+
     public static void displayResults(ResultReader resultReader, PrintWriter out, APIFramework.OutputFormat pdf)
             throws HyracksDataException {
         IFrameTupleAccessor fta = resultReader.getFrameTupleAccessor();
 
         ByteBuffer buffer = ByteBuffer.allocate(ResultReader.FRAME_SIZE);
         buffer.clear();
-
         int bytesRead = resultReader.read(buffer);
         ByteBufferInputStream bbis = new ByteBufferInputStream();
+
+        // Whether we need to separate top-level ADM instances with commas
         boolean need_commas = true;
+        // Whether this is the first instance being output
         boolean notfirst = false;
+
         switch (pdf) {
             case HTML:
                 out.println("<h4>Results:</h4>");
                 out.println("<pre>");
+                // Fall through
+            case CSV:
                 need_commas = false;
                 break;
             case JSON:
@@ -85,6 +106,7 @@
                 out.print("[ ");
                 break;
         }
+
         if (bytesRead > 0) {
             do {
                 try {
@@ -96,13 +118,21 @@
                         int length = fta.getTupleEndOffset(tIndex) - start;
                         bbis.setByteBuffer(buffer, start);
                         byte[] recordBytes = new byte[length];
-                        bbis.read(recordBytes, 0, length);
-                        result = new String(recordBytes, 0, length, UTF_8);
+                        int numread = bbis.read(recordBytes, 0, length);
+                        if (pdf == APIFramework.OutputFormat.CSV) {
+                            if ( (numread > 0) && (recordBytes[numread-1] == '\n') ) {
+                                numread--;
+                            }
+                        }
+                        result = new String(recordBytes, 0, numread, UTF_8);
                         if (need_commas && notfirst) {
                             out.print(", ");
                         }
                         notfirst = true;
                         out.print(result);
+                        if (pdf == APIFramework.OutputFormat.CSV) {
+                            out.print("\r\n");
+                        }
                     }
                     buffer.clear();
                 } finally {
@@ -125,6 +155,9 @@
             case ADM:
                 out.println(" ]");
                 break;
+            case CSV:
+                // Nothing to do
+                break;
         }
 
     }
diff --git a/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.1.ddl.aql
new file mode 100644
index 0000000..fafef26
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.1.ddl.aql
@@ -0,0 +1,10 @@
+drop dataverse test if exists;
+create dataverse test;
+
+use dataverse test;
+
+create type "foo" as {
+  "id": int32,
+  "name": string,
+  "money": float
+};
diff --git a/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.2.query.aql b/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.2.query.aql
new file mode 100644
index 0000000..6ef20f2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/csv/basic-types/basic-types.2.query.aql
@@ -0,0 +1,3 @@
+use dataverse "test";
+set outputRecordType "foo";
+{ "money": float("18.25"), "id": 12345, "name": "Chris"}
diff --git a/asterix-app/src/test/resources/runtimets/results/csv/basic-types/basic-types.1.csv b/asterix-app/src/test/resources/runtimets/results/csv/basic-types/basic-types.1.csv
new file mode 100644
index 0000000..941639e
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/csv/basic-types/basic-types.1.csv
@@ -0,0 +1,2 @@
+"id","name","money"
+12345,Chris,18.25
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 6fdef2a..c3b097a 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -5523,6 +5523,13 @@
             </compilation-unit>
         </test-case>
     </test-group>
+    <test-group name="csv">
+        <test-case FilePath="csv">
+            <compilation-unit name="basic-types">
+                <output-dir compare="CSV">basic-types</output-dir>
+            </compilation-unit>
+        </test-case>
+    </test-group>
     <test-group name="binary">
         <test-case FilePath="binary">
             <compilation-unit name="parse">
diff --git a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index c70f603..11153fc 100644
--- a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -75,6 +75,7 @@
 
     private static void runScriptAndCompareWithResult(File scriptFile, PrintWriter print, File expectedFile,
             File actualFile) throws Exception {
+        System.err.println("Expected results file: " + expectedFile.toString());
         BufferedReader readerExpected = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFile),
                 "UTF-8"));
         BufferedReader readerActual = new BufferedReader(
@@ -211,12 +212,7 @@
         // Create a method instance.
         GetMethod method = new GetMethod(url);
         method.setQueryString(new NameValuePair[] { new NameValuePair("query", str) });
-
-        // For now, ADM means "default", which is what is returned when no
-        // explicit Accept: header is specified.
-        if (fmt == OutputFormat.JSON) {
-            method.setRequestHeader("Accept", "application/json");
-        }
+        method.setRequestHeader("Accept", fmt.mimeType());
 
         // Provide custom retry handler is necessary
         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/declared/AqlMetadataProvider.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/declared/AqlMetadataProvider.java
index e562be4..71d41fc 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/declared/AqlMetadataProvider.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/declared/AqlMetadataProvider.java
@@ -278,6 +278,26 @@
         return resultSerializerFactoryProvider;
     }
 
+    /**
+     * Retrieve the Output RecordType, as defined by "set outputRecordType".
+     */
+    public ARecordType findOutputRecordType() throws AlgebricksException {
+        String outputRecordType = getPropertyValue("outputRecordType");
+        if (outputRecordType == null) {
+            return null;
+        }
+        String dataverse = getDefaultDataverseName();
+        if (dataverse == null) {
+            throw new AlgebricksException("Cannot declare outputRecordType with no dataverse!");
+        }
+        IAType type = findType(dataverse, outputRecordType);
+        if (!(type instanceof ARecordType)) {
+            throw new AlgebricksException
+                ("Type " + outputRecordType + " is not a record type!");
+        }
+        return (ARecordType) type;
+    }
+
     @Override
     public AqlDataSource findDataSource(AqlSourceId id) throws AlgebricksException {
         AqlSourceId aqlId = (AqlSourceId) id;
@@ -2116,15 +2136,16 @@
         }
     }
 
-    public IAType findType(String dataverse, String typeName) {
+    public IAType findType(String dataverse, String typeName) throws AlgebricksException {
         Datatype type;
         try {
             type = MetadataManager.INSTANCE.getDatatype(mdTxnCtx, dataverse, typeName);
-        } catch (Exception e) {
-            throw new IllegalStateException();
+        } catch (MetadataException e) {
+            throw new AlgebricksException("Metadata exception while looking up type '" + typeName +
+                                          "' in dataverse '" + dataverse + "'", e);
         }
         if (type == null) {
-            throw new IllegalStateException();
+            throw new AlgebricksException("Type name '" + typeName + " unknown in dataverse '" + dataverse +"'");
         }
         return type.getDatatype();
     }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AStringPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AStringPrinter.java
index 105a22e..af8eab8 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AStringPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/AStringPrinter.java
@@ -32,9 +32,10 @@
     @Override
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
         try {
-            PrintTools.writeUTF8StringWithEscapes(b, s + 1, l - 1, ps);
+            // ADM uses same escape semantics as JSON for strings
+            PrintTools.writeUTF8StringAsJSON(b, s + 1, l - 1, ps);
         } catch (IOException e) {
             throw new AlgebricksException(e);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/PrintTools.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/PrintTools.java
index 92beb61..e4b8441 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/PrintTools.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/PrintTools.java
@@ -26,11 +26,29 @@
         UPPER_CASE,
     }
 
-    public static void writeUTF8StringWithEscapes(byte[] b, int s, int l, OutputStream os) throws IOException {
+
+    public static void writeUTF8StringAsCSV(byte[] b, int s, int l, OutputStream os) throws IOException {
         int stringLength = UTF8StringPointable.getUTFLength(b, s);
         int position = s + 2; // skip 2 bytes containing string size
         int maxPosition = position + stringLength;
-        os.write('\"');
+        os.write('"');
+        while (position < maxPosition) {
+            char c = UTF8StringPointable.charAt(b, position);
+            int sz = UTF8StringPointable.charSize(b, position);
+            if (c == '"') {
+                os.write('"');
+            }
+            os.write(c);
+            position += sz;
+        }
+        os.write('"');
+    }
+
+    public static void writeUTF8StringAsJSON(byte[] b, int s, int l, OutputStream os) throws IOException {
+        int stringLength = UTF8StringPointable.getUTFLength(b, s);
+        int position = s + 2; // skip 2 bytes containing string size
+        int maxPosition = position + stringLength;
+        os.write('"');
         while (position < maxPosition) {
             char c = UTF8StringPointable.charAt(b, position);
             int sz = UTF8StringPointable.charSize(b, position);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinter.java
new file mode 100644
index 0000000..7de4d09
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ABooleanPrinter implements IPrinter {
+
+    public static final ABooleanPrinter INSTANCE = new ABooleanPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        ps.print(ABooleanSerializerDeserializer.getBoolean(b, s + 1));
+    }
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinterFactory.java
new file mode 100644
index 0000000..8fa7bac
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ABooleanPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ABooleanPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ABooleanPrinterFactory INSTANCE = new ABooleanPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ABooleanPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinter.java
new file mode 100644
index 0000000..b5041cf
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ACirclePrinter implements IPrinter {
+
+    public static final ACirclePrinter INSTANCE = new ACirclePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Circle' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinterFactory.java
new file mode 100644
index 0000000..0d4e0b9
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ACirclePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ACirclePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ACirclePrinterFactory INSTANCE = new ACirclePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ACirclePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinter.java
new file mode 100644
index 0000000..37af669
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ADatePrinter implements IPrinter {
+
+    public static final ADatePrinter INSTANCE = new ADatePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        // QQQ should be supported - issue 833
+        throw new AlgebricksException("'Date' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java
new file mode 100644
index 0000000..daec8ea
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADatePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ADatePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ADatePrinterFactory INSTANCE = new ADatePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ADatePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinter.java
new file mode 100644
index 0000000..e90c586
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ADateTimePrinter implements IPrinter {
+
+    public static final ADateTimePrinter INSTANCE = new ADateTimePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        // QQQ should be supported - issue 833
+        throw new AlgebricksException("'DateTime' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java
new file mode 100644
index 0000000..49ea344
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADateTimePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ADateTimePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ADateTimePrinterFactory INSTANCE = new ADateTimePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ADateTimePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinter.java
new file mode 100644
index 0000000..31de9ab
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ADayTimeDurationPrinter implements IPrinter {
+
+    public static final ADayTimeDurationPrinter INSTANCE = new ADayTimeDurationPrinter();
+
+    @Override
+    public void init() throws AlgebricksException {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        long milliseconds = AInt64SerializerDeserializer.getLong(b, s + 1);
+        // QQQ acceptable output for CSV?
+        ps.print(milliseconds);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinterFactory.java
new file mode 100644
index 0000000..988b7f8
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADayTimeDurationPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ADayTimeDurationPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ADayTimeDurationPrinterFactory INSTANCE = new ADayTimeDurationPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ADayTimeDurationPrinter.INSTANCE;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinter.java
new file mode 100644
index 0000000..2b3b0ff
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ADoublePrinter implements IPrinter {
+
+    public static final ADoublePrinter INSTANCE = new ADoublePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        ps.print(ADoubleSerializerDeserializer.getDouble(b, s + 1));
+    }
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinterFactory.java
new file mode 100644
index 0000000..9187760
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADoublePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ADoublePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ADoublePrinterFactory INSTANCE = new ADoublePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ADoublePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinter.java
new file mode 100644
index 0000000..82767e3
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ADurationPrinter implements IPrinter {
+
+    public static final ADurationPrinter INSTANCE = new ADurationPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        // QQQ Should possibly be supported? - issue 833
+        throw new AlgebricksException("'Duration' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinterFactory.java
new file mode 100644
index 0000000..bd97a9d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ADurationPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ADurationPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ADurationPrinterFactory INSTANCE = new ADurationPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ADurationPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinter.java
new file mode 100644
index 0000000..8aceb72
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AFloatPrinter implements IPrinter {
+
+    public static final AFloatPrinter INSTANCE = new AFloatPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        ps.print(AFloatSerializerDeserializer.getFloat(b, s + 1));
+    }
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinterFactory.java
new file mode 100644
index 0000000..0ff9e07
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AFloatPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AFloatPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AFloatPrinterFactory INSTANCE = new AFloatPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AFloatPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16Printer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16Printer.java
new file mode 100644
index 0000000..c878e55
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16Printer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AInt16Printer implements IPrinter {
+    public static final AInt16Printer INSTANCE = new AInt16Printer();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        short i = AInt16SerializerDeserializer.getShort(b, s + 1);
+        ps.print(i);
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16PrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16PrinterFactory.java
new file mode 100644
index 0000000..77a9df4
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt16PrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AInt16PrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AInt16PrinterFactory INSTANCE = new AInt16PrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AInt16Printer.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32Printer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32Printer.java
new file mode 100644
index 0000000..4ed9df3
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32Printer.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AInt32Printer implements IPrinter {
+
+    public static final AInt32Printer INSTANCE = new AInt32Printer();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        int d = AInt32SerializerDeserializer.getInt(b, s + 1);
+        ps.print(d);
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32PrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32PrinterFactory.java
new file mode 100644
index 0000000..4ef2448
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt32PrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AInt32PrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AInt32PrinterFactory INSTANCE = new AInt32PrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AInt32Printer.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64Printer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64Printer.java
new file mode 100644
index 0000000..6a291cc
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64Printer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AInt64Printer implements IPrinter {
+    public static final AInt64Printer INSTANCE = new AInt64Printer();
+
+    @Override
+    public void init() {
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        long d = AInt64SerializerDeserializer.getLong(b, s + 1);
+        ps.print(d);
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64PrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64PrinterFactory.java
new file mode 100644
index 0000000..b66e3a3
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt64PrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AInt64PrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AInt64PrinterFactory INSTANCE = new AInt64PrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AInt64Printer.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8Printer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8Printer.java
new file mode 100644
index 0000000..3db8a97
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8Printer.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AInt8Printer implements IPrinter {
+
+    public static final AInt8Printer INSTANCE = new AInt8Printer();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        byte o = AInt8SerializerDeserializer.getByte(b, s + 1);
+        ps.print(o);
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8PrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8PrinterFactory.java
new file mode 100644
index 0000000..2e62364
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AInt8PrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AInt8PrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AInt8PrinterFactory INSTANCE = new AInt8PrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AInt8Printer.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinter.java
new file mode 100644
index 0000000..c1793c9
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AIntervalPrinter implements IPrinter {
+
+    public static final AIntervalPrinter INSTANCE = new AIntervalPrinter();
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#init()
+     */
+    @Override
+    public void init() throws AlgebricksException {
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#print(byte[], int, int, java.io.PrintStream)
+     */
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Interval' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinterFactory.java
new file mode 100644
index 0000000..7caa95a
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AIntervalPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AIntervalPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AIntervalPrinterFactory INSTANCE = new AIntervalPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AIntervalPrinter.INSTANCE;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinter.java
new file mode 100644
index 0000000..083dd31
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ALinePrinter implements IPrinter {
+
+    public static final ALinePrinter INSTANCE = new ALinePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Line' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinterFactory.java
new file mode 100644
index 0000000..f1a165d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ALinePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ALinePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ALinePrinterFactory INSTANCE = new ALinePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ALinePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinter.java
new file mode 100644
index 0000000..84a400e
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ANullPrinter implements IPrinter {
+
+    public static final ANullPrinter INSTANCE = new ANullPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        ps.print("null");
+    }
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinterFactory.java
new file mode 100644
index 0000000..e34a07b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ANullPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ANullPrinterFactory INSTANCE = new ANullPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ANullPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
new file mode 100644
index 0000000..1d8adc5
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlCSVPrinterFactoryProvider;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ANullableFieldPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+
+    private AUnionType unionType;
+
+    public ANullableFieldPrinterFactory(AUnionType unionType) {
+        this.unionType = unionType;
+    }
+
+    @Override
+    public IPrinter createPrinter() {
+        return new IPrinter() {
+            private IPrinter nullPrinter;
+            private IPrinter fieldPrinter;
+
+            @Override
+            public void init() throws AlgebricksException {
+                nullPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.ANULL))
+                        .createPrinter();
+                fieldPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getUnionList()
+                        .get(1))).createPrinter();
+            }
+
+            @Override
+            public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+                fieldPrinter.init();
+                if (b[s] == ATypeTag.NULL.serialize())
+                    nullPrinter.print(b, s, l, ps);
+                else
+                    fieldPrinter.print(b, s, l, ps);
+            }
+
+        };
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
new file mode 100644
index 0000000..2f971d8
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AObjectPrinter implements IPrinter {
+
+    public static final AObjectPrinter INSTANCE = new AObjectPrinter();
+
+    private IPrinter recordPrinter = new ARecordPrinterFactory(null).createPrinter();
+
+    @Override
+    public void init() throws AlgebricksException {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[s]);
+        switch (typeTag) {
+            case INT8: {
+                AInt8Printer.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case INT16: {
+                AInt16Printer.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case INT32: {
+                AInt32Printer.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case INT64: {
+                AInt64Printer.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case NULL: {
+                ANullPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case BOOLEAN: {
+                ABooleanPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case FLOAT: {
+                AFloatPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case DOUBLE: {
+                ADoublePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case DATE: {
+                ADatePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case TIME: {
+                ATimePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case DATETIME: {
+                ADateTimePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case DURATION: {
+                ADurationPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case YEARMONTHDURATION: {
+                AYearMonthDurationPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case DAYTIMEDURATION: {
+                ADayTimeDurationPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case POINT: {
+                APointPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case POINT3D: {
+                APoint3DPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case LINE: {
+                ALinePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case POLYGON: {
+                APolygonPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case CIRCLE: {
+                ACirclePrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case STRING: {
+                AStringPrinter.INSTANCE.print(b, s, l, ps);
+                break;
+            }
+            case RECORD: {
+                this.recordPrinter.init();
+                recordPrinter.print(b, s, l, ps);
+                break;
+            }
+            default: {
+                throw new NotImplementedException("No printer for type " + typeTag);
+            }
+        }
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java
new file mode 100644
index 0000000..1945bab
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AObjectPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AObjectPrinterFactory INSTANCE = new AObjectPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AObjectPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinter.java
new file mode 100644
index 0000000..37b4466
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class APoint3DPrinter implements IPrinter {
+
+    public static final APoint3DPrinter INSTANCE = new APoint3DPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Point3D' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinterFactory.java
new file mode 100644
index 0000000..a2ec8ee
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APoint3DPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class APoint3DPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final APoint3DPrinterFactory INSTANCE = new APoint3DPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return APoint3DPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinter.java
new file mode 100644
index 0000000..c236f0e
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class APointPrinter implements IPrinter {
+
+    public static final APointPrinter INSTANCE = new APointPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Point' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinterFactory.java
new file mode 100644
index 0000000..83f6ca3
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APointPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class APointPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final APointPrinterFactory INSTANCE = new APointPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return APointPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinter.java
new file mode 100644
index 0000000..0e05eff
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class APolygonPrinter implements IPrinter {
+
+    public static final APolygonPrinter INSTANCE = new APolygonPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Polygon' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinterFactory.java
new file mode 100644
index 0000000..3760756
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/APolygonPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class APolygonPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final APolygonPrinterFactory INSTANCE = new APolygonPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return APolygonPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java
new file mode 100644
index 0000000..533b4a7
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARecordPrinterFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.om.pointables.PointableAllocator;
+import edu.uci.ics.asterix.om.pointables.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.om.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.om.pointables.printer.csv.APrintVisitor;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+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;
+
+public class ARecordPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    private final ARecordType recType;
+
+    public ARecordPrinterFactory(ARecordType recType) {
+        this.recType = recType;
+    }
+
+    @Override
+    public IPrinter createPrinter() {
+
+        PointableAllocator allocator = new PointableAllocator();
+        final IAType inputType = recType == null ? 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);
+
+        return new IPrinter() {
+
+            @Override
+            public void init() throws AlgebricksException {
+                arg.second = inputType.getTypeTag();
+            }
+
+            @Override
+            public void print(byte[] b, int start, int l, PrintStream ps) throws AlgebricksException {
+                try {
+                    recAccessor.set(b, start, l);
+                    arg.first = ps;
+                    recAccessor.accept(printVisitor, arg);
+                } catch (Exception ioe) {
+                    throw new AlgebricksException(ioe);
+                }
+            }
+        };
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinter.java
new file mode 100644
index 0000000..59a7c5d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinter.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ARectanglePrinter implements IPrinter {
+
+    public static final ARectanglePrinter INSTANCE = new ARectanglePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        throw new AlgebricksException("'Rectangle' type unsupported for CSV output");
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinterFactory.java
new file mode 100644
index 0000000..c7de000
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ARectanglePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ARectanglePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ARectanglePrinterFactory INSTANCE = new ARectanglePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ARectanglePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinter.java
new file mode 100644
index 0000000..a5e033b
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.PrintTools;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AStringPrinter implements IPrinter {
+
+    public static final AStringPrinter INSTANCE = new AStringPrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        try {
+            PrintTools.writeUTF8StringAsCSV(b, s + 1, l - 1, ps);
+        } catch (IOException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinterFactory.java
new file mode 100644
index 0000000..9eabb8e
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AStringPrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AStringPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AStringPrinterFactory INSTANCE = new AStringPrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return AStringPrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinter.java
new file mode 100644
index 0000000..fe08497
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class ATimePrinter implements IPrinter {
+
+    public static final ATimePrinter INSTANCE = new ATimePrinter();
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        // QQQ probably should be supported - issue 833
+        throw new AlgebricksException("'Time' type unsupported for CSV output");
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java
new file mode 100644
index 0000000..999b78d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/ATimePrinterFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class ATimePrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final ATimePrinterFactory INSTANCE = new ATimePrinterFactory();
+
+    @Override
+    public IPrinter createPrinter() {
+        return ATimePrinter.INSTANCE;
+    }
+
+}
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AUnionPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AUnionPrinterFactory.java
new file mode 100644
index 0000000..d3de14e
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AUnionPrinterFactory.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+import java.util.List;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlCSVPrinterFactoryProvider;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AUnionPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+
+    private AUnionType unionType;
+
+    public AUnionPrinterFactory(AUnionType unionType) {
+        this.unionType = unionType;
+    }
+
+    @Override
+    public IPrinter createPrinter() {
+
+        return new IPrinter() {
+
+            private IPrinter[] printers;
+            private List<IAType> unionList;
+
+            @Override
+            public void init() throws AlgebricksException {
+                unionList = unionType.getUnionList();
+                printers = new IPrinter[unionType.getUnionList().size()];
+                for (int i = 0; i < printers.length; i++) {
+                    printers[i] = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getUnionList()
+                            .get(i))).createPrinter();
+                    printers[i].init();
+                }
+            }
+
+            @Override
+            public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+                ATypeTag tag = unionList.get(b[s + 1]).getTypeTag();
+                if (tag == ATypeTag.UNION)
+                    printers[b[s + 1]].print(b, s + 1, l, ps);
+                else {
+                    if (tag == ATypeTag.ANY)
+                        printers[b[s + 1]].print(b, s + 2, l, ps);
+                    else
+                        printers[b[s + 1]].print(b, s + 1, l, ps);
+                }
+            }
+        };
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinter.java
new file mode 100644
index 0000000..c0a7cff
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import java.io.PrintStream;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+
+public class AYearMonthDurationPrinter implements IPrinter {
+
+    public static final AYearMonthDurationPrinter INSTANCE = new AYearMonthDurationPrinter();
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#init()
+     */
+    @Override
+    public void init() throws AlgebricksException {
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.algebricks.data.IPrinter#print(byte[], int, int, java.io.PrintStream)
+     */
+    @Override
+    public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
+        int months = AInt32SerializerDeserializer.getInt(b, s + 1);
+        // QQQ reasonable CSV representation?
+        ps.print(months);
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinterFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinterFactory.java
new file mode 100644
index 0000000..4afb427
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/csv/AYearMonthDurationPrinterFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009-2013 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.printers.csv;
+
+import edu.uci.ics.hyracks.algebricks.data.IPrinter;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+
+public class AYearMonthDurationPrinterFactory implements IPrinterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AYearMonthDurationPrinterFactory INSTANCE = new AYearMonthDurationPrinterFactory();
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.hyracks.algebricks.data.IPrinterFactory#createPrinter()
+     */
+    @Override
+    public IPrinter createPrinter() {
+        return AYearMonthDurationPrinter.INSTANCE;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/json/AStringPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/json/AStringPrinter.java
index 2c84c82..43af3ad 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/json/AStringPrinter.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/printers/json/AStringPrinter.java
@@ -33,9 +33,9 @@
     @Override
     public void print(byte[] b, int s, int l, PrintStream ps) throws AlgebricksException {
         try {
-            PrintTools.writeUTF8StringWithEscapes(b, s + 1, l - 1, ps);
+            PrintTools.writeUTF8StringAsJSON(b, s + 1, l - 1, ps);
         } catch (IOException e) {
             throw new AlgebricksException(e);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
index f2af980..c30cf3a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/base/IDataFormat.java
@@ -54,10 +54,13 @@
 
     public IBinaryIntegerInspectorFactory getBinaryIntegerInspectorFactory();
 
+    // QQQ Refactor: Make this accept an APIFramework.OutputFormat parameter
     public IPrinterFactoryProvider getPrinterFactoryProvider();
 
     public IPrinterFactoryProvider getJSONPrinterFactoryProvider();
 
+    public IPrinterFactoryProvider getCSVPrinterFactoryProvider();
+
     public INullWriterFactory getNullWriterFactory();
 
     public Triple<ICopyEvaluatorFactory, ScalarFunctionCallExpression, IAType> partitioningEvaluatorFactory(
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
new file mode 100644
index 0000000..371aa5d
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2009-2013 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.formats.nontagged;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AUUIDPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ShortWithoutTypeInfoPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ABooleanPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ACirclePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADatePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADateTimePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADayTimeDurationPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADoublePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADurationPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AFloatPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt16PrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt32PrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt64PrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt8PrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ALinePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ANullPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ANullableFieldPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AObjectPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APoint3DPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APointPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APolygonPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ARecordPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ARectanglePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AStringPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ATimePrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AUnionPrinterFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AYearMonthDurationPrinterFactory;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactory;
+import edu.uci.ics.hyracks.algebricks.data.IPrinterFactoryProvider;
+
+public class AqlCSVPrinterFactoryProvider implements IPrinterFactoryProvider {
+
+    public static final AqlCSVPrinterFactoryProvider INSTANCE = new AqlCSVPrinterFactoryProvider();
+
+    private AqlCSVPrinterFactoryProvider() {
+    }
+
+    @Override
+    public IPrinterFactory getPrinterFactory(Object type) throws AlgebricksException {
+        IAType aqlType = (IAType) type;
+
+        if (aqlType != null) {
+            switch (aqlType.getTypeTag()) {
+            // case ANYTYPE:
+            // return AAnyTypePrinterFactory.INSTANCE;
+                case INT8:
+                    return AInt8PrinterFactory.INSTANCE;
+                case INT16:
+                    return AInt16PrinterFactory.INSTANCE;
+                case INT32:
+                    return AInt32PrinterFactory.INSTANCE;
+                case INT64:
+                    return AInt64PrinterFactory.INSTANCE;
+                case NULL:
+                    return ANullPrinterFactory.INSTANCE;
+                case BOOLEAN:
+                    return ABooleanPrinterFactory.INSTANCE;
+                case FLOAT:
+                    return AFloatPrinterFactory.INSTANCE;
+                case DOUBLE:
+                    return ADoublePrinterFactory.INSTANCE;
+                case TIME:
+                    return ATimePrinterFactory.INSTANCE;
+                case DATE:
+                    return ADatePrinterFactory.INSTANCE;
+                case DATETIME:
+                    return ADateTimePrinterFactory.INSTANCE;
+                case DURATION:
+                    return ADurationPrinterFactory.INSTANCE;
+                case YEARMONTHDURATION:
+                    return AYearMonthDurationPrinterFactory.INSTANCE;
+                case DAYTIMEDURATION:
+                    return ADayTimeDurationPrinterFactory.INSTANCE;
+                case POINT:
+                    return APointPrinterFactory.INSTANCE;
+                case POINT3D:
+                    return APoint3DPrinterFactory.INSTANCE;
+                case LINE:
+                    return ALinePrinterFactory.INSTANCE;
+                case POLYGON:
+                    return APolygonPrinterFactory.INSTANCE;
+                case CIRCLE:
+                    return ACirclePrinterFactory.INSTANCE;
+                case RECTANGLE:
+                    return ARectanglePrinterFactory.INSTANCE;
+                case STRING:
+                    return AStringPrinterFactory.INSTANCE;
+                case RECORD:
+                    return new ARecordPrinterFactory((ARecordType) aqlType);
+                case ORDEREDLIST:
+                    throw new AlgebricksException("'Orderedlist' type unsupported for CSV output");
+                case UNORDEREDLIST:
+                    throw new AlgebricksException("'Unorderedlist' type unsupported for CSV output");
+                case UNION: {
+                    if (NonTaggedFormatUtil.isOptionalField((AUnionType) aqlType))
+                        return new ANullableFieldPrinterFactory((AUnionType) aqlType);
+                    else
+                        return new AUnionPrinterFactory((AUnionType) aqlType);
+                }
+                case UUID: {
+                    return AUUIDPrinterFactory.INSTANCE;
+                }
+                case SHORTWITHOUTTYPEINFO:
+                    return ShortWithoutTypeInfoPrinterFactory.INSTANCE;
+            }
+        }
+        return AObjectPrinterFactory.INSTANCE;
+
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/APrintVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/APrintVisitor.java
new file mode 100644
index 0000000..b5588eb
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/APrintVisitor.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2009-2013 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.om.pointables.printer.csv;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.AUUIDPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.ShortWithoutTypeInfoPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ABooleanPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ACirclePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADatePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADateTimePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADayTimeDurationPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADoublePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ADurationPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AFloatPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt16Printer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt32Printer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt64Printer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AInt8Printer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ALinePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ANullPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APoint3DPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APointPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.APolygonPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ARectanglePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AStringPrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.ATimePrinter;
+import edu.uci.ics.asterix.dataflow.data.nontagged.printers.csv.AYearMonthDurationPrinter;
+import edu.uci.ics.asterix.om.pointables.AFlatValuePointable;
+import edu.uci.ics.asterix.om.pointables.AListPointable;
+import edu.uci.ics.asterix.om.pointables.ARecordPointable;
+import edu.uci.ics.asterix.om.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.om.pointables.visitor.IVisitablePointableVisitor;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
+
+/**
+ * This class is a IVisitablePointableVisitor implementation which recursively
+ * visit a given record, list or flat value of a given type, and print it to a
+ * PrintStream in CSV format.
+ */
+public class APrintVisitor implements IVisitablePointableVisitor<Void, Pair<PrintStream, ATypeTag>> {
+
+    private final Map<IVisitablePointable, ARecordPrinter> raccessorToPrinter = new HashMap<IVisitablePointable, ARecordPrinter>();
+
+    private int level = 0;
+
+    @Override
+    public Void visit(AListPointable accessor, Pair<PrintStream, ATypeTag> arg) throws AsterixException {
+        throw new AsterixException("'List' type unsupported for CSV output");
+    }
+
+    @Override
+    public Void visit(ARecordPointable accessor, Pair<PrintStream, ATypeTag> arg) throws AsterixException {
+        ARecordPrinter printer = raccessorToPrinter.get(accessor);
+        if (printer == null) {
+            printer = new ARecordPrinter();
+            raccessorToPrinter.put(accessor, printer);
+        }
+        if (level > 0) {
+            throw new AsterixException("Nested 'Record' instances unsupported for CSV output");
+        }
+
+        try {
+            level++;
+            printer.printRecord(accessor, arg.first, this);
+            level--;
+        } catch (Exception e) {
+            throw new AsterixException(e);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(AFlatValuePointable accessor, Pair<PrintStream, ATypeTag> arg) {
+        try {
+            byte[] b = accessor.getByteArray();
+            int s = accessor.getStartOffset();
+            int l = accessor.getLength();
+            PrintStream ps = arg.first;
+            ATypeTag typeTag = arg.second;
+            switch (typeTag) {
+                case INT8: {
+                    AInt8Printer.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case INT16: {
+                    AInt16Printer.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case INT32: {
+                    AInt32Printer.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case INT64: {
+                    AInt64Printer.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case NULL: {
+                    ANullPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case BOOLEAN: {
+                    ABooleanPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case FLOAT: {
+                    AFloatPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case DOUBLE: {
+                    ADoublePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case DATE: {
+                    ADatePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case TIME: {
+                    ATimePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case DATETIME: {
+                    ADateTimePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case DURATION: {
+                    ADurationPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case POINT: {
+                    APointPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case POINT3D: {
+                    APoint3DPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case LINE: {
+                    ALinePrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case POLYGON: {
+                    APolygonPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case CIRCLE: {
+                    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;
+                }
+                case YEARMONTHDURATION: {
+                    AYearMonthDurationPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case DAYTIMEDURATION: {
+                    ADayTimeDurationPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case UUID: {
+                    AUUIDPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                case SHORTWITHOUTTYPEINFO: {
+                    ShortWithoutTypeInfoPrinter.INSTANCE.print(b, s, l, ps);
+                    break;
+                }
+                default: {
+                    throw new NotImplementedException("No printer for type " + typeTag);
+                }
+            }
+            return null;
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/ARecordPrinter.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/ARecordPrinter.java
new file mode 100644
index 0000000..7effcb3
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/csv/ARecordPrinter.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009-2013 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.om.pointables.printer.csv;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.pointables.ARecordPointable;
+import edu.uci.ics.asterix.om.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
+
+/**
+ * This class is to print the content of a record. It is ONLY visible to
+ * APrintVisitor.
+ */
+class ARecordPrinter {
+    // QQQ Might we want to make this a configurable delimiter?
+    private static String COMMA = ",";
+
+    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() {
+
+    }
+
+    public void printRecord(ARecordPointable recordAccessor, PrintStream ps, APrintVisitor visitor) throws IOException,
+            AsterixException {
+        List<IVisitablePointable> fieldNames = recordAccessor.getFieldNames();
+        List<IVisitablePointable> fieldTags = recordAccessor.getFieldTypeTags();
+        List<IVisitablePointable> fieldValues = recordAccessor.getFieldValues();
+
+        nameVisitorArg.first = ps;
+        itemVisitorArg.first = ps;
+
+        // print field 0 to n-2
+        for (int i = 0; i < fieldNames.size() - 1; i++) {
+            printField(ps, visitor, fieldNames, fieldTags, fieldValues, i);
+            // print the comma
+            ps.print(COMMA);
+        }
+
+        // print field n-1
+        if (fieldValues.size() > 0) {
+            printField(ps, visitor, fieldNames, fieldTags, fieldValues, fieldValues.size() - 1);
+        }
+    }
+
+    private void printField(PrintStream ps, APrintVisitor visitor, List<IVisitablePointable> fieldNames,
+            List<IVisitablePointable> fieldTags, List<IVisitablePointable> fieldValues, int i) throws AsterixException {
+        IVisitablePointable itemTypeTag = fieldTags.get(i);
+        IVisitablePointable item = fieldValues.get(i);
+        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getByteArray()[itemTypeTag
+                .getStartOffset()]);
+        itemVisitorArg.second = item.getLength() <= 1 ? ATypeTag.NULL : typeTag;
+
+        // print field value
+        item.accept(visitor, itemVisitorArg);
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/APrintVisitor.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/APrintVisitor.java
index 2d716d6..da45f47 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/APrintVisitor.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/pointables/printer/json/APrintVisitor.java
@@ -56,7 +56,7 @@
 /**
  * This class is a IVisitablePointableVisitor implementation which recursively
  * visit a given record, list or flat value of a given type, and print it to a
- * PrintStream in adm format.
+ * PrintStream in JSON format.
  */
 public class APrintVisitor implements IVisitablePointableVisitor<Void, Pair<PrintStream, ATypeTag>> {
 
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index d9bf623..65a4ea2 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -33,6 +33,7 @@
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryHashFunctionFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryHashFunctionFamilyProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlBinaryIntegerInspector;
+import edu.uci.ics.asterix.formats.nontagged.AqlCSVPrinterFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlJSONPrinterFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlNormalizedKeyComputerFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlPredicateEvaluatorFactoryProvider;
@@ -927,6 +928,11 @@
         return AqlJSONPrinterFactoryProvider.INSTANCE;
     }
 
+    @Override
+    public IPrinterFactoryProvider getCSVPrinterFactoryProvider() {
+        return AqlCSVPrinterFactoryProvider.INSTANCE;
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public ICopyEvaluatorFactory getConstantEvalFactory(IAlgebricksConstantValue value) throws AlgebricksException {
diff --git a/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java b/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
index b3e4de9e..e2e4cb4 100644
--- a/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
+++ b/asterix-test-framework/src/main/java/edu/uci/ics/asterix/testframework/context/TestCaseContext.java
@@ -34,8 +34,9 @@
      */
     public enum OutputFormat {
         NONE  ("", ""),
-        ADM   ("adm", "application/adm"),
-        JSON  ("json", "application/json");
+        ADM   ("adm", "application/x-adm"),
+        JSON  ("json", "application/json"),
+        CSV   ("csv", "text/csv");
 
         private final String extension;
         private final String mimetype;
@@ -59,6 +60,8 @@
                 return OutputFormat.ADM;
             case JSON:
                 return OutputFormat.JSON;
+            case CSV:
+                return OutputFormat.CSV;
             case INSPECT:
             case IGNORE:
                 return OutputFormat.NONE;
diff --git a/asterix-test-framework/src/main/resources/Catalog.xsd b/asterix-test-framework/src/main/resources/Catalog.xsd
index 78c401e..a33399c 100644
--- a/asterix-test-framework/src/main/resources/Catalog.xsd
+++ b/asterix-test-framework/src/main/resources/Catalog.xsd
@@ -187,6 +187,7 @@
          <xs:enumeration value="Inspect"/>

          <xs:enumeration value="Ignore"/>

          <xs:enumeration value="JSON"/>

+         <xs:enumeration value="CSV"/>

       </xs:restriction>

    </xs:simpleType>