0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 package org.apache.hive.service.cli;
0020
0021 import java.sql.SQLException;
0022 import java.util.ArrayList;
0023 import java.util.List;
0024
0025 import org.apache.hive.service.cli.thrift.TStatus;
0026 import org.apache.hive.service.cli.thrift.TStatusCode;
0027
0028
0029
0030
0031
0032 public class HiveSQLException extends SQLException {
0033
0034
0035
0036
0037 private static final long serialVersionUID = -6095254671958748094L;
0038
0039
0040
0041
0042 public HiveSQLException() {
0043 super();
0044 }
0045
0046
0047
0048
0049 public HiveSQLException(String reason) {
0050 super(reason);
0051 }
0052
0053
0054
0055
0056 public HiveSQLException(Throwable cause) {
0057 super(cause);
0058 }
0059
0060
0061
0062
0063
0064 public HiveSQLException(String reason, String sqlState) {
0065 super(reason, sqlState);
0066 }
0067
0068
0069
0070
0071
0072 public HiveSQLException(String reason, Throwable cause) {
0073 super(reason, cause);
0074 }
0075
0076
0077
0078
0079
0080
0081 public HiveSQLException(String reason, String sqlState, int vendorCode) {
0082 super(reason, sqlState, vendorCode);
0083 }
0084
0085
0086
0087
0088
0089
0090 public HiveSQLException(String reason, String sqlState, Throwable cause) {
0091 super(reason, sqlState, cause);
0092 }
0093
0094
0095
0096
0097
0098
0099
0100 public HiveSQLException(String reason, String sqlState, int vendorCode, Throwable cause) {
0101 super(reason, sqlState, vendorCode, cause);
0102 }
0103
0104 public HiveSQLException(TStatus status) {
0105
0106 super(status.getErrorMessage(), status.getSqlState(), status.getErrorCode());
0107 if (status.getInfoMessages() != null) {
0108 initCause(toCause(status.getInfoMessages()));
0109 }
0110 }
0111
0112
0113
0114
0115
0116 public TStatus toTStatus() {
0117
0118 TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
0119 tStatus.setSqlState(getSQLState());
0120 tStatus.setErrorCode(getErrorCode());
0121 tStatus.setErrorMessage(getMessage());
0122 tStatus.setInfoMessages(toString(this));
0123 return tStatus;
0124 }
0125
0126
0127
0128
0129
0130
0131 public static TStatus toTStatus(Exception e) {
0132 if (e instanceof HiveSQLException) {
0133 return ((HiveSQLException)e).toTStatus();
0134 }
0135 TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
0136 tStatus.setErrorMessage(e.getMessage());
0137 tStatus.setInfoMessages(toString(e));
0138 return tStatus;
0139 }
0140
0141
0142
0143
0144
0145
0146
0147
0148 public static List<String> toString(Throwable ex) {
0149 return toString(ex, null);
0150 }
0151
0152 private static List<String> toString(Throwable cause, StackTraceElement[] parent) {
0153 StackTraceElement[] trace = cause.getStackTrace();
0154 int m = trace.length - 1;
0155 if (parent != null) {
0156 int n = parent.length - 1;
0157 while (m >= 0 && n >= 0 && trace[m].equals(parent[n])) {
0158 m--;
0159 n--;
0160 }
0161 }
0162 List<String> detail = enroll(cause, trace, m);
0163 cause = cause.getCause();
0164 if (cause != null) {
0165 detail.addAll(toString(cause, trace));
0166 }
0167 return detail;
0168 }
0169
0170 private static List<String> enroll(Throwable ex, StackTraceElement[] trace, int max) {
0171 List<String> details = new ArrayList<String>();
0172 StringBuilder builder = new StringBuilder();
0173 builder.append('*').append(ex.getClass().getName()).append(':');
0174 builder.append(ex.getMessage()).append(':');
0175 builder.append(trace.length).append(':').append(max);
0176 details.add(builder.toString());
0177 for (int i = 0; i <= max; i++) {
0178 builder.setLength(0);
0179 builder.append(trace[i].getClassName()).append(':');
0180 builder.append(trace[i].getMethodName()).append(':');
0181 String fileName = trace[i].getFileName();
0182 builder.append(fileName == null ? "" : fileName).append(':');
0183 builder.append(trace[i].getLineNumber());
0184 details.add(builder.toString());
0185 }
0186 return details;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196 public static Throwable toCause(List<String> details) {
0197 return toStackTrace(details, null, 0);
0198 }
0199
0200 private static Throwable toStackTrace(List<String> details, StackTraceElement[] parent, int index) {
0201 String detail = details.get(index++);
0202 if (!detail.startsWith("*")) {
0203 return null;
0204 }
0205 int i1 = detail.indexOf(':');
0206 int i3 = detail.lastIndexOf(':');
0207 int i2 = detail.substring(0, i3).lastIndexOf(':');
0208 String exceptionClass = detail.substring(1, i1);
0209 String exceptionMessage = detail.substring(i1 + 1, i2);
0210 Throwable ex = newInstance(exceptionClass, exceptionMessage);
0211
0212 Integer length = Integer.valueOf(detail.substring(i2 + 1, i3));
0213 Integer unique = Integer.valueOf(detail.substring(i3 + 1));
0214
0215 int i = 0;
0216 StackTraceElement[] trace = new StackTraceElement[length];
0217 for (; i <= unique; i++) {
0218 detail = details.get(index++);
0219 int j1 = detail.indexOf(':');
0220 int j3 = detail.lastIndexOf(':');
0221 int j2 = detail.substring(0, j3).lastIndexOf(':');
0222 String className = detail.substring(0, j1);
0223 String methodName = detail.substring(j1 + 1, j2);
0224 String fileName = detail.substring(j2 + 1, j3);
0225 if (fileName.isEmpty()) {
0226 fileName = null;
0227 }
0228 int lineNumber = Integer.valueOf(detail.substring(j3 + 1));
0229 trace[i] = new StackTraceElement(className, methodName, fileName, lineNumber);
0230 }
0231 int common = trace.length - i;
0232 if (common > 0) {
0233 System.arraycopy(parent, parent.length - common, trace, trace.length - common, common);
0234 }
0235 if (details.size() > index) {
0236 ex.initCause(toStackTrace(details, trace, index));
0237 }
0238 ex.setStackTrace(trace);
0239 return ex;
0240 }
0241
0242 private static Throwable newInstance(String className, String message) {
0243 try {
0244 return (Throwable)Class.forName(className).getConstructor(String.class).newInstance(message);
0245 } catch (Exception e) {
0246 return new RuntimeException(className + ":" + message);
0247 }
0248 }
0249 }