提交 886d1c5c authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 dd4dd186
......@@ -248,7 +248,7 @@
<mkdir dir="docs/javadoc"/>
<javadoc
sourcepath="src/main"
packagenames="org.h2.jdbc.*,org.h2.jdbcx.*,org.h2.tools.*,org.h2.api.*"
packagenames="org.h2.jdbc.*,org.h2.jdbcx.*,org.h2.tools.*,org.h2.api.*,org.h2.constant.*"
doclet="org.h2.tools.doclet.Doclet"
docletpath="bin"
/>
......
......@@ -570,12 +570,16 @@ public class Select extends Query {
}
}
}
if (sort != null && !isQuickQuery && !isGroupQuery && (!distinct || isDistinctQuery)) {
if (sort != null && !isQuickQuery && !isGroupQuery) {
Index index = getSortIndex();
Index current = topTableFilter.getIndex();
if (index != null && (current.getIndexType().isScan() || current == index)) {
topTableFilter.setIndex(index);
sortUsingIndex = true;
if (!distinct || isDistinctQuery) {
// sort using index wouldn't work correctly for distinct result sets
// because it would break too early when limit is used
sortUsingIndex = true;
}
}
}
}
......
......@@ -27,10 +27,11 @@ public class JdbcBatchUpdateException extends BatchUpdateException {
* INTERNAL
*/
public void printStackTrace() {
super.printStackTrace();
if (getNextException() != null) {
getNextException().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);
}
/**
......
......@@ -55,7 +55,7 @@ import java.sql.SQLClientInfoException;
*/
public class JdbcConnection extends TraceObject implements Connection {
// TODO test: check if enough synchronization on jdbc objects
// TODO feature auto-reconnect on lost connection!
// TODO feature: auto-reconnect on lost connection
private String url;
private String user;
......
......@@ -61,17 +61,11 @@ public class JdbcSQLException extends SQLException {
* Prints the stack trace to the standard error stream.
*/
public void printStackTrace() {
super.printStackTrace();
//#ifdef JDK13
/*
if (cause != null) {
cause.printStackTrace();
}
*/
//#endif
if (getNextException() != null) {
getNextException().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);
}
/**
......@@ -89,8 +83,15 @@ public class JdbcSQLException extends SQLException {
}
*/
//#endif
if (getNextException() != null) {
getNextException().printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow
// 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)");
}
}
}
......@@ -110,8 +111,15 @@ public class JdbcSQLException extends SQLException {
}
*/
//#endif
if (getNextException() != null) {
getNextException().printStackTrace(s);
// getNextException().printStackTrace(s) would be very very slow
// 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)");
}
}
}
......
......@@ -31,9 +31,10 @@ import org.h2.message.Message;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.NetUtils;
/**
* A factory to create encrypted sockets. To generate new keystore, use the
* A factory to create encrypted sockets. To generate new keystore, use the
* SecureKeyStoreBuilder tool.
*/
public class SecureSocketFactory {
......@@ -42,7 +43,7 @@ public class SecureSocketFactory {
private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore";
private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
public static final String KEYSTORE_PASSWORD = "h2pass";
// TODO security / SSL: need a way to disable anonymous ssl
private static final boolean ENABLE_ANONYMOUS_SSL = true;
private static SecureSocketFactory factory;
......@@ -58,7 +59,7 @@ public class SecureSocketFactory {
}
return factory;
}
public Socket createSocket(InetAddress address, int port) throws IOException {
Socket socket = null;
//#ifdef JDK14
......@@ -80,7 +81,13 @@ public class SecureSocketFactory {
//#ifdef JDK14
setKeystore();
ServerSocketFactory f = SSLServerSocketFactory.getDefault();
SSLServerSocket secureSocket = (SSLServerSocket) f.createServerSocket(port);
SSLServerSocket secureSocket;
InetAddress bindAddress = NetUtils.getBindAddress();
if (bindAddress == null) {
secureSocket = (SSLServerSocket) f.createServerSocket(port);
} else {
secureSocket = (SSLServerSocket) f.createServerSocket(port, 0, bindAddress);
}
if (ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list);
......@@ -95,7 +102,7 @@ public class SecureSocketFactory {
private static byte[] getBytes(String hex) throws SQLException {
return ByteUtils.convertStringToBytes(hex);
}
private static byte[] getKeyStoreBytes(KeyStore store, String password) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
......@@ -105,16 +112,16 @@ public class SecureSocketFactory {
}
return bout.toByteArray();
}
public static KeyStore getKeyStore(String password) throws IOException {
try {
// The following source code can be re-generated when you have a keystore file.
// This code is (hopefully) more Java version independent than using keystores directly.
// See also: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4887561 (1.4.2 cannot read keystore written with 1.4.1)
// --- generated code start ---
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, password.toCharArray());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
store.load(null, password.toCharArray());
......@@ -133,8 +140,8 @@ public class SecureSocketFactory {
throw Message.convertToIOException(e);
}
}
private void setKeystore() throws IOException {
private void setKeystore() throws IOException {
Properties p = System.getProperties();
if (p.getProperty(KEYSTORE_KEY) == null) {
String fileName = FileUtils.getFileInUserHome(KEYSTORE);
......
......@@ -81,8 +81,8 @@ public class FtpServer implements Service {
}
}
public ServerSocket createDataSocket() throws IOException {
ServerSocket dataSocket = new ServerSocket(0);
public ServerSocket createDataSocket() throws SQLException {
ServerSocket dataSocket = NetUtils.createServerSocket(0, false);
return dataSocket;
}
......
......@@ -24,6 +24,7 @@ import org.h2.message.TraceSystem;
import org.h2.store.fs.FileSystem;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
import org.h2.util.NetUtils;
import org.h2.util.RandomUtils;
import org.h2.util.SortedProperties;
......@@ -52,7 +53,7 @@ public class FileLock {
private volatile ServerSocket socket;
private boolean locked;
private Trace trace;
// private java.nio.channels.FileLock fileLock;
public FileLock(TraceSystem traceSystem, int sleep) {
......@@ -267,7 +268,7 @@ public class FileLock {
}
try {
// 0 to use any free port
socket = new ServerSocket(0);
socket = NetUtils.createServerSocket(0, false);
int port = socket.getLocalPort();
properties.setProperty("ipAddress", ipAddress);
properties.setProperty("port", String.valueOf(port));
......@@ -323,6 +324,6 @@ public class FileLock {
} else {
throw Message.getSQLException(ErrorCode.UNSUPPORTED_LOCK_METHOD_1, method);
}
}
}
}
......@@ -712,43 +712,44 @@ public class MetaTable extends Table {
add(rows, new String[] { "EXCLUSIVE", database.getExclusiveSession() == null ? "FALSE" : "TRUE" });
add(rows, new String[] { "MODE", database.getMode().getName() });
add(rows, new String[] { "MULTI_THREADED", database.getMultiThreaded() ? "1" : "0"});
DiskFile dataFile = database.getDataFile();
if (dataFile != null) {
add(rows, new String[] { "CACHE_TYPE", dataFile.getCache().getTypeName() });
if (session.getUser().getAdmin()) {
add(rows, new String[]{"info.FILE_DISK_WRITE", "" + dataFile.getWriteCount()});
add(rows, new String[]{"info.FILE_DISK_READ", "" + dataFile.getReadCount()});
add(rows, new String[]{"info.FILE_INDEX_WRITE", "" + database.getIndexFile().getWriteCount()});
add(rows, new String[]{"info.FILE_INDEX_READ", "" + database.getIndexFile().getReadCount()});
}
}
add(rows, new String[]{"h2.allowBigDecimalExtensions", "" + SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS});
add(rows, new String[]{"h2.baseDir", "" + SysProperties.getBaseDir()});
add(rows, new String[]{"h2.check", "" + SysProperties.CHECK});
add(rows, new String[]{"h2.check2", "" + SysProperties.CHECK2});
add(rows, new String[]{"h2.clientTraceDirectory", SysProperties.CLIENT_TRACE_DIRECTORY});
add(rows, new String[]{"h2.defaultMaxMemoryUndo", "" + SysProperties.DEFAULT_MAX_MEMORY_UNDO});
add(rows, new String[]{"h2.emergencySpaceInitial", "" + SysProperties.EMERGENCY_SPACE_INITIAL});
add(rows, new String[]{"h2.emergencySpaceMin", "" + SysProperties.EMERGENCY_SPACE_MIN});
add(rows, new String[]{"h2.lobFilesInDirectories", "" + SysProperties.LOB_FILES_IN_DIRECTORIES});
add(rows, new String[]{"h2.lobFilesPerDirectory", "" + SysProperties.LOB_FILES_PER_DIRECTORY});
add(rows, new String[]{"h2.runFinalize", "" + SysProperties.runFinalize});
add(rows, new String[]{"h2.optimizeMinMax", "" + SysProperties.OPTIMIZE_MIN_MAX});
add(rows, new String[]{"h2.optimizeIn", "" + SysProperties.OPTIMIZE_IN});
add(rows, new String[]{"h2.redoBufferSize", "" + SysProperties.REDO_BUFFER_SIZE});
add(rows, new String[]{"h2.recompileAlways", "" + SysProperties.RECOMPILE_ALWAYS});
add(rows, new String[]{"h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE});
add(rows, new String[]{"h2.overflowExceptions", "" + SysProperties.OVERFLOW_EXCEPTIONS});
add(rows, new String[]{"h2.logAllErrors", "" + SysProperties.LOG_ALL_ERRORS});
add(rows, new String[]{"h2.logAllErrorsFile", "" + SysProperties.LOG_ALL_ERRORS_FILE});
add(rows, new String[]{"h2.serverCachedObjects", "" + SysProperties.SERVER_CACHED_OBJECTS});
add(rows, new String[]{"h2.serverResultSetFetchSize", "" + SysProperties.SERVER_RESULT_SET_FETCH_SIZE});
add(rows, new String[]{"h2.emergencySpaceInitial", "" + SysProperties.EMERGENCY_SPACE_INITIAL});
add(rows, new String[]{"h2.emergencySpaceMin", "" + SysProperties.EMERGENCY_SPACE_MIN});
add(rows, new String[]{"h2.maxFileRetry", "" + SysProperties.MAX_FILE_RETRY});
add(rows, new String[]{"h2.lobCloseBetweenReads", "" + SysProperties.lobCloseBetweenReads});
add(rows, new String[]{"h2.objectCache", "" + SysProperties.OBJECT_CACHE});
add(rows, new String[]{"h2.objectCacheSize", "" + SysProperties.OBJECT_CACHE_SIZE});
add(rows, new String[]{"h2.objectCacheMaxPerElementSize", "" + SysProperties.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE});
add(rows, new String[]{"h2.clientTraceDirectory", SysProperties.CLIENT_TRACE_DIRECTORY});
add(rows, new String[]{"h2.optimizeIn", "" + SysProperties.OPTIMIZE_IN});
add(rows, new String[]{"h2.optimizeInJoin", "" + SysProperties.OPTIMIZE_IN_JOIN});
add(rows, new String[]{"h2.optimizeMinMax", "" + SysProperties.OPTIMIZE_MIN_MAX});
add(rows, new String[]{"h2.optimizeSubqueryCache", "" + SysProperties.OPTIMIZE_SUBQUERY_CACHE});
add(rows, new String[]{"h2.overflowExceptions", "" + SysProperties.OVERFLOW_EXCEPTIONS});
add(rows, new String[]{"h2.recompileAlways", "" + SysProperties.RECOMPILE_ALWAYS});
add(rows, new String[]{"h2.redoBufferSize", "" + SysProperties.REDO_BUFFER_SIZE});
add(rows, new String[]{"h2.runFinalize", "" + SysProperties.runFinalize});
add(rows, new String[]{"h2.scriptDirectory", SysProperties.scriptDirectory});
add(rows, new String[]{"h2.maxFileRetry", "" + SysProperties.MAX_FILE_RETRY});
add(rows, new String[]{"h2.lobCloseBetweenReads", "" + SysProperties.lobCloseBetweenReads});
add(rows, new String[]{"h2.allowBigDecimalExtensions", "" + SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS});
add(rows, new String[]{"h2.baseDir", "" + SysProperties.getBaseDir()});
add(rows, new String[]{"h2.defaultMaxMemoryUndo", "" + SysProperties.DEFAULT_MAX_MEMORY_UNDO});
add(rows, new String[]{"h2.serverCachedObjects", "" + SysProperties.SERVER_CACHED_OBJECTS});
add(rows, new String[]{"h2.serverResultSetFetchSize", "" + SysProperties.SERVER_RESULT_SET_FETCH_SIZE});
DiskFile dataFile = database.getDataFile();
if (dataFile != null) {
add(rows, new String[] { "CACHE_TYPE", dataFile.getCache().getTypeName() });
if (session.getUser().getAdmin()) {
add(rows, new String[]{"info.FILE_DISK_WRITE", "" + dataFile.getWriteCount()});
add(rows, new String[]{"info.FILE_DISK_READ", "" + dataFile.getReadCount()});
add(rows, new String[]{"info.FILE_INDEX_WRITE", "" + database.getIndexFile().getWriteCount()});
add(rows, new String[]{"info.FILE_INDEX_READ", "" + database.getIndexFile().getReadCount()});
}
}
break;
}
case TYPE_INFO: {
......
......@@ -9,9 +9,11 @@ import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
import org.h2.security.SecureSocketFactory;
......@@ -20,6 +22,8 @@ import org.h2.security.SecureSocketFactory;
*/
public class NetUtils {
private static InetAddress bindAddress;
public static Socket createLoopbackSocket(int port, boolean ssl) throws IOException {
return createSocket("127.0.0.1", port, ssl);
}
......@@ -58,15 +62,37 @@ public class NetUtils {
}
}
/**
* Get the bind address if the system property h2.bindAddress is set, or
* null if not.
*
* @return the bind address
*/
public static InetAddress getBindAddress() throws UnknownHostException {
String host = SysProperties.BIND_ADDRESS;
if (host == null || host.length() == 0) {
return null;
}
synchronized (NetUtils.class) {
if (bindAddress == null) {
bindAddress = InetAddress.getByName(host);
}
}
return bindAddress;
}
private static ServerSocket createServerSocketTry(int port, boolean ssl) throws SQLException {
// TODO server sockets: maybe automatically open the next port if this is in use?
// TODO server sockets: maybe a parameter to allow anonymous ssl?
try {
if (ssl) {
SecureSocketFactory f = SecureSocketFactory.getInstance();
return f.createServerSocket(port);
} else {
return new ServerSocket(port);
InetAddress bindAddress = getBindAddress();
if (bindAddress == null) {
return new ServerSocket(port);
} else {
return new ServerSocket(port, 0, bindAddress);
}
}
} catch (BindException be) {
throw Message.getSQLException(ErrorCode.EXCEPTION_OPENING_PORT_2,
......
......@@ -11,7 +11,6 @@ import org.h2.server.TcpServer;
import org.h2.store.fs.FileSystemDisk;
import org.h2.test.db.TestAutoRecompile;
import org.h2.test.db.TestBackup;
import org.h2.test.db.TestBatchUpdates;
import org.h2.test.db.TestBigDb;
import org.h2.test.db.TestBigResult;
import org.h2.test.db.TestCases;
......@@ -49,6 +48,7 @@ import org.h2.test.db.TestTransaction;
import org.h2.test.db.TestTriggersConstraints;
import org.h2.test.db.TestTwoPhaseCommit;
import org.h2.test.db.TestView;
import org.h2.test.jdbc.TestBatchUpdates;
import org.h2.test.jdbc.TestCallableStatement;
import org.h2.test.jdbc.TestCancel;
import org.h2.test.jdbc.TestDataSource;
......@@ -149,16 +149,32 @@ java org.h2.test.TestAll timer
/*
staging.trace.db.gz
drop table logs;
CREATE TABLE Logs(id INT PRIMARY KEY, procid INT);
CREATE unique INDEX procIdx ON Logs(procid, id);
@LOOP 1000 INSERT INTO Logs VALUES(?, MOD(?, 100000));
ANALYZE SAMPLE_SIZE 0;
script nodata;
EXPLAIN SELECT id FROM Logs WHERE procid=2 AND id<100;
h2CallableStatementBatchTest.zip
h2-2007-12-27_test.zip
docs,
History:
The bind IP address can now be set when using multi-homed host (if multiple network adapters are available)
using the system property h2.bindAddress.
Batch update: Calling BatchUpdateException.printStackTrace() could result in out of memory. Fixed.
Create system property documentation from Javadocs.
allow queries as well in batch updates
CALL syntax should probably work for regular executeUpdate as well.
http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/callablestatement.html#1000220
-Djboss.bind.address=<ip_address>
-Dh2.bindAddress=...
Automatically switch source code before compiling
[echo] Java version is 1.6 but source code is switched to 1.4.
[echo] Run ant codeswitchJdk... first.
......@@ -487,7 +503,6 @@ Features of H2
new TestScript().runTest(this);
new TestAutoRecompile().runTest(this);
new TestBackup().runTest(this);
new TestBatchUpdates().runTest(this);
new TestBigDb().runTest(this);
new TestBigResult().runTest(this);
new TestCache().runTest(this);
......@@ -531,6 +546,7 @@ Features of H2
new TestPgServer().runTest(this);
// jdbc
new TestBatchUpdates().runTest(this);
new TestCallableStatement().runTest(this);
new TestCancel().runTest(this);
new TestDatabaseEventListener().runTest(this);
......
......@@ -66,20 +66,25 @@ public class TestOptimizations extends TestBase {
checkFalse(rs.next());
stat.execute("ANALYZE");
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE");
for (int i = 0; rs.next(); i++) {
for (int i = 0; i < 10; i++) {
check(rs.next());
check(i, rs.getInt(1));
}
checkFalse(rs.next());
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 5 OFFSET 2");
for (int i = 2; i < 7; i++) {
rs.next();
check(rs.next());
check(i, rs.getInt(1));
}
checkFalse(rs.next());
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 0 OFFSET 0 SAMPLE_SIZE 3");
// must have at least one row
check(rs.next());
for (int i = 0; i < 3; i++) {
rs.next();
check(i, rs.getInt(1));
rs.getInt(1);
if (i > 0 && !rs.next()) {
break;
}
}
checkFalse(rs.next());
conn.close();
......
......@@ -2,8 +2,10 @@
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.db;
package org.h2.test.jdbc;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
......@@ -36,6 +38,37 @@ public class TestBatchUpdates extends TestBase {
PreparedStatement prep;
public void test() throws Exception {
testException();
testCoffee();
}
private void testException() throws Exception {
deleteDb("batchUpdates");
Connection conn = getConnection("batchUpdates");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key)");
PreparedStatement prep = conn.prepareStatement("insert into test values(?)");
for (int i = 0; i < 700; i++) {
prep.setString(1, "x");
prep.addBatch();
}
try {
prep.executeBatch();
} catch (BatchUpdateException e) {
PrintStream temp = System.err;
try {
ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream p = new PrintStream(buff);
System.setErr(p);
e.printStackTrace();
} finally {
System.setErr(temp);
}
}
conn.close();
}
private void testCoffee() throws Exception {
deleteDb("batchUpdates");
this.conn = getConnection("batchUpdates");
stat = conn.createStatement();
......
......@@ -36,4 +36,5 @@ To call getFD().sync() (which results in the OS call fsync()),
set the system property derby.storage.fileSyncTransactionLog to true true.
See
http://db.apache.org/derby/javadoc/engine/org/apache/derby/iapi/reference/Property.html#FILESYNC_TRANSACTION_LOG
Missing features:
LIMIT OFFSET is not supported.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论