This is an automated email from the ASF dual-hosted git repository.

zhangyifan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c333560b [java client] Make row errors more readable
7c333560b is described below

commit 7c333560b4287c8ce399bd33768a346b39d4fd22
Author: xinghuayu007 <[email protected]>
AuthorDate: Thu Jul 6 09:24:33 2023 +0800

    [java client] Make row errors more readable
    
    Flushing data in AUTO_FLUSH_BACKGROUND mode sometimes may fail.
    It's possible get the error details by calling
    KuduSession.getPendingErrors(), but it doesn't present the
    information in a human-readable form.
    Here is an example:
    "
    Row error for primary key=[-128, 0, 0, 12], tablet=null,
    server=ff9a26c5fcde45f5b74c3da11a7fc89d, status=Already
    present: key already present (error 0)
    "
    This patch makes the row errors more readable for debugging.
    Here is an example after using this patch:
    "
    Row error for row=(int32 key=12, int32 column1_i=2,
    int32 column2_i=3, string column3_s="a string",
    bool column4_b=true), tablet=null,
    server=ba360521df2844b8a9035c7c505d30d8,
    status=Already present: key already present (error 0)
    "
    
    Change-Id: I1170986ef9b40d83a6b6da8571d15d1c6bf4df97
    Reviewed-on: http://gerrit.cloudera.org:8080/20163
    Reviewed-by: Yifan Zhang <[email protected]>
    Tested-by: Yifan Zhang <[email protected]>
---
 .../main/java/org/apache/kudu/client/RowError.java |  2 +-
 .../java/org/apache/kudu/client/TestRowErrors.java | 84 ++++++++++++++++++++++
 2 files changed, 85 insertions(+), 1 deletion(-)

diff --git 
a/java/kudu-client/src/main/java/org/apache/kudu/client/RowError.java 
b/java/kudu-client/src/main/java/org/apache/kudu/client/RowError.java
index 048b3ab54..ef6bd0aa3 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/RowError.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/RowError.java
@@ -100,7 +100,7 @@ public class RowError {
   @Override
   public String toString() {
     // Intentionally not redacting the row key to make this more useful.
-    return "Row error for primary key=" + 
Bytes.pretty(operation.getRow().encodePrimaryKey()) +
+    return "Row error for row=" + operation.getRow() +
         ", tablet=" + operation.getTablet() +
         ", server=" + tsUUID +
         ", status=" + status.toString();
diff --git 
a/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowErrors.java 
b/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowErrors.java
index 5f122a20d..d476079e9 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowErrors.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestRowErrors.java
@@ -25,13 +25,21 @@ import static 
org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import com.google.common.collect.ImmutableList;
 import org.junit.Rule;
 import org.junit.Test;
 
+import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.Schema;
+import org.apache.kudu.Type;
 import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.DateUtil;
 
 public class TestRowErrors {
 
@@ -99,6 +107,82 @@ public class TestRowErrors {
     assertEquals(0, session.countPendingErrors());
   }
 
+  @Test(timeout = 100000)
+  public void readableRowErrorTest() throws Exception {
+    KuduSession session = harness.getClient().newSession();
+    Map<Type, String> dataByType = new HashMap<>();
+    dataByType.put(Type.INT32, "10000");
+    dataByType.put(Type.DATE, "1970-01-01");
+    dataByType.put(Type.STRING, "fun with ütf");
+    dataByType.put(Type.BINARY, "[0, 1, 2, 3, 4]");
+    int anotherColData = 101;
+    Type[] types = new Type[] {Type.INT32, Type.DATE, Type.STRING, 
Type.BINARY};
+    for (Type dataType : types) {
+      flushDifferentTypeData(dataType, dataByType, anotherColData, session);
+      for (RowError re : session.getPendingErrors().getRowErrors()) {
+        String cmpStr = String.format("Row error for row=(%s c0=%s, int32 
c1=%d)",
+                        dataType.getName(), dataByType.get(dataType), 
anotherColData);
+        if (dataType == Type.STRING || dataType == Type.BINARY) {
+          cmpStr = String.format("Row error for row=(%s c0=\"%s\", int32 
c1=%d)",
+                   dataType.getName(), dataByType.get(dataType), 
anotherColData);
+        }
+        assertTrue(re.toString().contains(cmpStr));
+      }
+    }
+  }
+
+  private void flushDifferentTypeData(Type dataType, Map<Type, String> 
dataByType,
+                                      int anotherColData, KuduSession session)
+                                      throws Exception {
+    String tableName = TestRowErrors.class.getName() + "-" + 
System.currentTimeMillis();
+    CreateTableOptions createOptions = new CreateTableOptions()
+        .addHashPartitions(ImmutableList.of("c0"), 2, 0);
+    ArrayList<ColumnSchema> columns = new ArrayList<>();
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("c0", dataType)
+                                .nullable(false)
+                                .key(true)
+                                .build());
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("c1", Type.INT32)
+                                .nullable(false)
+                                .build());
+    Schema schema = new Schema(columns);
+
+    KuduClient client = harness.getClient();
+    client.createTable(tableName, schema, createOptions);
+    table = client.openTable(tableName);
+
+    session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
+
+    Update update = table.newUpdate();
+    PartialRow row = update.getRow();
+    switch (dataType) {
+      // Type.INT32.
+      case INT32:
+        row.addInt("c0", Integer.parseInt(dataByType.get(dataType)));
+        break;
+      // Type.DATE.
+      case DATE:
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd" );
+        java.util.Date d1 = sdf.parse(dataByType.get(dataType));
+        java.sql.Date d2 = new java.sql.Date(d1.getTime());
+        row.addDate("c0",  d2);
+        break;
+      // Type.STRING.
+      case STRING:
+        row.addString("c0", dataByType.get(dataType));
+        break;
+      // Type.BINARY.
+      case BINARY:
+        row.addBinary("c0", dataByType.get(dataType).getBytes("UTF-8"));
+        break;
+      default:
+        return;
+    }
+    row.addInt("c1", anotherColData);
+    session.apply(update);
+    session.flush();
+  }
+
   private Insert createInsert(int key) {
     return createBasicSchemaInsert(table, key);
   }

Reply via email to