ASTERIXDB-1940: Report number of errors

Change-Id: I2d7fbf351cc0fc21f47cf0b9d82a8b72bc5098e9
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1831
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
BAD: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index da04c52..ec90ae9 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -135,7 +135,8 @@
         ELAPSED_TIME("elapsedTime"),
         EXECUTION_TIME("executionTime"),
         RESULT_COUNT("resultCount"),
-        RESULT_SIZE("resultSize");
+        RESULT_SIZE("resultSize"),
+        ERROR_COUNT("errorCount");
 
         private final String str;
 
@@ -285,7 +286,8 @@
     }
 
     private static void printMetrics(PrintWriter pw, long elapsedTime, long executionTime, long resultCount,
-            long resultSize) {
+            long resultSize, long errorCount) {
+        boolean hasErrors = errorCount != 0;
         pw.print("\t\"");
         pw.print(ResultFields.METRICS.str());
         pw.print("\": {\n");
@@ -296,7 +298,11 @@
         pw.print("\t");
         ResultUtil.printField(pw, Metrics.RESULT_COUNT.str(), resultCount, true);
         pw.print("\t");
-        ResultUtil.printField(pw, Metrics.RESULT_SIZE.str(), resultSize, false);
+        ResultUtil.printField(pw, Metrics.RESULT_SIZE.str(), resultSize, hasErrors);
+        if (hasErrors) {
+            pw.print("\t");
+            ResultUtil.printField(pw, Metrics.ERROR_COUNT.str(), errorCount, false);
+        }
         pw.print("\t}\n");
     }
 
@@ -403,6 +409,7 @@
         printClientContextID(resultWriter, param);
         printSignature(resultWriter);
         printType(resultWriter, sessionConfig);
+        long errorCount = 1; // so far we just return 1 error
         try {
             if (param.statement == null || param.statement.isEmpty()) {
                 throw new AsterixException("Empty request, no statement provided");
@@ -412,6 +419,7 @@
             if (ResultDelivery.IMMEDIATE == delivery || ResultDelivery.DEFERRED == delivery) {
                 ResultUtil.printStatus(sessionOutput, ResultStatus.SUCCESS);
             }
+            errorCount = 0;
         } catch (AlgebricksException | TokenMgrError | org.apache.asterix.aqlplus.parser.TokenMgrError pe) {
             GlobalConfig.ASTERIX_LOGGER.log(Level.INFO, pe.getMessage(), pe);
             ResultUtil.printError(resultWriter, pe);
@@ -435,7 +443,7 @@
             }
         }
         printMetrics(resultWriter, System.nanoTime() - elapsedStart, execStartEnd[1] - execStartEnd[0],
-                stats.getCount(), stats.getSize());
+                stats.getCount(), stats.getSize(), errorCount);
         resultWriter.print("}\n");
         resultWriter.flush();
         String result = stringWriter.toString();
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
index 1d50c26..76b3510 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/ResultExtractor.java
@@ -74,6 +74,9 @@
                     break;
                 case "errors":
                     JsonNode errors = result.get(field).get(0).get("msg");
+                    if (!result.get("metrics").has("errorCount")) {
+                        throw new AsterixException("Request reported error but not an errorCount");
+                    };
                     throw new AsterixException(errors.asText());
                 case "results":
                     if (result.get(field).size() <= 1) {