You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ti...@apache.org on 2018/11/10 05:31:45 UTC

[drill] branch master updated (33810df -> 9eba276)

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

timothyfarkas pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git.


    from 33810df  DRILL-6610: Add support for Minimum TLS restriction.
     new f2fd822  DRILL-6717: lower and upper functions not works with national characters
     new 9eba276  DRILL-6760: Retain original exception in Verbose Error Message

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../drill/common/exceptions/UserException.java     |   3 +
 .../common/exceptions/UserRemoteException.java     |   4 +-
 .../drill/common/util/DrillExceptionUtil.java      | 107 +++++++++++++++++++++
 .../exec/expr/fn/impl/StringFunctionHelpers.java   |  20 ++--
 .../drill/exec/expr/fn/impl/StringFunctions.java   |  35 +++----
 .../exec/expr/fn/impl/TestStringFunctions.java     |   2 -
 .../drill/exec/util/DrillExceptionUtilTest.java    |  53 ++++++++++
 7 files changed, 193 insertions(+), 31 deletions(-)
 create mode 100644 common/src/main/java/org/apache/drill/common/util/DrillExceptionUtil.java
 create mode 100644 exec/java-exec/src/test/java/org/apache/drill/exec/util/DrillExceptionUtilTest.java


[drill] 02/02: DRILL-6760: Retain original exception in Verbose Error Message

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9eba276845a8f9c6edba628bd6a59207cd41c64e
Author: shuifeng lu <lu...@gmail.com>
AuthorDate: Wed Oct 31 19:54:52 2018 +0800

    DRILL-6760: Retain original exception in Verbose Error Message
    
    closes #1519
---
 .../drill/common/exceptions/UserException.java     |   3 +
 .../common/exceptions/UserRemoteException.java     |   4 +-
 .../drill/common/util/DrillExceptionUtil.java      | 107 +++++++++++++++++++++
 .../drill/exec/util/DrillExceptionUtilTest.java    |  53 ++++++++++
 4 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/common/src/main/java/org/apache/drill/common/exceptions/UserException.java b/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
index 3a3ca5a..3fcdc07 100644
--- a/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
+++ b/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
@@ -742,6 +742,9 @@ public class UserException extends DrillRuntimeException {
     if (getCause() != null) {
       // some unit tests use this information to make sure a specific exception was thrown in the server
       builder.setException(ErrorHelper.getWrapper(getCause()));
+    } else {
+      // not a wrapper exception
+      builder.setException(ErrorHelper.getWrapper(this));
     }
     return builder.build();
   }
diff --git a/common/src/main/java/org/apache/drill/common/exceptions/UserRemoteException.java b/common/src/main/java/org/apache/drill/common/exceptions/UserRemoteException.java
index 04c9890..4835b29 100644
--- a/common/src/main/java/org/apache/drill/common/exceptions/UserRemoteException.java
+++ b/common/src/main/java/org/apache/drill/common/exceptions/UserRemoteException.java
@@ -19,6 +19,8 @@ package org.apache.drill.common.exceptions;
 
 import org.apache.drill.exec.proto.UserBitShared.DrillPBError;
 
+import static org.apache.drill.common.util.DrillExceptionUtil.getThrowable;
+
 /**
  * Wraps a DrillPBError object so we don't need to rebuilt it multiple times when sending it to the client. It also
  * gives access to the original exception className and message.
@@ -28,7 +30,7 @@ public class UserRemoteException extends UserException {
   private final DrillPBError error;
 
   public UserRemoteException(DrillPBError error) {
-    super(error.getErrorType(), "Drill Remote Exception", null);
+    super(error.getErrorType(), "Drill Remote Exception", getThrowable(error.getException()));
     this.error = error;
   }
 
diff --git a/common/src/main/java/org/apache/drill/common/util/DrillExceptionUtil.java b/common/src/main/java/org/apache/drill/common/util/DrillExceptionUtil.java
new file mode 100644
index 0000000..8ae93a8
--- /dev/null
+++ b/common/src/main/java/org/apache/drill/common/util/DrillExceptionUtil.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 at
+ *
+ * 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 org.apache.drill.common.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.drill.exec.proto.UserBitShared;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+
+/**
+ * Utility class which contain methods for conversion Drill ProtoBuf Error and Throwable
+ */
+public class DrillExceptionUtil {
+
+  /**
+   * Recreate throwable from exception protoBuf which received from remote or local node.
+   * if no match constructor found, the base Throwable (Exception or Error) is created as a substitution
+   *
+   * @param exceptionWrapper the exception protoBuf
+   * @return Throwable deserialized from protoBuf
+   */
+  public static Throwable getThrowable(UserBitShared.ExceptionWrapper exceptionWrapper) {
+    if (exceptionWrapper == null) {
+      return null;
+    }
+    String className = exceptionWrapper.getExceptionClass();
+    if (StringUtils.isBlank(className) || exceptionWrapper.getStackTraceCount() < 1) {
+      return null;
+    }
+    Throwable inner = getThrowable(exceptionWrapper.getCause());
+    try {
+      Throwable throwable = getInstance(className, exceptionWrapper.getMessage(), inner);
+      int size = exceptionWrapper.getStackTraceCount();
+      StackTraceElement[] stackTrace = new StackTraceElement[size];
+      for (int i = 0; i < size; ++i) {
+        UserBitShared.StackTraceElementWrapper w = exceptionWrapper.getStackTrace(i);
+        stackTrace[i] = new StackTraceElement(w.getClassName(), w.getMethodName(), w.getFileName(), w.getLineNumber());
+      }
+      throwable.setStackTrace(stackTrace);
+      return throwable;
+    } catch (Throwable t) {
+      return null;
+    }
+  }
+
+  /**
+   * Get throwable from class name and its constructors, the candidate constructor of exception are:
+   * 1) ExceptionClass(String message, Throwable t),
+   * 2) ExceptionClass(Throwable t, String message),
+   * 3) ExceptionClass(String message).
+   * if no match constructor found, the base Throwable (Exception or Error) is created as a substitution
+   *
+   * @param className the exception class name
+   * @param message the exception message
+   * @param inner the parent cause of the exception
+   * @return Throwable
+   */
+  private static Throwable getInstance(String className, String message, Throwable inner) throws ReflectiveOperationException {
+    Class clazz;
+    try {
+      clazz = Class.forName(className);
+    } catch (ClassNotFoundException e) {
+      return new Exception(message, inner);
+    }
+    Constructor<Throwable>[] constructors = clazz.getConstructors();
+    Class<?>[] defaultParameterTypes = new Class<?>[]{String.class, Throwable.class};
+    Class<?>[] revertParameterTypes = new Class<?>[]{Throwable.class, String.class};
+    Class<?>[] singleParameterType = new Class<?>[]{String.class};
+    for (Constructor<Throwable> constructor : constructors) {
+      if (Arrays.equals(defaultParameterTypes, constructor.getParameterTypes())) {
+        return constructor.newInstance(message, inner);
+      }
+      if (Arrays.equals(revertParameterTypes, constructor.getParameterTypes())) {
+        return constructor.newInstance(inner, message);
+      }
+      if (inner == null) {
+        if (Arrays.equals(singleParameterType, constructor.getParameterTypes())) {
+          return constructor.newInstance(message);
+        }
+      }
+    }
+    return getBaseInstance(clazz, message, inner);
+  }
+
+  private static Throwable getBaseInstance(Class clazz, String message, Throwable inner) {
+    if (Error.class.isAssignableFrom(clazz)) {
+      return new Error(message, inner);
+    }
+    return new Exception(message, inner);
+  }
+}
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/util/DrillExceptionUtilTest.java b/exec/java-exec/src/test/java/org/apache/drill/exec/util/DrillExceptionUtilTest.java
new file mode 100644
index 0000000..a2cb29a
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/util/DrillExceptionUtilTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 at
+ *
+ * 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 org.apache.drill.exec.util;
+
+import org.apache.drill.common.exceptions.DrillIOException;
+import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.exceptions.ErrorHelper;
+import org.apache.drill.common.util.DrillExceptionUtil;
+import org.apache.drill.exec.proto.UserBitShared;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class DrillExceptionUtilTest {
+  private static final String ERROR_MESSAGE = "Exception Test";
+  private static final String NESTED_ERROR_MESSAGE = "Nested Exception";
+
+  @Test
+  public void testUnwrapException() {
+    Throwable rootThrowable = new DrillRuntimeException(ERROR_MESSAGE);
+    UserBitShared.ExceptionWrapper exceptionWrapper = ErrorHelper.getWrapper(rootThrowable);
+    Throwable t = DrillExceptionUtil.getThrowable(exceptionWrapper);
+    assertEquals("Exception class should match", rootThrowable.getClass(), t.getClass());
+    assertEquals("Exception message should match", rootThrowable.getMessage(), t.getMessage());
+  }
+
+  @Test
+  public void testUnwrapNestedException() {
+    Throwable nested = new DrillIOException(NESTED_ERROR_MESSAGE);
+    Throwable rootThrowable = new Error(ERROR_MESSAGE, nested);
+    UserBitShared.ExceptionWrapper exceptionWrapper = ErrorHelper.getWrapper(rootThrowable);
+    Throwable t = DrillExceptionUtil.getThrowable(exceptionWrapper);
+    assertEquals("Exception class should match", rootThrowable.getClass(), t.getClass());
+    assertEquals("Exception message should match", rootThrowable.getMessage(), t.getMessage());
+    assertEquals("Exception cause class should match", rootThrowable.getCause().getClass(), t.getCause().getClass());
+    assertEquals("Exception cause message should match", rootThrowable.getCause().getMessage(), t.getCause().getMessage());
+  }
+}


[drill] 01/02: DRILL-6717: lower and upper functions not works with national characters

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f2fd822afd8acc5aaa99dd37fb2f798bbec54a00
Author: ozinoviev <oz...@solit-clouds.ru>
AuthorDate: Tue Aug 28 20:29:55 2018 +0300

    DRILL-6717: lower and upper functions not works with national characters
    
    closes #1450
---
 .../exec/expr/fn/impl/StringFunctionHelpers.java   | 20 ++++++-------
 .../drill/exec/expr/fn/impl/StringFunctions.java   | 35 +++++++++++-----------
 .../exec/expr/fn/impl/TestStringFunctions.java     |  2 --
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
index 677446a..cd18180 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctionHelpers.java
@@ -148,24 +148,22 @@ public class StringFunctionHelpers {
    * Capitalizes first letter in each word.
    * Any symbol except digits and letters is considered as word delimiter.
    *
-   * @param start start position in input buffer
-   * @param end end position in input buffer
-   * @param inBuf buffer with input characters
-   * @param outBuf buffer with output characters
+   * @param source input characters
    */
-  public static void initCap(int start, int end, DrillBuf inBuf, DrillBuf outBuf) {
+  public static String initCap(String source) {
     boolean capitalizeNext = true;
-    int out = 0;
-    for (int id = start; id < end; id++, out++) {
-      int currentByte = inBuf.getByte(id);
-      if (Character.isLetterOrDigit(currentByte)) {
-        currentByte = capitalizeNext ? Character.toUpperCase(currentByte) : Character.toLowerCase(currentByte);
+    StringBuilder str = new StringBuilder(source);
+    for (int i = 0; i < str.length(); i++) {
+      char c = str.charAt(i);
+      if (Character.isLetterOrDigit(c)) {
+        str.setCharAt(i, capitalizeNext ? Character.toUpperCase(c) : Character.toLowerCase(c));
         capitalizeNext = false;
       } else {
         capitalizeNext = true;
       }
-      outBuf.setByte(out, currentByte);
     }
+
+    return str.toString();
   }
 
   /**
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctions.java
index a77faee..6353e55 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctions.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/StringFunctions.java
@@ -491,14 +491,13 @@ public class StringFunctions{
 
     @Override
     public void eval() {
-      out.buffer = buffer = buffer.reallocIfNeeded(input.end- input.start);
-      out.start = 0;
-      out.end = input.end - input.start;
+      String str = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, input.buffer);
+      byte[] result = str.toLowerCase().getBytes(com.google.common.base.Charsets.UTF_8);
 
-      for (int id = input.start; id < input.end; id++) {
-        byte  currentByte = input.buffer.getByte(id);
-        out.buffer.setByte(id - input.start, Character.toLowerCase(currentByte));
-      }
+      out.buffer = buffer = buffer.reallocIfNeeded(result.length);
+      out.start = 0;
+      out.end = result.length;
+      out.buffer.setBytes(0, result);
     }
   }
 
@@ -522,14 +521,13 @@ public class StringFunctions{
 
     @Override
     public void eval() {
-      out.buffer = buffer = buffer.reallocIfNeeded(input.end- input.start);
-      out.start = 0;
-      out.end = input.end - input.start;
+      String str = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, input.buffer);
+      byte[] result = str.toUpperCase().getBytes(com.google.common.base.Charsets.UTF_8);
 
-      for (int id = input.start; id < input.end; id++) {
-        byte currentByte = input.buffer.getByte(id);
-        out.buffer.setByte(id - input.start, Character.toUpperCase(currentByte));
-      }
+      out.buffer = buffer = buffer.reallocIfNeeded(result.length);
+      out.start = 0;
+      out.end = result.length;
+      out.buffer.setBytes(0, result);
     }
   }
 
@@ -785,10 +783,13 @@ public class StringFunctions{
 
     @Override
     public void eval() {
-      out.buffer = buffer = buffer.reallocIfNeeded(input.end - input.start);
+      String source = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, input.buffer);
+      String result = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.initCap(source);
+      byte[] bytes = result.getBytes(com.google.common.base.Charsets.UTF_8);
+      out.buffer = buffer = buffer.reallocIfNeeded(bytes.length);
       out.start = 0;
-      out.end = input.end - input.start;
-      org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.initCap(input.start, input.end, input.buffer, out.buffer);
+      out.end = bytes.length;
+      out.buffer.setBytes(0, bytes);
     }
 
   }
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
index 8158c39..0f79daa 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/expr/fn/impl/TestStringFunctions.java
@@ -23,7 +23,6 @@ import org.apache.drill.categories.UnlikelyTest;
 import org.apache.drill.test.BaseTestQuery;
 import org.apache.drill.categories.SqlFunctionTest;
 import org.apache.drill.exec.util.Text;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableList;
@@ -1494,7 +1493,6 @@ public class TestStringFunctions extends BaseTestQuery {
         .run();
   }
 
-  @Ignore("DRILL-5477")
   @Test
   public void testMultiByteEncoding() throws Exception {
     testBuilder()