aboutsummaryrefslogtreecommitdiff
path: root/sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java
diff options
context:
space:
mode:
Diffstat (limited to 'sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java')
-rw-r--r--sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java248
1 files changed, 248 insertions, 0 deletions
diff --git a/sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java b/sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java
new file mode 100644
index 0000000000..1334dde663
--- /dev/null
+++ b/sql/hive-thriftserver/src/main/java/org/apache/hive/service/cli/HiveSQLException.java
@@ -0,0 +1,248 @@
+/**
+ * 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.hive.service.cli;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hive.service.cli.thrift.TStatus;
+import org.apache.hive.service.cli.thrift.TStatusCode;
+
+/**
+ * HiveSQLException.
+ *
+ */
+public class HiveSQLException extends SQLException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6095254671958748094L;
+
+ /**
+ *
+ */
+ public HiveSQLException() {
+ super();
+ }
+
+ /**
+ * @param reason
+ */
+ public HiveSQLException(String reason) {
+ super(reason);
+ }
+
+ /**
+ * @param cause
+ */
+ public HiveSQLException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param reason
+ * @param sqlState
+ */
+ public HiveSQLException(String reason, String sqlState) {
+ super(reason, sqlState);
+ }
+
+ /**
+ * @param reason
+ * @param cause
+ */
+ public HiveSQLException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
+
+ /**
+ * @param reason
+ * @param sqlState
+ * @param vendorCode
+ */
+ public HiveSQLException(String reason, String sqlState, int vendorCode) {
+ super(reason, sqlState, vendorCode);
+ }
+
+ /**
+ * @param reason
+ * @param sqlState
+ * @param cause
+ */
+ public HiveSQLException(String reason, String sqlState, Throwable cause) {
+ super(reason, sqlState, cause);
+ }
+
+ /**
+ * @param reason
+ * @param sqlState
+ * @param vendorCode
+ * @param cause
+ */
+ public HiveSQLException(String reason, String sqlState, int vendorCode, Throwable cause) {
+ super(reason, sqlState, vendorCode, cause);
+ }
+
+ public HiveSQLException(TStatus status) {
+ // TODO: set correct vendorCode field
+ super(status.getErrorMessage(), status.getSqlState(), status.getErrorCode());
+ if (status.getInfoMessages() != null) {
+ initCause(toCause(status.getInfoMessages()));
+ }
+ }
+
+ /**
+ * Converts current object to a {@link TStatus} object
+ * @return a {@link TStatus} object
+ */
+ public TStatus toTStatus() {
+ // TODO: convert sqlState, etc.
+ TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
+ tStatus.setSqlState(getSQLState());
+ tStatus.setErrorCode(getErrorCode());
+ tStatus.setErrorMessage(getMessage());
+ tStatus.setInfoMessages(toString(this));
+ return tStatus;
+ }
+
+ /**
+ * Converts the specified {@link Exception} object into a {@link TStatus} object
+ * @param e a {@link Exception} object
+ * @return a {@link TStatus} object
+ */
+ public static TStatus toTStatus(Exception e) {
+ if (e instanceof HiveSQLException) {
+ return ((HiveSQLException)e).toTStatus();
+ }
+ TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
+ tStatus.setErrorMessage(e.getMessage());
+ tStatus.setInfoMessages(toString(e));
+ return tStatus;
+ }
+
+ /**
+ * Converts a {@link Throwable} object into a flattened list of texts including its stack trace
+ * and the stack traces of the nested causes.
+ * @param ex a {@link Throwable} object
+ * @return a flattened list of texts including the {@link Throwable} object's stack trace
+ * and the stack traces of the nested causes.
+ */
+ public static List<String> toString(Throwable ex) {
+ return toString(ex, null);
+ }
+
+ private static List<String> toString(Throwable cause, StackTraceElement[] parent) {
+ StackTraceElement[] trace = cause.getStackTrace();
+ int m = trace.length - 1;
+ if (parent != null) {
+ int n = parent.length - 1;
+ while (m >= 0 && n >= 0 && trace[m].equals(parent[n])) {
+ m--; n--;
+ }
+ }
+ List<String> detail = enroll(cause, trace, m);
+ cause = cause.getCause();
+ if (cause != null) {
+ detail.addAll(toString(cause, trace));
+ }
+ return detail;
+ }
+
+ private static List<String> enroll(Throwable ex, StackTraceElement[] trace, int max) {
+ List<String> details = new ArrayList<String>();
+ StringBuilder builder = new StringBuilder();
+ builder.append('*').append(ex.getClass().getName()).append(':');
+ builder.append(ex.getMessage()).append(':');
+ builder.append(trace.length).append(':').append(max);
+ details.add(builder.toString());
+ for (int i = 0; i <= max; i++) {
+ builder.setLength(0);
+ builder.append(trace[i].getClassName()).append(':');
+ builder.append(trace[i].getMethodName()).append(':');
+ String fileName = trace[i].getFileName();
+ builder.append(fileName == null ? "" : fileName).append(':');
+ builder.append(trace[i].getLineNumber());
+ details.add(builder.toString());
+ }
+ return details;
+ }
+
+ /**
+ * Converts a flattened list of texts including the stack trace and the stack
+ * traces of the nested causes into a {@link Throwable} object.
+ * @param details a flattened list of texts including the stack trace and the stack
+ * traces of the nested causes
+ * @return a {@link Throwable} object
+ */
+ public static Throwable toCause(List<String> details) {
+ return toStackTrace(details, null, 0);
+ }
+
+ private static Throwable toStackTrace(List<String> details, StackTraceElement[] parent, int index) {
+ String detail = details.get(index++);
+ if (!detail.startsWith("*")) {
+ return null; // should not be happened. ignore remaining
+ }
+ int i1 = detail.indexOf(':');
+ int i3 = detail.lastIndexOf(':');
+ int i2 = detail.substring(0, i3).lastIndexOf(':');
+ String exceptionClass = detail.substring(1, i1);
+ String exceptionMessage = detail.substring(i1 + 1, i2);
+ Throwable ex = newInstance(exceptionClass, exceptionMessage);
+
+ Integer length = Integer.valueOf(detail.substring(i2 + 1, i3));
+ Integer unique = Integer.valueOf(detail.substring(i3 + 1));
+
+ int i = 0;
+ StackTraceElement[] trace = new StackTraceElement[length];
+ for (; i <= unique; i++) {
+ detail = details.get(index++);
+ int j1 = detail.indexOf(':');
+ int j3 = detail.lastIndexOf(':');
+ int j2 = detail.substring(0, j3).lastIndexOf(':');
+ String className = detail.substring(0, j1);
+ String methodName = detail.substring(j1 + 1, j2);
+ String fileName = detail.substring(j2 + 1, j3);
+ if (fileName.isEmpty()) {
+ fileName = null;
+ }
+ int lineNumber = Integer.valueOf(detail.substring(j3 + 1));
+ trace[i] = new StackTraceElement(className, methodName, fileName, lineNumber);
+ }
+ int common = trace.length - i;
+ if (common > 0) {
+ System.arraycopy(parent, parent.length - common, trace, trace.length - common, common);
+ }
+ if (details.size() > index) {
+ ex.initCause(toStackTrace(details, trace, index));
+ }
+ ex.setStackTrace(trace);
+ return ex;
+ }
+
+ private static Throwable newInstance(String className, String message) {
+ try {
+ return (Throwable)Class.forName(className).getConstructor(String.class).newInstance(message);
+ } catch (Exception e) {
+ return new RuntimeException(className + ":" + message);
+ }
+ }
+}