提交 f1e33e82 authored 作者: Thomas Mueller's avatar Thomas Mueller

Invalid database names are now detected and a better error message is thrown.

上级 4d710ddd
......@@ -16,7 +16,7 @@ public class ErrorCode {
* The error with code <code>2000</code> is thrown when
* the result set is positioned before the first or after the last row, or
* not on a valid row for the given operation.
* Example:
* Example of wrong usage:
* <pre>
* ResultSet rs = stat.executeQuery("SELECT * FROM DUAL");
* rs.getString(1);
......@@ -343,7 +343,7 @@ public class ErrorCode {
/**
* The error with code <code>90003</code> is thrown when
* trying to convert a String to a binary value. Two hex digits
* per byte are required. Example:
* per byte are required. Example of wrong usage:
* <pre>
* CALL X'00023';
* Hexadecimal string with odd number of characters: 00023
......@@ -485,7 +485,7 @@ public class ErrorCode {
* The error with code <code>90016</code> is thrown when
* a column was used in the expression list or the order by clause
* of a group or aggregate query, and that column is not in the GROUP BY clause.
* Example:
* Example of wrong usage:
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
......@@ -517,7 +517,7 @@ public class ErrorCode {
* closed automatically, but relying on the finalizer is not good practice
* as it is not guaranteed and behavior is virtual machine dependent. The
* application should close the connection. This exception only appears in
* the .trace.db file. Example:
* the .trace.db file. Example of wrong usage:
* <pre>
* Connection conn;
* conn = DriverManager.getConnection(&quot;jdbc:h2:&tilde;/test&quot;);
......@@ -835,7 +835,7 @@ public class ErrorCode {
* the user password. A single space needs to be added between the file
* password and the user password; the file password itself may not contain
* spaces. File passwords (as well as user passwords) are case sensitive.
* Example:
* Example of wrong usage:
* <pre>
* String url = &quot;jdbc:h2:&tilde;/test;CIPHER=AES&quot;;
* String passwords = &quot;filePasswordUserPassword&quot;;
......@@ -865,7 +865,7 @@ public class ErrorCode {
/**
* The error with code <code>90052</code> is thrown when
* a subquery that is used as a value contains more than one column.
* Example:
* Example of wrong usage:
* <pre>
* CREATE TABLE TEST(ID INT);
* INSERT INTO TEST VALUES(1), (2);
......@@ -1054,6 +1054,7 @@ public class ErrorCode {
* expression that is used in the ORDER BY is not in the result list. This
* is required for distinct queries, otherwise the result would be
* ambiguous.
* Example of wrong usage:
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* INSERT INTO TEST VALUES(2, 'Hello'), (1, 'Hello');
......@@ -1111,7 +1112,8 @@ public class ErrorCode {
/**
* The error with code <code>90073</code> is thrown when trying to create
* an alias for a Java method, if two methods exists in this class that have
* this name and the same number of parameters. Example:
* this name and the same number of parameters.
* Example of wrong usage:
* <pre>
* CREATE ALIAS GET_LONG FOR
* "java.lang.Long.getLong";
......@@ -1250,6 +1252,7 @@ public class ErrorCode {
* The error with code <code>90085</code> is thrown when trying to
* manually drop an index that was generated by the system because of a
* unique constraint.
* Example of wrong usage:
* <pre>
* CREATE TABLE TEST(ID INT, CONSTRAINT UID UNIQUE(ID));
* DROP INDEX UID_INDEX_0;
......@@ -1298,7 +1301,7 @@ public class ErrorCode {
* trying to change the collation while there was already data in
* the database. The collation of the database must be set when the
* database is empty.
* Example:
* Example of wrong usage:
* <pre>
* CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
* INSERT INTO TEST VALUES('Hello', 'World');
......@@ -1424,7 +1427,7 @@ public class ErrorCode {
/**
* The error with code <code>90102</code> is thrown when
* trying to use unsupported options for the given compression algorithm.
* Example:
* Example of wrong usage:
* <pre>
* CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 10');
* </pre>
......@@ -1668,6 +1671,7 @@ public class ErrorCode {
* with object that extends the class BigDecimal, and the system property
* h2.allowBigDecimalExtensions is not set. Using extensions of BigDecimal is
* dangerous because the database relies on the behavior of BigDecimal.
* Example of wrong usage:
* <pre>
* BigDecimal bd = new MyDecimal("$10.3");
* prep.setBigDecimal(1, bd);
......@@ -1725,7 +1729,8 @@ public class ErrorCode {
* The error with code <code>90130</code> is thrown when
* an execute method of PreparedStatement was called with a SQL statement.
* This is not allowed according to the JDBC specification. Instead, use
* an execute method of Statement. Example:
* an execute method of Statement.
* Example of wrong usage:
* <pre>
* PreparedStatement prep = conn.prepareStatement("SELECT * FROM TEST");
* prep.execute("DELETE FROM TEST");
......@@ -1811,8 +1816,29 @@ public class ErrorCode {
* </pre>
*/
public static final int CAN_ONLY_ASSIGN_TO_VARIABLE_1 = 90137;
/**
* The error with code <code>90138</code> is thrown when
*
* trying to open a persistent database using an incorrect database name.
* The name of a persistent database contains the path and file name prefix
* where the data is stored. The file name part of a database name must be
* at least two characters.
*
* Example of wrong usage:
* <pre>
* DriverManager.getConnection("jdbc:h2:~/t");
* DriverManager.getConnection("jdbc:h2:~/test/");
* </pre>
* Correct:
* <pre>
* DriverManager.getConnection("jdbc:h2:~/te");
* DriverManager.getConnection("jdbc:h2:~/test/te");
* </pre>
*/
public static final int INVALID_DATABASE_NAME_1 = 90138;
// next is 90138
// next is 90139
private ErrorCode() {
// utility class
......
......@@ -291,6 +291,10 @@ public class ConnectionInfo {
String getName() throws SQLException {
if (persistent) {
String n = FileUtils.normalize(name + Constants.SUFFIX_DATA_FILE);
String fileName = FileUtils.getFileName(n);
if (fileName.length() < Constants.SUFFIX_DATA_FILE.length() + 2) {
throw Message.getSQLException(ErrorCode.INVALID_DATABASE_NAME_1, name);
}
n = n.substring(0, n.length() - Constants.SUFFIX_DATA_FILE.length());
return FileUtils.normalize(n);
}
......
......@@ -40,8 +40,6 @@ public class Engine {
}
private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) throws SQLException {
// may not remove properties here, otherwise they are lost
// if it is required to call it twice
String name = ci.getName();
Database database;
if (ci.isUnnamedInMemory()) {
......
......@@ -159,6 +159,7 @@
90135=Die Datenbank befindet sich im Exclusiv Modus; es k\u00F6nnen keine zus\u00E4tzlichen Verbindungen ge\u00F6ffnet werden
90136=Diese Outer Join Bedingung wird nicht unterst\u00FCtzt\: {0}
90137=Werte k\u00F6nnen nur einer Variablen zugewiesen werden, nicht an\: {0}
90138=Ung\u00FCltiger Datenbank Name\: {0}
HY000=Allgemeiner Fehler\: {0}
HY004=Unbekannter Datentyp\: {0}
HYC00=Dieses Feature wird unterst\u00FCtzt
......
......@@ -159,6 +159,7 @@
90135=The database is open in exclusive mode; can not open additional connections
90136=Unsupported outer join condition\: {0}
90137=Can only assign to a variable, not to\: {0}
90138=Invalid database name\: {0}
HY000=General error\: {0}
HY004=Unknown data type\: {0}
HYC00=Feature not supported
......
......@@ -159,6 +159,7 @@
90135=\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306F\u6392\u4ED6\u30E2\u30FC\u30C9\u3067\u30AA\u30FC\u30D7\u30F3\u3055\u308C\u3066\u3044\u307E\u3059; \u63A5\u7D9A\u3092\u8FFD\u52A0\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
90136=\u672A\u30B5\u30DD\u30FC\u30C8\u306E\u5916\u90E8\u7D50\u5408\u6761\u4EF6\: {0}
90137=\u5272\u308A\u5F53\u3066\u306F\u5909\u6570\u306B\u306E\u307F\u53EF\u80FD\u3067\u3059\u3002{0} \u306B\u306F\u3067\u304D\u307E\u305B\u3093
90138=\#Invalid database name\: {0}
HY000=\u4E00\u822C\u30A8\u30E9\u30FC\: {0}
HY004=\u4E0D\u660E\u306A\u30C7\u30FC\u30BF\u578B\: {0}
HYC00=\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093
......
......@@ -159,6 +159,7 @@
90135=\#The database is open in exclusive mode; can not open additional connections
90136=\#Unsupported outer join condition\: {0}
90137=\#Can only assign to a variable, not to\: {0}
90138=\#Invalid database name\: {0}
HY000=Blad ogolny\: {0}
HY004=Nieznany typ danyche\: {0}
HYC00=Cecha nie jest wspierana
......
......@@ -159,6 +159,7 @@
90135=\#The database is open in exclusive mode; can not open additional connections
90136=\#Unsupported outer join condition\: {0}
90137=\#Can only assign to a variable, not to\: {0}
90138=\#Invalid database name\: {0}
HY000=Erro geral\: {0}
HY004=Tipo de dados desconhecido\: {0}
HYC00=Recurso n\u00E3o suportado
......
......@@ -300,7 +300,7 @@ public class FileSystemDisk extends FileSystem {
}
String fullFileName = normalize(name);
if (!fullFileName.startsWith(path)) {
throw Message.getInternalError("file utils error: " + fullFileName+" does not start with "+path);
throw Message.getInternalError("file utils error: " + fullFileName + " does not start with " + path);
}
String fileName = fullFileName.substring(path.length());
return fileName;
......
......@@ -18,6 +18,7 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.util.Random;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
/**
......@@ -26,6 +27,7 @@ import org.h2.test.TestBase;
public class TestCases extends TestBase {
public void test() throws Exception {
testInvalidDatabaseName();
testReuseSpace();
testDeleteGroup();
testDisconnect();
......@@ -55,6 +57,24 @@ public class TestCases extends TestBase {
testCollation();
}
private void testInvalidDatabaseName() throws Exception {
if (config.memory) {
return;
}
try {
getConnection("cases/");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.INVALID_DATABASE_NAME_1, e.getErrorCode());
}
try {
getConnection("cases/a");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.INVALID_DATABASE_NAME_1, e.getErrorCode());
}
}
private void testReuseSpace() throws Exception {
deleteDb("cases");
Connection conn = getConnection("cases");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论