/* * 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.tajo.exception; import com.google.common.collect.Maps; import org.apache.tajo.error.Errors.ResultCode; import org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.ReturnState; import java.sql.SQLException; import java.util.Map; import static org.apache.tajo.exception.ReturnStateUtil.isError; public class SQLExceptionUtil { private static final Map<ResultCode, String> SQLSTATES = Maps.newHashMap(); static { SQLSTATES.put(ResultCode.INTERNAL_ERROR, "XX000"); SQLSTATES.put(ResultCode.NOT_IMPLEMENTED, "0A000"); SQLSTATES.put(ResultCode.FEATURE_NOT_SUPPORTED, "0A000"); SQLSTATES.put(ResultCode.INVALID_RPC_CALL, "08P01"); // Protocol violation // Class 61 - Query Management and Scheduler SQLSTATES.put(ResultCode.QUERY_FAILED, "61T01"); SQLSTATES.put(ResultCode.QUERY_KILLED, "61T02"); SQLSTATES.put(ResultCode.QUERY_TIMEOUT, "61T03"); SQLSTATES.put(ResultCode.QUERY_NOT_FOUND, "61T04"); SQLSTATES.put(ResultCode.NO_DATA, "61T05"); SQLSTATES.put(ResultCode.INCOMPLETE_QUERY, "61T06"); // Class 62 - Session SQLSTATES.put(ResultCode.INVALID_SESSION, "62T01"); SQLSTATES.put(ResultCode.NO_SUCH_SESSION_VARIABLE, "62T02"); SQLSTATES.put(ResultCode.INVALID_SESSION_VARIABLE, "62T03"); // Data Exception (SQLState Class - 22) SQLSTATES.put(ResultCode.DIVISION_BY_ZERO, "22012"); SQLSTATES.put(ResultCode.INVALID_VALUE_FOR_CAST, "22T01"); // Section: Class 42 - Syntax Error or Access Rule Violation SQLSTATES.put(ResultCode.SYNTAX_ERROR, "42601"); SQLSTATES.put(ResultCode.UNDEFINED_DATABASE, "42T01"); SQLSTATES.put(ResultCode.UNDEFINED_SCHEMA, "42T02"); SQLSTATES.put(ResultCode.UNDEFINED_TABLE, "42P01"); SQLSTATES.put(ResultCode.UNDEFINED_COLUMN, "42703"); SQLSTATES.put(ResultCode.UNDEFINED_FUNCTION, "42883"); SQLSTATES.put(ResultCode.UNDEFINED_INDEX_FOR_TABLE, "42T03"); SQLSTATES.put(ResultCode.UNDEFINED_INDEX_FOR_COLUMNS, "42T04"); SQLSTATES.put(ResultCode.UNDEFINED_PARTITION, "42T05"); SQLSTATES.put(ResultCode.UNDEFINED_PARTITION_METHOD, "42T06"); SQLSTATES.put(ResultCode.UNDEFINED_OPERATOR, "42883"); // == UNDEFINED_FUNCTION SQLSTATES.put(ResultCode.UNDEFINED_PARTITION_KEY, "42T07"); SQLSTATES.put(ResultCode.UNDEFINED_TABLESPACE_HANDLER, "42T11"); SQLSTATES.put(ResultCode.DUPLICATE_TABLESPACE, "42T08"); SQLSTATES.put(ResultCode.DUPLICATE_DATABASE, "42P04"); SQLSTATES.put(ResultCode.DUPLICATE_SCHEMA, "42P06"); SQLSTATES.put(ResultCode.DUPLICATE_TABLE, "42P07"); SQLSTATES.put(ResultCode.DUPLICATE_COLUMN, "42701"); SQLSTATES.put(ResultCode.DUPLICATE_ALIAS, "42712"); SQLSTATES.put(ResultCode.DUPLICATE_FUNCTION, "42723"); SQLSTATES.put(ResultCode.DUPLICATE_INDEX, "42710"); SQLSTATES.put(ResultCode.DUPLICATE_PARTITION, "42T09"); SQLSTATES.put(ResultCode.AMBIGUOUS_TABLE, "42723"); SQLSTATES.put(ResultCode.AMBIGUOUS_COLUMN, "42723"); SQLSTATES.put(ResultCode.AMBIGUOUS_FUNCTION, "42723"); SQLSTATES.put(ResultCode.AMBIGUOUS_PARTITION_DIRECTORY, "42T10"); SQLSTATES.put(ResultCode.CANNOT_CAST, "42846"); SQLSTATES.put(ResultCode.GROUPING_ERROR, "42803"); SQLSTATES.put(ResultCode.WINDOWING_ERROR, "42P20"); SQLSTATES.put(ResultCode.INVALID_RECURSION, "42P19"); SQLSTATES.put(ResultCode.SET_OPERATION_SCHEMA_MISMATCH, "42601"); SQLSTATES.put(ResultCode.SET_OPERATION_DATATYPE_MISMATCH, "42601"); SQLSTATES.put(ResultCode.INVALID_FOREIGN_KEY, "42830"); SQLSTATES.put(ResultCode.INVALID_NAME, "42602"); SQLSTATES.put(ResultCode.INVALID_COLUMN_DEFINITION, "42611"); SQLSTATES.put(ResultCode.NAME_TOO_LONG, "42622"); SQLSTATES.put(ResultCode.RESERVED_NAME, "42939"); SQLSTATES.put(ResultCode.DATATYPE_MISMATCH, "42804"); SQLSTATES.put(ResultCode.INDETERMINATE_DATATYPE, "42P18"); // Client Connection SQLSTATES.put(ResultCode.CLIENT_CONNECTION_EXCEPTION, "08000"); SQLSTATES.put(ResultCode.CLIENT_CONNECTION_DOES_NOT_EXIST, "08003"); SQLSTATES.put(ResultCode.CLIENT_UNABLE_TO_ESTABLISH_CONNECTION, "08006"); } public static boolean isThisError(SQLException e, ResultCode code) { if (SQLSTATES.containsKey(code)) { return e.getSQLState().equals(SQLSTATES.get(code)); } else { throw new TajoInternalError("Unknown error code: " + code.name()); } } public static void throwIfError(ReturnState state) throws SQLException { if (isError(state)) { throw toSQLException(state); } } private static SQLException toSQLException(ResultCode code, String message) throws SQLException { if (SQLSTATES.containsKey(code)) { return new SQLException( message, SQLSTATES.get(code), code.getNumber() ); } else { // If there is no SQLState corresponding to error code, // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). return new SQLException( message, "42000", ResultCode.SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION_VALUE ); } } public static String toSQLState(ResultCode code) { if (SQLSTATES.containsKey(code)) { return SQLSTATES.get(code); } else { return "42000"; } } public static SQLException toSQLException(DefaultTajoException e) throws SQLException { if (e instanceof TajoRuntimeException) { return toSQLException(e.getErrorCode(), ((TajoRuntimeException) e).getCause().getMessage()); } else { return toSQLException(e.getErrorCode(), e.getMessage()); } } public static SQLException toSQLException(ReturnState state) throws SQLException { return toSQLException(state.getReturnCode(), state.getMessage()); } public static SQLException makeSQLException(ResultCode code, String ...args) { if (SQLSTATES.containsKey(code)) { return new SQLException( ErrorMessages.getMessage(code, args), SQLSTATES.get(code), code.getNumber()); } else { // If there is no SQLState corresponding to error code, // It will make SQLState '42000' (Syntax Error Or Access Rule Violation). return new SQLException( code.name(), "42000", code.getNumber()); } } public static SQLException makeUnableToEstablishConnection(Throwable t) { return makeSQLException( ResultCode.CLIENT_UNABLE_TO_ESTABLISH_CONNECTION, t.getMessage()); } }