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

--no commit message

--no commit message
上级 dd4dd186
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
<mkdir dir="docs/javadoc"/> <mkdir dir="docs/javadoc"/>
<javadoc <javadoc
sourcepath="src/main" 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" doclet="org.h2.tools.doclet.Doclet"
docletpath="bin" docletpath="bin"
/> />
......
...@@ -570,15 +570,19 @@ public class Select extends Query { ...@@ -570,15 +570,19 @@ public class Select extends Query {
} }
} }
} }
if (sort != null && !isQuickQuery && !isGroupQuery && (!distinct || isDistinctQuery)) { if (sort != null && !isQuickQuery && !isGroupQuery) {
Index index = getSortIndex(); Index index = getSortIndex();
Index current = topTableFilter.getIndex(); Index current = topTableFilter.getIndex();
if (index != null && (current.getIndexType().isScan() || current == index)) { if (index != null && (current.getIndexType().isScan() || current == index)) {
topTableFilter.setIndex(index); topTableFilter.setIndex(index);
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; sortUsingIndex = true;
} }
} }
} }
}
public double getCost() { public double getCost() {
return cost; return cost;
......
package org.h2.constant;
import org.h2.engine.Constants;
/* /*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html). * Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.constant;
import org.h2.engine.Constants;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
/** /**
...@@ -21,58 +21,221 @@ import org.h2.message.TraceSystem; ...@@ -21,58 +21,221 @@ import org.h2.message.TraceSystem;
*/ */
public class SysProperties { public class SysProperties {
public static final String LINE_SEPARATOR = getStringSetting("line.separator", "\n"); /**
* The system property <code>file.encoding</code> (default: Cp1252).
* It is usually set by the system and is the default encoding used for the RunScript and CSV tool.
*/
public static final String FILE_ENCODING = getStringSetting("file.encoding", "Cp1252");
/**
* The system property <code>file.separator</code> (default: /).
* It is usually set by the system, and used to build absolute file names.
*/
public static final String FILE_SEPARATOR = getStringSetting("file.separator", "/"); public static final String FILE_SEPARATOR = getStringSetting("file.separator", "/");
/**
* The system property <code>line.separator</code> (default: \n).
* It is usually set by the system, and used by the script and trace tools.
*/
public static final String LINE_SEPARATOR = getStringSetting("line.separator", "\n");
/**
* The system property <code>user.home</code> (default: empty string).
* It is usually set by the system, and used as a replacement for ~ in file names.
*/
public static final String USER_HOME = getStringSetting("user.home", ""); public static final String USER_HOME = getStringSetting("user.home", "");
public static final String FILE_ENCODING = getStringSetting("file.encoding", "Cp1252");
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5); /**
* The system property <code>h2.allowBigDecimalExtensions</code> (default: false).
* When enabled, classes that extend BigDecimal are supported in PreparedStatement.setBigDecimal.
*/
public static final boolean ALLOW_BIG_DECIMAL_EXTENSIONS = getBooleanSetting("h2.allowBigDecimalExtensions", false);
/**
* The system property <code>h2.allowedClasses</code> (default: *).
* Comma separated list of class names or prefixes.
*/
public static final String ALLOWED_CLASSES = getStringSetting("h2.allowedClasses", "*");
public static final String BIND_ADDRESS = getStringSetting("h2.bindAddress", null);
public static final int CACHE_SIZE_DEFAULT = getIntSetting("h2.cacheSizeDefault", 16 * 1024);
public static final int CACHE_SIZE_INDEX_SHIFT = getIntSetting("h2.cacheSizeIndexShift", 3);
/**
* INTERNAL
*/
public static final int CACHE_SIZE_INDEX_DEFAULT = CACHE_SIZE_DEFAULT >> CACHE_SIZE_INDEX_SHIFT;
/**
* The system property <code>h2.check</code> (default: true).
* Assertions in the database engine.
*/
public static final boolean CHECK = getBooleanSetting("h2.check", true); public static final boolean CHECK = getBooleanSetting("h2.check", true);
/**
* The system property <code>h2.check2</code> (default: true).
* Additional assertions in the database engine.
*/
public static final boolean CHECK2 = getBooleanSetting("h2.check2", false); public static final boolean CHECK2 = getBooleanSetting("h2.check2", false);
/**
* The system property <code>h2.clientTraceDirectory</code> (default: trace.db/).
* Directory where the trace files of the JDBC client are stored (only for client / server).
*/
public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/");
/**
* The system property <code>h2.check2</code> (default: true).
* Additional assertions in the database engine.
*/
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
public static final int DATASOURCE_TRACE_LEVEL = getIntSetting("h2.dataSourceTraceLevel", TraceSystem.ERROR);
public static final int DEFAULT_MAX_MEMORY_UNDO = getIntSetting("h2.defaultMaxMemoryUndo", 100000);
public static final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED);
/**
* The system property <code>h2.emergencySpaceInitial</code> (default: 262144).
* Size of 'reserve' file to detect disk full problems early.
*/
public static final int EMERGENCY_SPACE_INITIAL = getIntSetting("h2.emergencySpaceInitial", 256 * 1024);
/**
* The system property <code>h2.emergencySpaceMin</code> (default: 65536).
* Minimum size of 'reserve' file.
*/
public static final int EMERGENCY_SPACE_MIN = getIntSetting("h2.emergencySpaceMin", 64 * 1024);
public static final boolean INDEX_LOOKUP_NEW = getBooleanSetting("h2.indexLookupNew", true);
/**
* The system property <code>h2.lobCloseBetweenReads</code> (default: false).
* Close LOB files between read operations.
*/
public static boolean lobCloseBetweenReads = getBooleanSetting("h2.lobCloseBetweenReads", false);
/**
* The system property <code>h2.lobFilesInDirectories</code> (default: false).
* Store LOB files in subdirectories.
*/
// TODO: also remove DataHandler.allocateObjectId, createTempFile when setting this to true and removing it
public static final boolean LOB_FILES_IN_DIRECTORIES = getBooleanSetting("h2.lobFilesInDirectories", false);
/**
* The system property <code>h2.lobFilesPerDirectory</code> (default: 256).
* Maximum number of LOB files per directory.
*/
public static final int LOB_FILES_PER_DIRECTORY = getIntSetting("h2.lobFilesPerDirectory", 256);
/**
* The system property <code>h2.logAllErrors</code> (default: false).
* Write stack traces of any kind of error to a file.
*/
public static final boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false);
/**
* The system property <code>h2.logAllErrorsFile</code> (default: h2errors.txt).
* File name to log errors.
*/
public static final String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt");
/**
* The system property <code>h2.maxFileRetry</code> (default: 16).
* Number of times to retry file delete and rename.
*/
public static final int MAX_FILE_RETRY = Math.max(1, getIntSetting("h2.maxFileRetry", 16));
public static final int MIN_COLUMN_NAME_MAP = getIntSetting("h2.minColumnNameMap", 3);
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
public static final boolean NEW_DISPLAY_SIZE = getBooleanSetting("h2.newDisplaySize", true);
/**
* The system property <code>h2.objectCache</code> (default: true).
* Cache commonly used objects (integers, strings).
*/
public static final boolean OBJECT_CACHE = getBooleanSetting("h2.objectCache", true);
/**
* The system property <code>h2.objectCacheMaxPerElementSize</code> (default: 4096).
* Maximum size of an object in the cache.
*/
public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = getIntSetting("h2.objectCacheMaxPerElementSize", 4096);
/**
* The system property <code>h2.objectCacheSize</code> (default: 1024).
* Maximum size of an object in the cache.
*/
public static final int OBJECT_CACHE_SIZE = getIntSetting("h2.objectCacheSize", 1024);
public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true);
/**
* The system property <code>h2.optimizeEvaluatableSubqueries</code> (default: true).
* Optimize subqueries that are not dependent on the outer query.
*/
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true); public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
/**
* The system property <code>h2.optimizeIn</code> (default: true).
* Optimize IN(...) comparisons.
*/
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
public static final boolean OPTIMIZE_IN_JOIN = getBooleanSetting("h2.optimizeInJoin", false); public static final boolean OPTIMIZE_IN_JOIN = getBooleanSetting("h2.optimizeInJoin", false);
public static final boolean OPTIMIZE_DISTINCT = getBooleanSetting("h2.optimizeDistinct", true); /**
* The system property <code>h2.optimizeMinMax</code> (default: true).
* Optimize MIN and MAX aggregate functions.
*/
public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true); public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
/**
* The system property <code>h2.optimizeSubqueryCache</code> (default: true).
* Cache subquery results.
*/
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true); public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true); public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true);
public static final boolean OPTIMIZE_TWO_EQUALS = getBooleanSetting("h2.optimizeTwoEquals", true); public static final boolean OPTIMIZE_TWO_EQUALS = getBooleanSetting("h2.optimizeTwoEquals", true);
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
public static final boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false); /**
* The system property <code>h2.overflowExceptions</code> (default: true).
* Throw an exception on integer overflows.
*/
public static final boolean OVERFLOW_EXCEPTIONS = getBooleanSetting("h2.overflowExceptions", true); public static final boolean OVERFLOW_EXCEPTIONS = getBooleanSetting("h2.overflowExceptions", true);
public static final boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false);
public static final String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt"); /**
* The system property <code>h2.recompileAlways</code> (default: false).
* Always recompile prepared statements.
*/
public static final boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false);
/**
* The system property <code>h2.redoBufferSize</code> (default: 262144).
* Size of the redo buffer (used at startup when recovering).
*/
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
/**
* The system property <code>h2.runFinalize</code> (default: true).
* Run finalizers to detect unclosed connections.
*/
public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true);
/**
* The system property <code>h2.scriptDirectory</code> (default: empty string).
* Relative or absolute directory where the script files are stored to or read from.
*/
public static String scriptDirectory = getStringSetting("h2.scriptDirectory", "");
/**
* The system property <code>h2.serverCachedObjects</code> (default: 64).
* TCP Server: number of cached objects per session.
*/
public static final int SERVER_CACHED_OBJECTS = getIntSetting("h2.serverCachedObjects", 64); public static final int SERVER_CACHED_OBJECTS = getIntSetting("h2.serverCachedObjects", 64);
/**
* The system property <code>h2.serverResultSetFetchSize</code> (default: 100).
* The default result set fetch size when using the server mode.
*/
public static final int SERVER_RESULT_SET_FETCH_SIZE = getIntSetting("h2.serverResultSetFetchSize", 100); public static final int SERVER_RESULT_SET_FETCH_SIZE = getIntSetting("h2.serverResultSetFetchSize", 100);
public static final int EMERGENCY_SPACE_INITIAL = getIntSetting("h2.emergencySpaceInitial", 256 * 1024);
public static final int EMERGENCY_SPACE_MIN = getIntSetting("h2.emergencySpaceMin", 64 * 1024);
public static final boolean OBJECT_CACHE = getBooleanSetting("h2.objectCache", true);
public static final int OBJECT_CACHE_SIZE = getIntSetting("h2.objectCacheSize", 1024);
public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = getIntSetting("h2.objectCacheMaxPerElementSize", 4096);
public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/");
public static final int MAX_FILE_RETRY = Math.max(1, getIntSetting("h2.maxFileRetry", 16));
public static final boolean ALLOW_BIG_DECIMAL_EXTENSIONS = getBooleanSetting("h2.allowBigDecimalExtensions", false);
public static final boolean INDEX_LOOKUP_NEW = getBooleanSetting("h2.indexLookupNew", true);
public static final boolean TRACE_IO = getBooleanSetting("h2.traceIO", false); public static final boolean TRACE_IO = getBooleanSetting("h2.traceIO", false);
public static final int DATASOURCE_TRACE_LEVEL = getIntSetting("h2.dataSourceTraceLevel", TraceSystem.ERROR);
public static final int CACHE_SIZE_DEFAULT = getIntSetting("h2.cacheSizeDefault", 16 * 1024);
public static final int CACHE_SIZE_INDEX_SHIFT = getIntSetting("h2.cacheSizeIndexShift", 3);
public static final int DEFAULT_MAX_MEMORY_UNDO = getIntSetting("h2.defaultMaxMemoryUndo", 100000);
public static final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED);
public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true);
public static String scriptDirectory = getStringSetting("h2.scriptDirectory", "");
private static String baseDir = getStringSetting("h2.baseDir", null); private static String baseDir = getStringSetting("h2.baseDir", null);
public static boolean lobCloseBetweenReads = getBooleanSetting("h2.lobCloseBetweenReads", false);
// TODO: also remove DataHandler.allocateObjectId, createTempFile when setting this to true and removing it
public static final boolean LOB_FILES_IN_DIRECTORIES = getBooleanSetting("h2.lobFilesInDirectories", false);
public static final int LOB_FILES_PER_DIRECTORY = getIntSetting("h2.lobFilesPerDirectory", 256);
public static final boolean NEW_DISPLAY_SIZE = getBooleanSetting("h2.newDisplaySize", true);
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
public static final String ALLOWED_CLASSES = getStringSetting("h2.allowedClasses", "*");
public static final int MIN_COLUMN_NAME_MAP = getIntSetting("h2.minColumnNameMap", 3);
private static boolean getBooleanSetting(String name, boolean defaultValue) { private static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = getProperty(name); String s = getProperty(name);
...@@ -94,6 +257,9 @@ public class SysProperties { ...@@ -94,6 +257,9 @@ public class SysProperties {
} }
} }
/**
* INTERNAL
*/
public static String getStringSetting(String name, String defaultValue) { public static String getStringSetting(String name, String defaultValue) {
String s = getProperty(name); String s = getProperty(name);
return s == null ? defaultValue : s; return s == null ? defaultValue : s;
...@@ -127,5 +293,4 @@ public class SysProperties { ...@@ -127,5 +293,4 @@ public class SysProperties {
return baseDir; return baseDir;
} }
public static final int CACHE_SIZE_INDEX_DEFAULT = CACHE_SIZE_DEFAULT >> CACHE_SIZE_INDEX_SHIFT;
} }
...@@ -27,10 +27,11 @@ public class JdbcBatchUpdateException extends BatchUpdateException { ...@@ -27,10 +27,11 @@ public class JdbcBatchUpdateException extends BatchUpdateException {
* INTERNAL * INTERNAL
*/ */
public void printStackTrace() { public void printStackTrace() {
super.printStackTrace(); // The default implementation already does that,
if (getNextException() != null) { // but we do it again to avoid problems.
getNextException().printStackTrace(); // 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; ...@@ -55,7 +55,7 @@ import java.sql.SQLClientInfoException;
*/ */
public class JdbcConnection extends TraceObject implements Connection { public class JdbcConnection extends TraceObject implements Connection {
// TODO test: check if enough synchronization on jdbc objects // 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 url;
private String user; private String user;
......
...@@ -61,17 +61,11 @@ public class JdbcSQLException extends SQLException { ...@@ -61,17 +61,11 @@ public class JdbcSQLException extends SQLException {
* Prints the stack trace to the standard error stream. * Prints the stack trace to the standard error stream.
*/ */
public void printStackTrace() { public void printStackTrace() {
super.printStackTrace(); // The default implementation already does that,
//#ifdef JDK13 // but we do it again to avoid problems.
/* // If it is not implemented, somebody might implement it
if (cause != null) { // later on which would be a problem if done in the wrong way.
cause.printStackTrace(); printStackTrace(System.err);
}
*/
//#endif
if (getNextException() != null) {
getNextException().printStackTrace();
}
} }
/** /**
...@@ -89,8 +83,15 @@ public class JdbcSQLException extends SQLException { ...@@ -89,8 +83,15 @@ public class JdbcSQLException extends SQLException {
} }
*/ */
//#endif //#endif
if (getNextException() != null) { // getNextException().printStackTrace(s) would be very very slow
getNextException().printStackTrace(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)");
} }
} }
} }
...@@ -110,8 +111,15 @@ public class JdbcSQLException extends SQLException { ...@@ -110,8 +111,15 @@ public class JdbcSQLException extends SQLException {
} }
*/ */
//#endif //#endif
if (getNextException() != null) { // getNextException().printStackTrace(s) would be very very slow
getNextException().printStackTrace(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)");
} }
} }
} }
......
...@@ -31,6 +31,7 @@ import org.h2.message.Message; ...@@ -31,6 +31,7 @@ import org.h2.message.Message;
import org.h2.util.ByteUtils; import org.h2.util.ByteUtils;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.IOUtils; 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
...@@ -80,7 +81,13 @@ public class SecureSocketFactory { ...@@ -80,7 +81,13 @@ public class SecureSocketFactory {
//#ifdef JDK14 //#ifdef JDK14
setKeystore(); setKeystore();
ServerSocketFactory f = SSLServerSocketFactory.getDefault(); 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) { if (ENABLE_ANONYMOUS_SSL) {
String[] list = secureSocket.getEnabledCipherSuites(); String[] list = secureSocket.getEnabledCipherSuites();
list = addAnonymous(list); list = addAnonymous(list);
......
...@@ -81,8 +81,8 @@ public class FtpServer implements Service { ...@@ -81,8 +81,8 @@ public class FtpServer implements Service {
} }
} }
public ServerSocket createDataSocket() throws IOException { public ServerSocket createDataSocket() throws SQLException {
ServerSocket dataSocket = new ServerSocket(0); ServerSocket dataSocket = NetUtils.createServerSocket(0, false);
return dataSocket; return dataSocket;
} }
......
...@@ -24,6 +24,7 @@ import org.h2.message.TraceSystem; ...@@ -24,6 +24,7 @@ import org.h2.message.TraceSystem;
import org.h2.store.fs.FileSystem; import org.h2.store.fs.FileSystem;
import org.h2.util.ByteUtils; import org.h2.util.ByteUtils;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.NetUtils;
import org.h2.util.RandomUtils; import org.h2.util.RandomUtils;
import org.h2.util.SortedProperties; import org.h2.util.SortedProperties;
...@@ -267,7 +268,7 @@ public class FileLock { ...@@ -267,7 +268,7 @@ public class FileLock {
} }
try { try {
// 0 to use any free port // 0 to use any free port
socket = new ServerSocket(0); socket = NetUtils.createServerSocket(0, false);
int port = socket.getLocalPort(); int port = socket.getLocalPort();
properties.setProperty("ipAddress", ipAddress); properties.setProperty("ipAddress", ipAddress);
properties.setProperty("port", String.valueOf(port)); properties.setProperty("port", String.valueOf(port));
......
...@@ -712,43 +712,44 @@ public class MetaTable extends Table { ...@@ -712,43 +712,44 @@ public class MetaTable extends Table {
add(rows, new String[] { "EXCLUSIVE", database.getExclusiveSession() == null ? "FALSE" : "TRUE" }); add(rows, new String[] { "EXCLUSIVE", database.getExclusiveSession() == null ? "FALSE" : "TRUE" });
add(rows, new String[] { "MODE", database.getMode().getName() }); add(rows, new String[] { "MODE", database.getMode().getName() });
add(rows, new String[] { "MULTI_THREADED", database.getMultiThreaded() ? "1" : "0"}); add(rows, new String[] { "MULTI_THREADED", database.getMultiThreaded() ? "1" : "0"});
DiskFile dataFile = database.getDataFile(); add(rows, new String[]{"h2.allowBigDecimalExtensions", "" + SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS});
if (dataFile != null) { add(rows, new String[]{"h2.baseDir", "" + SysProperties.getBaseDir()});
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.check", "" + SysProperties.CHECK}); add(rows, new String[]{"h2.check", "" + SysProperties.CHECK});
add(rows, new String[]{"h2.check2", "" + SysProperties.CHECK2}); 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.lobFilesInDirectories", "" + SysProperties.LOB_FILES_IN_DIRECTORIES});
add(rows, new String[]{"h2.lobFilesPerDirectory", "" + SysProperties.LOB_FILES_PER_DIRECTORY}); 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.logAllErrors", "" + SysProperties.LOG_ALL_ERRORS});
add(rows, new String[]{"h2.logAllErrorsFile", "" + SysProperties.LOG_ALL_ERRORS_FILE}); 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.maxFileRetry", "" + SysProperties.MAX_FILE_RETRY});
add(rows, new String[]{"h2.serverResultSetFetchSize", "" + SysProperties.SERVER_RESULT_SET_FETCH_SIZE}); add(rows, new String[]{"h2.lobCloseBetweenReads", "" + SysProperties.lobCloseBetweenReads});
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.objectCache", "" + SysProperties.OBJECT_CACHE}); add(rows, new String[]{"h2.objectCache", "" + SysProperties.OBJECT_CACHE});
add(rows, new String[]{"h2.objectCacheSize", "" + SysProperties.OBJECT_CACHE_SIZE}); 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.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.scriptDirectory", SysProperties.scriptDirectory});
add(rows, new String[]{"h2.maxFileRetry", "" + SysProperties.MAX_FILE_RETRY}); add(rows, new String[]{"h2.serverCachedObjects", "" + SysProperties.SERVER_CACHED_OBJECTS});
add(rows, new String[]{"h2.lobCloseBetweenReads", "" + SysProperties.lobCloseBetweenReads}); add(rows, new String[]{"h2.serverResultSetFetchSize", "" + SysProperties.SERVER_RESULT_SET_FETCH_SIZE});
add(rows, new String[]{"h2.allowBigDecimalExtensions", "" + SysProperties.ALLOW_BIG_DECIMAL_EXTENSIONS}); DiskFile dataFile = database.getDataFile();
add(rows, new String[]{"h2.baseDir", "" + SysProperties.getBaseDir()}); if (dataFile != null) {
add(rows, new String[]{"h2.defaultMaxMemoryUndo", "" + SysProperties.DEFAULT_MAX_MEMORY_UNDO}); 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; break;
} }
case TYPE_INFO: { case TYPE_INFO: {
......
...@@ -9,9 +9,11 @@ import java.net.BindException; ...@@ -9,9 +9,11 @@ import java.net.BindException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.security.SecureSocketFactory; import org.h2.security.SecureSocketFactory;
...@@ -20,6 +22,8 @@ import org.h2.security.SecureSocketFactory; ...@@ -20,6 +22,8 @@ import org.h2.security.SecureSocketFactory;
*/ */
public class NetUtils { public class NetUtils {
private static InetAddress bindAddress;
public static Socket createLoopbackSocket(int port, boolean ssl) throws IOException { public static Socket createLoopbackSocket(int port, boolean ssl) throws IOException {
return createSocket("127.0.0.1", port, ssl); return createSocket("127.0.0.1", port, ssl);
} }
...@@ -58,15 +62,37 @@ public class NetUtils { ...@@ -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 { 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 { try {
if (ssl) { if (ssl) {
SecureSocketFactory f = SecureSocketFactory.getInstance(); SecureSocketFactory f = SecureSocketFactory.getInstance();
return f.createServerSocket(port); return f.createServerSocket(port);
} else { } else {
InetAddress bindAddress = getBindAddress();
if (bindAddress == null) {
return new ServerSocket(port); return new ServerSocket(port);
} else {
return new ServerSocket(port, 0, bindAddress);
}
} }
} catch (BindException be) { } catch (BindException be) {
throw Message.getSQLException(ErrorCode.EXCEPTION_OPENING_PORT_2, throw Message.getSQLException(ErrorCode.EXCEPTION_OPENING_PORT_2,
......
...@@ -11,7 +11,6 @@ import org.h2.server.TcpServer; ...@@ -11,7 +11,6 @@ import org.h2.server.TcpServer;
import org.h2.store.fs.FileSystemDisk; import org.h2.store.fs.FileSystemDisk;
import org.h2.test.db.TestAutoRecompile; import org.h2.test.db.TestAutoRecompile;
import org.h2.test.db.TestBackup; import org.h2.test.db.TestBackup;
import org.h2.test.db.TestBatchUpdates;
import org.h2.test.db.TestBigDb; import org.h2.test.db.TestBigDb;
import org.h2.test.db.TestBigResult; import org.h2.test.db.TestBigResult;
import org.h2.test.db.TestCases; import org.h2.test.db.TestCases;
...@@ -49,6 +48,7 @@ import org.h2.test.db.TestTransaction; ...@@ -49,6 +48,7 @@ import org.h2.test.db.TestTransaction;
import org.h2.test.db.TestTriggersConstraints; import org.h2.test.db.TestTriggersConstraints;
import org.h2.test.db.TestTwoPhaseCommit; import org.h2.test.db.TestTwoPhaseCommit;
import org.h2.test.db.TestView; import org.h2.test.db.TestView;
import org.h2.test.jdbc.TestBatchUpdates;
import org.h2.test.jdbc.TestCallableStatement; import org.h2.test.jdbc.TestCallableStatement;
import org.h2.test.jdbc.TestCancel; import org.h2.test.jdbc.TestCancel;
import org.h2.test.jdbc.TestDataSource; import org.h2.test.jdbc.TestDataSource;
...@@ -149,16 +149,32 @@ java org.h2.test.TestAll timer ...@@ -149,16 +149,32 @@ java org.h2.test.TestAll timer
/* /*
staging.trace.db.gz 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 allow queries as well in batch updates
CALL syntax should probably work for regular executeUpdate as well. 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 http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/callablestatement.html#1000220
-Djboss.bind.address=<ip_address> Automatically switch source code before compiling
-Dh2.bindAddress=...
[echo] Java version is 1.6 but source code is switched to 1.4. [echo] Java version is 1.6 but source code is switched to 1.4.
[echo] Run ant codeswitchJdk... first. [echo] Run ant codeswitchJdk... first.
...@@ -487,7 +503,6 @@ Features of H2 ...@@ -487,7 +503,6 @@ Features of H2
new TestScript().runTest(this); new TestScript().runTest(this);
new TestAutoRecompile().runTest(this); new TestAutoRecompile().runTest(this);
new TestBackup().runTest(this); new TestBackup().runTest(this);
new TestBatchUpdates().runTest(this);
new TestBigDb().runTest(this); new TestBigDb().runTest(this);
new TestBigResult().runTest(this); new TestBigResult().runTest(this);
new TestCache().runTest(this); new TestCache().runTest(this);
...@@ -531,6 +546,7 @@ Features of H2 ...@@ -531,6 +546,7 @@ Features of H2
new TestPgServer().runTest(this); new TestPgServer().runTest(this);
// jdbc // jdbc
new TestBatchUpdates().runTest(this);
new TestCallableStatement().runTest(this); new TestCallableStatement().runTest(this);
new TestCancel().runTest(this); new TestCancel().runTest(this);
new TestDatabaseEventListener().runTest(this); new TestDatabaseEventListener().runTest(this);
......
...@@ -66,20 +66,25 @@ public class TestOptimizations extends TestBase { ...@@ -66,20 +66,25 @@ public class TestOptimizations extends TestBase {
checkFalse(rs.next()); checkFalse(rs.next());
stat.execute("ANALYZE"); stat.execute("ANALYZE");
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE"); 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)); check(i, rs.getInt(1));
} }
checkFalse(rs.next()); checkFalse(rs.next());
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 5 OFFSET 2"); rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 5 OFFSET 2");
for (int i = 2; i < 7; i++) { for (int i = 2; i < 7; i++) {
rs.next(); check(rs.next());
check(i, rs.getInt(1)); check(i, rs.getInt(1));
} }
checkFalse(rs.next()); checkFalse(rs.next());
rs = stat.executeQuery("SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 0 OFFSET 0 SAMPLE_SIZE 3"); 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++) { for (int i = 0; i < 3; i++) {
rs.next(); rs.getInt(1);
check(i, rs.getInt(1)); if (i > 0 && !rs.next()) {
break;
}
} }
checkFalse(rs.next()); checkFalse(rs.next());
conn.close(); conn.close();
......
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html). * Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * 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.BatchUpdateException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
...@@ -36,6 +38,37 @@ public class TestBatchUpdates extends TestBase { ...@@ -36,6 +38,37 @@ public class TestBatchUpdates extends TestBase {
PreparedStatement prep; PreparedStatement prep;
public void test() throws Exception { 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"); deleteDb("batchUpdates");
this.conn = getConnection("batchUpdates"); this.conn = getConnection("batchUpdates");
stat = conn.createStatement(); stat = conn.createStatement();
......
...@@ -36,4 +36,5 @@ To call getFD().sync() (which results in the OS call fsync()), ...@@ -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. set the system property derby.storage.fileSyncTransactionLog to true true.
See See
http://db.apache.org/derby/javadoc/engine/org/apache/derby/iapi/reference/Property.html#FILESYNC_TRANSACTION_LOG 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论