Unverified 提交 57734d02 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1399 from katzyn/exception

Add more subclases of SQLException and use it for some error codes
...@@ -533,9 +533,8 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -533,9 +533,8 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Long running transactions: log session id when detected. </li><li>Long running transactions: log session id when detected.
</li><li>Optimization: "select id from test" should use the index on id even without "order by". </li><li>Optimization: "select id from test" should use the index on id even without "order by".
</li><li>Sybase SQL Anywhere compatibility: SELECT TOP ... START AT ... </li><li>Sybase SQL Anywhere compatibility: SELECT TOP ... START AT ...
</li><li>Use Java 6 SQLException subclasses. </li><li>Use Java 6 SQLException subclasses for more kinds of errors.
</li><li>Issue 390: RUNSCRIPT FROM '...' CONTINUE_ON_ERROR </li><li>Issue 390: RUNSCRIPT FROM '...' CONTINUE_ON_ERROR
</li><li>Use Java 6 exceptions: SQLDataException, SQLSyntaxErrorException, SQLTimeoutException,..
</li></ul> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
...@@ -7,6 +7,7 @@ package org.h2.engine; ...@@ -7,6 +7,7 @@ package org.h2.engine;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
...@@ -15,7 +16,7 @@ import org.h2.api.JavaObjectSerializer; ...@@ -15,7 +16,7 @@ import org.h2.api.JavaObjectSerializer;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.command.CommandRemote; import org.h2.command.CommandRemote;
import org.h2.command.dml.SetTypes; import org.h2.command.dml.SetTypes;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
...@@ -337,8 +338,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -337,8 +338,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
DbException e = DbException.convert(re); DbException e = DbException.convert(re);
if (e.getErrorCode() == ErrorCode.DATABASE_ALREADY_OPEN_1) { if (e.getErrorCode() == ErrorCode.DATABASE_ALREADY_OPEN_1) {
if (autoServerMode) { if (autoServerMode) {
String serverKey = ((JdbcSQLException) e.getSQLException()). String serverKey = ((JdbcException) e.getSQLException()).getSQL();
getSQL();
if (serverKey != null) { if (serverKey != null) {
backup.setServerKey(serverKey); backup.setServerKey(serverKey);
// OPEN_NEW must be removed now, otherwise // OPEN_NEW must be removed now, otherwise
...@@ -604,8 +604,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -604,8 +604,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
String sql = transfer.readString(); String sql = transfer.readString();
int errorCode = transfer.readInt(); int errorCode = transfer.readInt();
String stackTrace = transfer.readString(); String stackTrace = transfer.readString();
JdbcSQLException s = new JdbcSQLException(message, sql, sqlstate, SQLException s = DbException.getJdbcSQLException(message, sql, sqlstate, errorCode, null, stackTrace);
errorCode, null, stackTrace);
if (errorCode == ErrorCode.CONNECTION_BROKEN_1) { if (errorCode == ErrorCode.CONNECTION_BROKEN_1) {
// allow re-connect // allow re-connect
throw new IOException(s.toString(), s); throw new IOException(s.toString(), s);
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
/**
* This interface contains additional methods for database exceptions.
*/
public interface JdbcException {
/**
* Returns the H2-specific error code.
*
* @return the H2-specific error code
*/
public int getErrorCode();
/**
* INTERNAL
*/
String getOriginalMessage();
/**
* Returns the SQL statement.
* <p>
* SQL statements that contain '--hide--' are not listed.
* </p>
*
* @return the SQL statement
*/
String getSQL();
/**
* INTERNAL
*/
void setSQL(String sql);
/**
* Returns the class name, the message, and in the server mode, the stack
* trace of the server
*
* @return the string representation
*/
@Override
String toString();
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLDataException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLDataException extends SQLDataException implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLDataException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLDataException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
...@@ -9,23 +9,16 @@ import java.io.PrintStream; ...@@ -9,23 +9,16 @@ import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.engine.Constants; import org.h2.message.DbException;
/** /**
* Represents a database exception. * Represents a database exception.
*/ */
public class JdbcSQLException extends SQLException { public class JdbcSQLException extends SQLException implements JdbcException {
/**
* If the SQL statement contains this text, then it is never added to the
* SQL exception. Hiding the SQL statement may be important if it contains a
* passwords, such as a CREATE LINKED TABLE statement.
*/
public static final String HIDE_SQL = "--hide--";
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String originalMessage; private final String originalMessage;
private final Throwable cause;
private final String stackTrace; private final String stackTrace;
private String message; private String message;
private String sql; private String sql;
...@@ -44,131 +37,45 @@ public class JdbcSQLException extends SQLException { ...@@ -44,131 +37,45 @@ public class JdbcSQLException extends SQLException {
int errorCode, Throwable cause, String stackTrace) { int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode); super(message, state, errorCode);
this.originalMessage = message; this.originalMessage = message;
this.cause = cause;
this.stackTrace = stackTrace; this.stackTrace = stackTrace;
// setSQL() invokes buildMessage() by itself // setSQL() also generates message
setSQL(sql); setSQL(sql);
initCause(cause); initCause(cause);
} }
/**
* Get the detail error message.
*
* @return the message
*/
@Override @Override
public String getMessage() { public String getMessage() {
return message; return message;
} }
/** @Override
* INTERNAL
*/
public String getOriginalMessage() { public String getOriginalMessage() {
return originalMessage; return originalMessage;
} }
/**
* Prints the stack trace to the standard error stream.
*/
@Override
public void printStackTrace() {
// The default implementation already does that,
// but we do it again to avoid problems.
// If it is not implemented, somebody might implement it
// later on which would be a problem if done in the wrong way.
printStackTrace(System.err);
}
/**
* Prints the stack trace to the specified print writer.
*
* @param s the print writer
*/
@Override @Override
public void printStackTrace(PrintWriter s) { public void printStackTrace(PrintWriter s) {
if (s != null) {
super.printStackTrace(s); super.printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow DbException.printNextExceptions(this, s);
// if many exceptions are joined
SQLException next = getNextException();
for (int i = 0; i < 100 && next != null; i++) {
s.println(next.toString());
next = next.getNextException();
}
if (next != null) {
s.println("(truncated)");
}
}
} }
/**
* Prints the stack trace to the specified print stream.
*
* @param s the print stream
*/
@Override @Override
public void printStackTrace(PrintStream s) { public void printStackTrace(PrintStream s) {
if (s != null) {
super.printStackTrace(s); super.printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow DbException.printNextExceptions(this, s);
// if many exceptions are joined
SQLException next = getNextException();
for (int i = 0; i < 100 && next != null; i++) {
s.println(next.toString());
next = next.getNextException();
}
if (next != null) {
s.println("(truncated)");
}
}
} }
/** @Override
* INTERNAL
*/
public Throwable getOriginalCause() {
return cause;
}
/**
* Returns the SQL statement.
* SQL statements that contain '--hide--' are not listed.
*
* @return the SQL statement
*/
public String getSQL() { public String getSQL() {
return sql; return sql;
} }
/** @Override
* INTERNAL
*/
public void setSQL(String sql) { public void setSQL(String sql) {
if (sql != null && sql.contains(HIDE_SQL)) {
sql = "-";
}
this.sql = sql; this.sql = sql;
buildMessage(); message = DbException.buildMessageForException(this);
} }
private void buildMessage() {
StringBuilder buff = new StringBuilder(originalMessage == null ?
"- " : originalMessage);
if (sql != null) {
buff.append("; SQL statement:\n").append(sql);
}
buff.append(" [").append(getErrorCode()).
append('-').append(Constants.BUILD_ID).append(']');
message = buff.toString();
}
/**
* Returns the class name, the message, and in the server mode, the stack
* trace of the server
*
* @return the string representation
*/
@Override @Override
public String toString() { public String toString() {
if (stackTrace == null) { if (stackTrace == null) {
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLFeatureNotSupportedException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLFeatureNotSupportedException extends SQLFeatureNotSupportedException implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLFeatureNotSupportedException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLFeatureNotSupportedException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLIntegrityConstraintViolationException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLIntegrityConstraintViolationException extends SQLIntegrityConstraintViolationException
implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLIntegrityConstraintViolationException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLIntegrityConstraintViolationException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLInvalidAuthorizationSpecException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLInvalidAuthorizationSpecException extends SQLInvalidAuthorizationSpecException
implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLInvalidAuthorizationSpecException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLInvalidAuthorizationSpecException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLNonTransientConnectionException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLNonTransientConnectionException extends SQLNonTransientConnectionException
implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLNonTransientConnectionException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLNonTransientConnectionException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLSyntaxErrorException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLSyntaxErrorException extends SQLSyntaxErrorException implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLSyntaxErrorException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLSyntaxErrorException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.jdbc;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.SQLTransactionRollbackException;
import org.h2.message.DbException;
/**
* Represents a database exception.
*/
public class JdbcSQLTransactionRollbackException extends SQLTransactionRollbackException implements JdbcException {
private static final long serialVersionUID = 1L;
private final String originalMessage;
private final String stackTrace;
private String message;
private String sql;
/**
* Creates a SQLTransactionRollbackException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public JdbcSQLTransactionRollbackException(String message, String sql, String state,
int errorCode, Throwable cause, String stackTrace) {
super(message, state, errorCode);
this.originalMessage = message;
this.stackTrace = stackTrace;
// setSQL() also generates message
setSQL(sql);
initCause(cause);
}
@Override
public String getMessage() {
return message;
}
@Override
public String getOriginalMessage() {
return originalMessage;
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
DbException.printNextExceptions(this, s);
}
@Override
public String getSQL() {
return sql;
}
@Override
public void setSQL(String sql) {
this.sql = sql;
message = DbException.buildMessageForException(this);
}
@Override
public String toString() {
if (stackTrace == null) {
return super.toString();
}
return stackTrace;
}
}
...@@ -7,6 +7,7 @@ package org.h2.message; ...@@ -7,6 +7,7 @@ package org.h2.message;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
...@@ -17,7 +18,16 @@ import java.util.Locale; ...@@ -17,7 +18,16 @@ import java.util.Locale;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Properties; import java.util.Properties;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcException;
import org.h2.jdbc.JdbcSQLDataException;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcSQLException;
import org.h2.jdbc.JdbcSQLFeatureNotSupportedException;
import org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException;
import org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException;
import org.h2.jdbc.JdbcSQLNonTransientConnectionException;
import org.h2.jdbc.JdbcSQLSyntaxErrorException;
import org.h2.jdbc.JdbcSQLTransactionRollbackException;
import org.h2.util.SortedProperties; import org.h2.util.SortedProperties;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -31,6 +41,13 @@ public class DbException extends RuntimeException { ...@@ -31,6 +41,13 @@ public class DbException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* If the SQL statement contains this text, then it is never added to the
* SQL exception. Hiding the SQL statement may be important if it contains a
* passwords, such as a CREATE LINKED TABLE statement.
*/
public static final String HIDE_SQL = "--hide--";
private static final Properties MESSAGES = new Properties(); private static final Properties MESSAGES = new Properties();
public static final SQLException SQL_OOME = public static final SQLException SQL_OOME =
...@@ -125,15 +142,14 @@ public class DbException extends RuntimeException { ...@@ -125,15 +142,14 @@ public class DbException extends RuntimeException {
*/ */
public DbException addSQL(String sql) { public DbException addSQL(String sql) {
SQLException e = getSQLException(); SQLException e = getSQLException();
if (e instanceof JdbcSQLException) { if (e instanceof JdbcException) {
JdbcSQLException j = (JdbcSQLException) e; JdbcException j = (JdbcException) e;
if (j.getSQL() == null) { if (j.getSQL() == null) {
j.setSQL(sql); j.setSQL(filterSQL(sql));
} }
return this; return this;
} }
e = new JdbcSQLException(e.getMessage(), sql, e.getSQLState(), e = getJdbcSQLException(e.getMessage(), sql, e.getSQLState(), e.getErrorCode(), e, null);
e.getErrorCode(), e, null);
return new DbException(e); return new DbException(e);
} }
...@@ -191,7 +207,7 @@ public class DbException extends RuntimeException { ...@@ -191,7 +207,7 @@ public class DbException extends RuntimeException {
*/ */
public static DbException fromUser(String sqlstate, String message) { public static DbException fromUser(String sqlstate, String message) {
// do not translate as sqlstate is arbitrary : avoid "message not found" // do not translate as sqlstate is arbitrary : avoid "message not found"
return new DbException(new JdbcSQLException(message, null, sqlstate, 0, null, null)); return new DbException(getJdbcSQLException(message, null, sqlstate, 0, null, null));
} }
/** /**
...@@ -387,11 +403,58 @@ public class DbException extends RuntimeException { ...@@ -387,11 +403,58 @@ public class DbException extends RuntimeException {
* @param params the list of parameters of the message * @param params the list of parameters of the message
* @return the SQLException object * @return the SQLException object
*/ */
public static JdbcSQLException getJdbcSQLException(int errorCode, public static SQLException getJdbcSQLException(int errorCode, Throwable cause, String... params) {
Throwable cause, String... params) {
String sqlstate = ErrorCode.getState(errorCode); String sqlstate = ErrorCode.getState(errorCode);
String message = translate(sqlstate, params); String message = translate(sqlstate, params);
return new JdbcSQLException(message, null, sqlstate, errorCode, cause, null); return getJdbcSQLException(message, null, sqlstate, errorCode, cause, null);
}
/**
* Creates a SQLException.
*
* @param message the reason
* @param sql the SQL statement
* @param state the SQL state
* @param errorCode the error code
* @param cause the exception that was the reason for this exception
* @param stackTrace the stack trace
*/
public static SQLException getJdbcSQLException(String message, String sql, String state, int errorCode,
Throwable cause, String stackTrace) {
sql = filterSQL(sql);
// Use SQLState class value to detect type
switch (errorCode / 1_000) {
case 8:
return new JdbcSQLNonTransientConnectionException(message, sql, state, errorCode, cause, stackTrace);
case 22:
return new JdbcSQLDataException(message, sql, state, errorCode, cause, stackTrace);
case 23:
return new JdbcSQLIntegrityConstraintViolationException(message, sql, state, errorCode, cause, stackTrace);
case 28:
return new JdbcSQLInvalidAuthorizationSpecException(message, sql, state, errorCode, cause, stackTrace);
case 40:
return new JdbcSQLTransactionRollbackException(message, sql, state, errorCode, cause, stackTrace);
case 42:
return new JdbcSQLSyntaxErrorException(message, sql, state, errorCode, cause, stackTrace);
}
// Check error code
switch (errorCode){
case ErrorCode.FEATURE_NOT_SUPPORTED_1:
return new JdbcSQLFeatureNotSupportedException(message, sql, state, errorCode, cause, stackTrace);
case ErrorCode.HEX_STRING_ODD_1:
case ErrorCode.HEX_STRING_WRONG_1:
case ErrorCode.INVALID_VALUE_2:
case ErrorCode.PARSE_ERROR_1:
case ErrorCode.INVALID_TO_DATE_FORMAT:
case ErrorCode.STRING_FORMAT_ERROR_1:
return new JdbcSQLDataException(message, sql, state, errorCode, cause, stackTrace);
}
// Default
return new JdbcSQLException(message, sql, state, errorCode, cause, stackTrace);
}
private static String filterSQL(String sql) {
return sql == null || !sql.contains(HIDE_SQL) ? sql : "-";
} }
/** /**
...@@ -404,15 +467,69 @@ public class DbException extends RuntimeException { ...@@ -404,15 +467,69 @@ public class DbException extends RuntimeException {
if (e instanceof IOException) { if (e instanceof IOException) {
return (IOException) e; return (IOException) e;
} }
if (e instanceof JdbcSQLException) { if (e instanceof JdbcException) {
JdbcSQLException e2 = (JdbcSQLException) e; if (e.getCause() != null) {
if (e2.getOriginalCause() != null) { e = e.getCause();
e = e2.getOriginalCause();
} }
} }
return new IOException(e.toString(), e); return new IOException(e.toString(), e);
} }
/**
* Builds message for an exception.
*
* @param e exception
* @return message
*/
public static String buildMessageForException(JdbcException e) {
String s = e.getOriginalMessage();
StringBuilder buff = new StringBuilder(s != null ? s : "- ");
s = e.getSQL();
if (s != null) {
buff.append("; SQL statement:\n").append(s);
}
buff.append(" [").append(e.getErrorCode()).append('-').append(Constants.BUILD_ID).append(']');
return buff.toString();
}
/**
* Prints up to 100 next exceptions for a specified SQL exception.
*
* @param e SQL exception
* @param s print writer
*/
public static void printNextExceptions(SQLException e, PrintWriter s) {
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
int i = 0;
while ((e = e.getNextException()) != null) {
if (i++ == 100) {
s.println("(truncated)");
return;
}
s.println(e.toString());
}
}
/**
* Prints up to 100 next exceptions for a specified SQL exception.
*
* @param e SQL exception
* @param s print stream
*/
public static void printNextExceptions(SQLException e, PrintStream s) {
// getNextException().printStackTrace(s) would be very very slow
// if many exceptions are joined
int i = 0;
while ((e = e.getNextException()) != null) {
if (i++ == 100) {
s.println("(truncated)");
return;
}
s.println(e.toString());
}
}
public Object getSource() { public Object getSource() {
return source; return source;
} }
......
...@@ -13,7 +13,7 @@ import java.text.SimpleDateFormat; ...@@ -13,7 +13,7 @@ import java.text.SimpleDateFormat;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
...@@ -260,8 +260,8 @@ public class TraceSystem implements TraceWriter { ...@@ -260,8 +260,8 @@ public class TraceSystem implements TraceWriter {
} }
printWriter.println(s); printWriter.println(s);
if (t != null) { if (t != null) {
if (levelFile == ERROR && t instanceof JdbcSQLException) { if (levelFile == ERROR && t instanceof JdbcException) {
JdbcSQLException se = (JdbcSQLException) t; JdbcException se = (JdbcException) t;
int code = se.getErrorCode(); int code = se.getErrorCode();
if (ErrorCode.isCommon(code)) { if (ErrorCode.isCommon(code)) {
printWriter.println(t.toString()); printWriter.println(t.toString());
......
...@@ -28,7 +28,7 @@ import org.h2.engine.SysProperties; ...@@ -28,7 +28,7 @@ import org.h2.engine.SysProperties;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.expression.ParameterInterface; import org.h2.expression.ParameterInterface;
import org.h2.expression.ParameterRemote; import org.h2.expression.ParameterRemote;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.ResultColumn; import org.h2.result.ResultColumn;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
...@@ -235,8 +235,8 @@ public class TcpServerThread implements Runnable { ...@@ -235,8 +235,8 @@ public class TcpServerThread implements Runnable {
String trace = writer.toString(); String trace = writer.toString();
String message; String message;
String sql; String sql;
if (e instanceof JdbcSQLException) { if (e instanceof JdbcException) {
JdbcSQLException j = (JdbcSQLException) e; JdbcException j = (JdbcException) e;
message = j.getOriginalMessage(); message = j.getOriginalMessage();
sql = j.getSQL(); sql = j.getSQL();
} else { } else {
......
...@@ -42,7 +42,7 @@ import org.h2.bnf.context.DbSchema; ...@@ -42,7 +42,7 @@ import org.h2.bnf.context.DbSchema;
import org.h2.bnf.context.DbTableOrView; import org.h2.bnf.context.DbTableOrView;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.security.SHA256; import org.h2.security.SHA256;
import org.h2.tools.Backup; import org.h2.tools.Backup;
...@@ -935,8 +935,7 @@ public class WebApp { ...@@ -935,8 +935,7 @@ public class WebApp {
* @return the formatted error message * @return the formatted error message
*/ */
private String getLoginError(Exception e, boolean isH2) { private String getLoginError(Exception e, boolean isH2) {
if (e instanceof JdbcSQLException && if (e instanceof JdbcException && ((JdbcException) e).getErrorCode() == ErrorCode.CLASS_NOT_FOUND_1) {
((JdbcSQLException) e).getErrorCode() == ErrorCode.CLASS_NOT_FOUND_1) {
return "${text.login.driverNotFound}<br />" + getStackTrace(0, e, isH2); return "${text.login.driverNotFound}<br />" + getStackTrace(0, e, isH2);
} }
return getStackTrace(0, e, isH2); return getStackTrace(0, e, isH2);
......
...@@ -41,7 +41,6 @@ import org.h2.expression.ValueExpression; ...@@ -41,7 +41,6 @@ import org.h2.expression.ValueExpression;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.index.MetaIndex; import org.h2.index.MetaIndex;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.FileStore; import org.h2.mvstore.FileStore;
import org.h2.mvstore.MVStore; import org.h2.mvstore.MVStore;
...@@ -788,7 +787,7 @@ public class MetaTable extends Table { ...@@ -788,7 +787,7 @@ public class MetaTable extends Table {
} }
String sql = table.getCreateSQL(); String sql = table.getCreateSQL();
if (!admin) { if (!admin) {
if (sql != null && sql.contains(JdbcSQLException.HIDE_SQL)) { if (sql != null && sql.contains(DbException.HIDE_SQL)) {
// hide the password of linked tables // hide the password of linked tables
sql = "-"; sql = "-";
} }
......
...@@ -24,7 +24,6 @@ import org.h2.engine.UndoLogRecord; ...@@ -24,7 +24,6 @@ import org.h2.engine.UndoLogRecord;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.index.LinkedIndex; import org.h2.index.LinkedIndex;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.RowList; import org.h2.result.RowList;
...@@ -392,7 +391,7 @@ public class TableLink extends Table { ...@@ -392,7 +391,7 @@ public class TableLink extends Table {
if (readOnly) { if (readOnly) {
buff.append(" READONLY"); buff.append(" READONLY");
} }
buff.append(" /*").append(JdbcSQLException.HIDE_SQL).append("*/"); buff.append(" /*").append(DbException.HIDE_SQL).append("*/");
return buff.toString(); return buff.toString();
} }
......
...@@ -395,7 +395,8 @@ public class IntervalUtils { ...@@ -395,7 +395,8 @@ public class IntervalUtils {
* the value of all remaining fields * the value of all remaining fields
* @return string representation of the specified interval * @return string representation of the specified interval
*/ */
public static String intervalToString(IntervalQualifier qualifier, boolean negative, long leading, long remaining) { public static String intervalToString(IntervalQualifier qualifier, boolean negative, long leading, long remaining)
{
StringBuilder buff = new StringBuilder().append("INTERVAL "); StringBuilder buff = new StringBuilder().append("INTERVAL ");
buff.append('\''); buff.append('\'');
if (negative) { if (negative) {
...@@ -553,8 +554,8 @@ public class IntervalUtils { ...@@ -553,8 +554,8 @@ public class IntervalUtils {
case MONTH: case MONTH:
return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute), 0); return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute), 0);
case DAY: case DAY:
return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute.divide(NANOS_PER_DAY_BI)), return ValueInterval.from(qualifier, absolute.signum() < 0,
0); leadingExact(absolute.divide(NANOS_PER_DAY_BI)), 0);
case HOUR: case HOUR:
return ValueInterval.from(qualifier, absolute.signum() < 0, return ValueInterval.from(qualifier, absolute.signum() < 0,
leadingExact(absolute.divide(NANOS_PER_HOUR_BI)), 0); leadingExact(absolute.divide(NANOS_PER_HOUR_BI)), 0);
...@@ -696,7 +697,8 @@ public class IntervalUtils { ...@@ -696,7 +697,8 @@ public class IntervalUtils {
* values of all remaining fields * values of all remaining fields
* @return months, or 0 * @return months, or 0
*/ */
public static long monthsFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining) { public static long monthsFromInterval(IntervalQualifier qualifier, boolean negative, long leading, long remaining)
{
long v; long v;
if (qualifier == IntervalQualifier.MONTH) { if (qualifier == IntervalQualifier.MONTH) {
v = leading; v = leading;
......
...@@ -15,7 +15,6 @@ import java.sql.ResultSetMetaData; ...@@ -15,7 +15,6 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcSQLException;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.TestDb; import org.h2.test.TestDb;
...@@ -278,7 +277,7 @@ public class TestCompatibility extends TestDb { ...@@ -278,7 +277,7 @@ public class TestCompatibility extends TestDb {
try { try {
stat.execute("CREATE TABLE TEST(COL " + type + ")"); stat.execute("CREATE TABLE TEST(COL " + type + ")");
fail("Expect type " + type + " to not exist in PostgreSQL mode"); fail("Expect type " + type + " to not exist in PostgreSQL mode");
} catch (org.h2.jdbc.JdbcSQLException e) { } catch (SQLException e) {
/* Expected! */ /* Expected! */
} }
} }
...@@ -675,7 +674,7 @@ public class TestCompatibility extends TestDb { ...@@ -675,7 +674,7 @@ public class TestCompatibility extends TestDb {
try { try {
getConnection("compatibility;MODE=Unknown").close(); getConnection("compatibility;MODE=Unknown").close();
deleteDb("compatibility"); deleteDb("compatibility");
} catch (JdbcSQLException ex) { } catch (SQLException ex) {
assertEquals(ErrorCode.UNKNOWN_MODE_1, ex.getErrorCode()); assertEquals(ErrorCode.UNKNOWN_MODE_1, ex.getErrorCode());
return; return;
} }
......
...@@ -46,7 +46,6 @@ import org.h2.api.Aggregate; ...@@ -46,7 +46,6 @@ import org.h2.api.Aggregate;
import org.h2.api.AggregateFunction; import org.h2.api.AggregateFunction;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
...@@ -2023,12 +2022,12 @@ public class TestFunctions extends TestDb implements AggregateFunction { ...@@ -2023,12 +2022,12 @@ public class TestFunctions extends TestDb implements AggregateFunction {
conn.close(); conn.close();
} }
private void testAnnotationProcessorsOutput() throws SQLException { private void testAnnotationProcessorsOutput() {
try { try {
System.setProperty(TestAnnotationProcessor.MESSAGES_KEY, "WARNING,foo1|ERROR,foo2"); System.setProperty(TestAnnotationProcessor.MESSAGES_KEY, "WARNING,foo1|ERROR,foo2");
callCompiledFunction("test_annotation_processor_warn_and_error"); callCompiledFunction("test_annotation_processor_warn_and_error");
fail(); fail();
} catch (JdbcSQLException e) { } catch (SQLException e) {
assertEquals(ErrorCode.SYNTAX_ERROR_1, e.getErrorCode()); assertEquals(ErrorCode.SYNTAX_ERROR_1, e.getErrorCode());
assertContains(e.getMessage(), "foo1"); assertContains(e.getMessage(), "foo1");
assertContains(e.getMessage(), "foo2"); assertContains(e.getMessage(), "foo2");
......
...@@ -8,8 +8,8 @@ package org.h2.test.db; ...@@ -8,8 +8,8 @@ package org.h2.test.db;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.jdbc.JdbcSQLException;
import org.h2.test.TestAll; import org.h2.test.TestAll;
import org.h2.test.TestBase; import org.h2.test.TestBase;
...@@ -235,7 +235,7 @@ public class TestGeneralCommonTableQueries extends AbstractBaseForCommonTableExp ...@@ -235,7 +235,7 @@ public class TestGeneralCommonTableQueries extends AbstractBaseForCommonTableExp
rs = prep.executeQuery(); rs = prep.executeQuery();
fail("Temp view T1 was accessible after previous WITH statement finished "+ fail("Temp view T1 was accessible after previous WITH statement finished "+
"- but should not have been."); "- but should not have been.");
} catch (JdbcSQLException e) { } catch (SQLException e) {
// ensure the T1 table has been removed even without auto commit // ensure the T1 table has been removed even without auto commit
assertContains(e.getMessage(), "Table \"T1\" not found;"); assertContains(e.getMessage(), "Table \"T1\" not found;");
} }
......
...@@ -347,7 +347,7 @@ public class TestMergeUsing extends TestDb implements Trigger { ...@@ -347,7 +347,7 @@ public class TestMergeUsing extends TestDb implements Trigger {
try { try {
testMergeUsing(setupSQL, statementUnderTest, gatherResultsSQL, testMergeUsing(setupSQL, statementUnderTest, gatherResultsSQL,
expectedResultsSQL, expectedRowUpdateCount); expectedResultsSQL, expectedRowUpdateCount);
} catch (RuntimeException | org.h2.jdbc.JdbcSQLException e) { } catch (RuntimeException | SQLException e) {
if (!e.getMessage().contains(exceptionMessage)) { if (!e.getMessage().contains(exceptionMessage)) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -22,7 +22,6 @@ import java.util.concurrent.Executors; ...@@ -22,7 +22,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcSQLException;
import org.h2.test.TestAll; import org.h2.test.TestAll;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.TestDb; import org.h2.test.TestDb;
...@@ -372,9 +371,8 @@ public class TestMultiThread extends TestDb implements Runnable { ...@@ -372,9 +371,8 @@ public class TestMultiThread extends TestDb implements Runnable {
// ignore timeout exceptions, happens periodically when the // ignore timeout exceptions, happens periodically when the
// machine is really busy and it's not the thing we are // machine is really busy and it's not the thing we are
// trying to test // trying to test
if (!(ex.getCause() instanceof JdbcSQLException) if (!(ex.getCause() instanceof SQLException)
|| ((JdbcSQLException) ex.getCause()) || ((SQLException) ex.getCause()).getErrorCode() != ErrorCode.LOCK_TIMEOUT_1) {
.getErrorCode() != ErrorCode.LOCK_TIMEOUT_1) {
throw ex; throw ex;
} }
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
*/ */
package org.h2.test.db; package org.h2.test.db;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -14,7 +13,6 @@ import java.sql.Statement; ...@@ -14,7 +13,6 @@ import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.h2.jdbc.JdbcSQLException;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.TestDb; import org.h2.test.TestDb;
...@@ -124,7 +122,7 @@ public class TestSetCollation extends TestDb { ...@@ -124,7 +122,7 @@ public class TestSetCollation extends TestDb {
try { try {
getConnection(DB_NAME); getConnection(DB_NAME);
fail(); fail();
} catch (JdbcSQLException e) { } catch (SQLException e) {
// expected // expected
} finally { } finally {
config.collation = null; config.collation = null;
......
...@@ -10,8 +10,8 @@ import java.sql.PreparedStatement; ...@@ -10,8 +10,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.test.TestDb; import org.h2.test.TestDb;
...@@ -71,7 +71,7 @@ public class TestSynonymForTable extends TestDb { ...@@ -71,7 +71,7 @@ public class TestSynonymForTable extends TestDb {
stat.execute("CREATE OR REPLACE SYNONYM testsynonym FOR s1.backingtable"); stat.execute("CREATE OR REPLACE SYNONYM testsynonym FOR s1.backingtable");
stat.execute("DROP SCHEMA s1 CASCADE"); stat.execute("DROP SCHEMA s1 CASCADE");
assertThrows(JdbcSQLException.class, stat).execute("SELECT id FROM testsynonym"); assertThrows(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, stat).execute("SELECT id FROM testsynonym");
conn.close(); conn.close();
} }
...@@ -82,7 +82,7 @@ public class TestSynonymForTable extends TestDb { ...@@ -82,7 +82,7 @@ public class TestSynonymForTable extends TestDb {
stat.execute("DROP TABLE backingtable"); stat.execute("DROP TABLE backingtable");
// Backing table does not exist anymore. // Backing table does not exist anymore.
assertThrows(JdbcSQLException.class, stat).execute("SELECT id FROM testsynonym"); assertThrows(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, stat).execute("SELECT id FROM testsynonym");
// Synonym should be dropped as well // Synonym should be dropped as well
ResultSet synonyms = conn.createStatement().executeQuery( ResultSet synonyms = conn.createStatement().executeQuery(
...@@ -92,7 +92,7 @@ public class TestSynonymForTable extends TestDb { ...@@ -92,7 +92,7 @@ public class TestSynonymForTable extends TestDb {
// Reopening should work with dropped synonym // Reopening should work with dropped synonym
Connection conn2 = getConnection("synonym"); Connection conn2 = getConnection("synonym");
assertThrows(JdbcSQLException.class, stat).execute("SELECT id FROM testsynonym"); assertThrows(ErrorCode.OBJECT_CLOSED, stat).execute("SELECT id FROM testsynonym");
conn2.close(); conn2.close();
} }
...@@ -104,13 +104,13 @@ public class TestSynonymForTable extends TestDb { ...@@ -104,13 +104,13 @@ public class TestSynonymForTable extends TestDb {
stat.execute("DROP SYNONYM testsynonym"); stat.execute("DROP SYNONYM testsynonym");
// Synonym does not exist anymore. // Synonym does not exist anymore.
assertThrows(JdbcSQLException.class, stat).execute("SELECT id FROM testsynonym"); assertThrows(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, stat).execute("SELECT id FROM testsynonym");
// Dropping with "if exists" should succeed even if the synonym does not exist anymore. // Dropping with "if exists" should succeed even if the synonym does not exist anymore.
stat.execute("DROP SYNONYM IF EXISTS testsynonym"); stat.execute("DROP SYNONYM IF EXISTS testsynonym");
// Without "if exists" the command should fail if the synonym does not exist. // Without "if exists" the command should fail if the synonym does not exist.
assertThrows(JdbcSQLException.class, stat).execute("DROP SYNONYM testsynonym"); assertThrows(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, stat).execute("DROP SYNONYM testsynonym");
conn.close(); conn.close();
} }
...@@ -132,7 +132,8 @@ public class TestSynonymForTable extends TestDb { ...@@ -132,7 +132,8 @@ public class TestSynonymForTable extends TestDb {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE TABLE IF NOT EXISTS backingtable(id INT PRIMARY KEY)"); stat.execute("CREATE TABLE IF NOT EXISTS backingtable(id INT PRIMARY KEY)");
assertThrows(JdbcSQLException.class, stat).execute("CREATE OR REPLACE SYNONYM backingtable FOR backingtable"); assertThrows(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, stat)
.execute("CREATE OR REPLACE SYNONYM backingtable FOR backingtable");
conn.close(); conn.close();
} }
...@@ -194,7 +195,8 @@ public class TestSynonymForTable extends TestDb { ...@@ -194,7 +195,8 @@ public class TestSynonymForTable extends TestDb {
Connection conn = getConnection("synonym"); Connection conn = getConnection("synonym");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
assertThrows(JdbcSQLException.class, stat).execute("CREATE SYNONYM someSynonym FOR nonexistingTable"); assertThrows(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, stat)
.execute("CREATE SYNONYM someSynonym FOR nonexistingTable");
conn.close(); conn.close();
} }
...@@ -203,7 +205,8 @@ public class TestSynonymForTable extends TestDb { ...@@ -203,7 +205,8 @@ public class TestSynonymForTable extends TestDb {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE TABLE IF NOT EXISTS backingtable(id INT PRIMARY KEY)"); stat.execute("CREATE TABLE IF NOT EXISTS backingtable(id INT PRIMARY KEY)");
assertThrows(JdbcSQLException.class, stat).execute("CREATE SYNONYM backingtable FOR backingtable"); assertThrows(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, stat)
.execute("CREATE SYNONYM backingtable FOR backingtable");
conn.close(); conn.close();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论