提交 0ae9a7c4 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 681e0c20
......@@ -228,6 +228,20 @@
</copy>
</target>
<target name="javadocImpl">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/test" destdir="bin" debug="true" includes="org/h2/test/bnf/*.java"/>
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/tools" destdir="bin" debug="true" includes="org/h2/tools/doclet/*.java"/>
<mkdir dir="docs/javadoc"/>
<javadoc
sourcepath="src/main"
packagenames="org.h2.jdbc.*,org.h2.tools.*,org.h2.api.*,org.h2.store.*"
destDir="doc/javadoc"
/> <!-- doclet="org.h2.tools.doclet.Doclet" docletpath="bin"-->
<copy todir="docs/javadoc">
<fileset dir="src/docsrc/javadoc" includes="**/*"/>
</copy>
</target>
<target name="manifest">
<mkdir dir="bin/META-INF"/>
<manifest file="bin/META-INF/MANIFEST.MF">
......
......@@ -358,6 +358,11 @@ Therefore, the PostgreSQL ODBC driver can be used.
Support for the PostgreSQL network protocol is quite new and should be viewed
as experimental. It should not be used for production applications.
</p>
<p>
At this time, the PostgreSQL ODBC driver does not work on 64 bit versions of Windows.
For more information, see:
<a href="http://svr5.postgresql.org/pgsql-odbc/2005-09/msg00127.php">ODBC Driver on Windows 64 bit</a>
</p>
<h3>ODBC Installation</h3>
<p>
......@@ -896,6 +901,7 @@ INFORMATION_SCHEMA.SETTINGS
<tr><td>h2.objectCache</td><td>true</td><td>Cache commonly used objects (integers, strings)</td></tr>
<tr><td>h2.objectCacheMaxPerElementSize</td><td>4096</td><td>Maximum size of an object in the cache</td></tr>
<tr><td>h2.objectCacheSize</td><td>1024</td><td>Size of object cache</td></tr>
<tr><td>h2.optimizeEvaluatableSubqueries</td><td>true</td><td>Optimize subqueries that are not dependent on the outer query</td></tr>
<tr><td>h2.optimizeIn</td><td>true</td><td>Optimize IN(...) comparisons</td></tr>
<tr><td>h2.optimizeMinMax</td><td>true</td><td>Optimize MIN and MAX aggregate functions</td></tr>
<tr><td>h2.optimizeSubqueryCache</td><td>true</td><td>Cache subquery results</td></tr>
......
......@@ -40,14 +40,19 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3>
<h3>Version 1.0.x (2007-09-x)</h3><ul>
<li>When using IFNULL, NULLIF, COALESCE, LEAST, or GREATEST,
and the first parameter was ?, an exception was thrown.
Now the higest data type of all parameters is used.
<li>Optimization for independent subqueries. For example, this query can now an index:
SELECT * FROM TEST WHERE ID = (SELECT MAX(ID) FROM TEST)
This can be disabled by setting the system property h2.optimizeSubqueryCache to false.
</li><li>The explain plan now says: /* direct lookup query */ if the query can be processed directly without reading rows,
for example when using MIN(indexed column), MAX(indexed column), or COUNT(*).
</li><li>When using IFNULL, NULLIF, COALESCE, LEAST, or GREATEST,
and the first parameter was ?, an exception was thrown.
Now the highest data type of all parameters is used.
</li><li>When comparing TINYINT or SMALLINT columns against constants, the index was not used. Fixed.
</li><li>Maven 2: new version are now automatically synched with the central repositories.
</li><li>Maven 2: new version are now automatically synced with the central repositories.
</li><li>The default value for MAX_MEMORY_UNDO is now 100000.
</li><li>The documentation indexer does no longer index Japanese pages.
If somebody knows how to split Japanese into words please post it.
If somebody knows how to split Japanese into words please post it.
</li><li>Oracle compatibility: SYSDATE now returns a timestamp. CHR(..) is now an alias for CHAR(..).
</li><li>After deleting data, empty space in the database files was not efficiently reused
(but it was reused when opening the database). This has been fixed.
......@@ -752,7 +757,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6
</li><li>Document org.h2.samples.MixedMode
</li><li>Server: use one listener (detect if the request comes from an PG or TCP client)
</li><li>Store dates as 'local'. Existing files use GMT. Use escape syntax for backward compatiblity)
</li><li>Store dates as 'local'. Existing files use GMT. Use escape syntax for compatibility)
</li><li>Support data type INTERVAL
</li></ul>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -18,12 +18,12 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.log.LogFile;
import org.h2.log.LogSystem;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.store.DiskFile;
import org.h2.store.FileLister;
import org.h2.store.LogFile;
import org.h2.store.LogSystem;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.ObjectArray;
......
......@@ -10,9 +10,9 @@ import org.h2.command.Prepared;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.log.UndoLogRecord;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.PlanItem;
import org.h2.table.Table;
import org.h2.table.TableFilter;
......
......@@ -12,10 +12,10 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
......
......@@ -14,10 +14,10 @@ import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.Parameter;
import org.h2.index.Index;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
......
......@@ -9,7 +9,6 @@ import java.util.HashMap;
import java.util.HashSet;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Session;
import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr;
......@@ -534,6 +533,8 @@ public class Select extends Query {
if (on != null) {
if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) {
f.removeJoinCondition();
// need to check that all added are bound to a table
on = on.optimize(session);
addCondition(on);
}
}
......@@ -544,9 +545,13 @@ public class Select extends Query {
addCondition(on);
}
}
// this is only important for subqueries, so they know the result columns are evaluatable
for (int i = 0; i < expressions.size(); i++) {
Expression e = (Expression) expressions.get(i);
e.setEvaluatable(f, true);
}
f = f.getJoin();
}
topTableFilter.prepare();
return cost;
}
......@@ -621,6 +626,11 @@ public class Select extends Query {
if (isForUpdate) {
buff.append("\nFOR UPDATE");
}
if (isQuickQuery) {
buff.append("\n/* direct lookup query */");
}
return buff.toString();
}
......@@ -739,13 +749,11 @@ public class Select extends Query {
}
}
if (visitor.type == ExpressionVisitor.EVALUATABLE) {
if (!Constants.OPTIMIZE_EVALUATABLE_SUBQUERIES) {
if (!SysProperties.OPTIMIZE_EVALUATABLE_SUBQUERIES) {
return false;
}
}
if (visitor.type != ExpressionVisitor.EVALUATABLE) {
visitor.queryLevel(1);
}
visitor.queryLevel(1);
boolean result = true;
for (int i = 0; i < expressions.size(); i++) {
Expression e = (Expression) expressions.get(i);
......@@ -760,9 +768,7 @@ public class Select extends Query {
if (result && having != null && !having.isEverything(visitor)) {
result = false;
}
if (visitor.type != ExpressionVisitor.EVALUATABLE) {
visitor.queryLevel(-1);
}
visitor.queryLevel(-1);
return result;
}
......
......@@ -25,11 +25,15 @@ public class SysProperties {
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
public static final boolean CHECK = getBooleanSetting("h2.check", true);
public static final boolean CHECK2 = getBooleanSetting("h2.check2", false);
public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", 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_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);
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", 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");
......@@ -49,8 +53,6 @@ public class SysProperties {
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 boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true);
public static final boolean OPTIMIZE_TWO_EQUALS = getBooleanSetting("h2.optimizeTwoEquals", true);
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", "");
......
......@@ -24,7 +24,9 @@ import org.h2.constant.SysProperties;
* set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_01
* ant codeswitchJdk16
* ant compile
* ant javadocImpl
* ant codeswitchJdk14
* ant javadocImpl
*
* - Change FAQ (next release planned, known bugs)
* - Check version, change build number in Constants.java and ant-build.properties
......@@ -169,9 +171,6 @@ public class Constants {
public static final int VIEW_COST_CACHE_MAX_AGE = 10000; // 10 seconds
public static final int MAX_PARAMETER_INDEX = 100000;
// TODO need to refactor & test the code to enable this (add more tests!)
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = false;
// to slow down dictionary attacks
public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024;
public static final String SCRIPT_SQL = "script.sql";
......
......@@ -19,6 +19,8 @@ import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.jdbc.JdbcSQLException;
import org.h2.log.LogSystem;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
......@@ -32,10 +34,8 @@ import org.h2.store.DataPage;
import org.h2.store.DiskFile;
import org.h2.store.FileLock;
import org.h2.store.FileStore;
import org.h2.store.LogSystem;
import org.h2.store.RecordReader;
import org.h2.store.Storage;
import org.h2.store.UndoLogRecord;
import org.h2.store.WriterThread;
import org.h2.table.Column;
import org.h2.table.MetaTable;
......
......@@ -19,16 +19,16 @@ import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.jdbc.JdbcConnection;
import org.h2.log.InDoubtTransaction;
import org.h2.log.LogSystem;
import org.h2.log.UndoLog;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.store.DataHandler;
import org.h2.store.InDoubtTransaction;
import org.h2.store.LogSystem;
import org.h2.store.UndoLog;
import org.h2.store.UndoLogRecord;
import org.h2.table.Table;
import org.h2.util.ObjectUtils;
import org.h2.util.ObjectArray;
......
......@@ -35,7 +35,7 @@ public class Comparison extends Condition {
private final int compareType;
private Expression left;
private Expression right;
private int dataType = -1;
private int dataType = -2;
public Comparison(Session session, int compareType, Expression left, Expression right) {
this.database = session.getDatabase();
......@@ -318,11 +318,9 @@ public class Comparison extends Condition {
public void addFilterConditions(TableFilter filter, boolean outerJoin) {
if (compareType == IS_NULL && outerJoin) {
// can not optimize:
// select * from test t1 left join test t2 on t1.id = t2.id where
// t2.id is null
// select * from test t1 left join test t2 on t1.id = t2.id where t2.id is null
// to
// select * from test t1 left join test t2 on t1.id = t2.id and
// t2.id is null
// select * from test t1 left join test t2 on t1.id = t2.id and t2.id is null
return;
}
super.addFilterConditions(filter, outerJoin);
......
......@@ -11,11 +11,11 @@ import java.util.HashSet;
import java.util.Iterator;
import org.h2.engine.Constants;
import org.h2.engine.Session;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.store.Storage;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column;
import org.h2.table.TableData;
import org.h2.util.ObjectArray;
......
......@@ -840,9 +840,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
* Sets the value of a parameter as an input stream.
*
* @param parameterIndex the parameter index (1, 2, ...)
* @param x the value
* @param length the number of bytes
* @throws SQLException if this object is closed
* @param x the value * @throws SQLException if this object is closed
*/
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
setBinaryStream(parameterIndex, x, -1);
......
......@@ -910,7 +910,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/**
* Returns the value of the specified column as a Blob.
*
* @param columnName the name of the column label
* @param columnIndex (1,2,...)
* @return the value
* @throws SQLException if the column is not found or if the result set is closed
*/
......@@ -929,7 +929,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/**
* Returns the value of the specified column as a Blob.
*
* @param columnIndex (1,2,...)
* @param columnName the name of the column label
* @return the value
* @throws SQLException if the column is not found or if the result set is closed
*/
......@@ -1013,7 +1013,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/**
* Returns the value of the specified column as a Clob.
*
* @param columnName the name of the column label
* @param columnIndex (1,2,...)
* @return the value
* @throws SQLException if the column is not found or if the result set is closed
*/
......@@ -1032,7 +1032,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/**
* Returns the value of the specified column as a Clob.
*
* @param columnIndex (1,2,...)
* @param columnName the name of the column label
* @return the value
* @throws SQLException if the column is not found or if the result set is closed
*/
......@@ -1695,7 +1695,6 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
*
* @param columnIndex (1,2,...)
* @param x the value
* @param length the number of characters
* @throws SQLException if the result set is closed
*/
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
......@@ -1740,7 +1739,6 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
*
* @param columnName the name of the column label
* @param x the value
* @param length the number of characters
* @throws SQLException if the result set is closed
*/
public void updateAsciiStream(String columnName, InputStream x) throws SQLException {
......@@ -3029,7 +3027,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/**
* Updates a column in the current or insert row.
*
* @param columnIndex (1,2,...)
* @param columnName the name of the column label
* @param x the value
* @throws SQLException if the result set is closed
*/
......
......@@ -2,7 +2,7 @@
* 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.store;
package org.h2.log;
import java.sql.SQLException;
......
......@@ -2,7 +2,7 @@
* 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.store;
package org.h2.log;
import java.io.IOException;
import java.sql.SQLException;
......@@ -14,17 +14,27 @@ import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.store.DataPage;
import org.h2.store.DiskFile;
import org.h2.store.FileStore;
import org.h2.store.Record;
import org.h2.store.Storage;
import org.h2.util.FileUtils;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
/*
/**
* Each log file contains a number of log records.
*
* Header format:
* intFixed logId (<0 means ignore: rolled back already)
* intFixed firstUncommittedLogRecordId (-1 if none)
* intFixed firstUnwrittenLogRecordId (-1 if none)
* <pre>
* int logId (<0 means ignore: rolled back already)
* int firstUncommittedLogRecordId (-1 if none)
* int firstUnwrittenLogRecordId (-1 if none)
* </pre>
*
* Record format:
* <pre>
* int block size
* byte 'D' (delete) / 'I' (insert) / 'C' (commit) / 'R' (rollback) / 'P' (prepare commit) / 'T' (truncate)
* int session
......@@ -34,6 +44,7 @@ import org.h2.util.ObjectArray;
* int record.blockCount
* [prepare commit only:]
* string transaction
* </pre>
*/
public class LogFile {
......
......@@ -2,7 +2,8 @@
* 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.store;
package org.h2.log;
public class LogRecord {
LogFile log;
......
......@@ -2,7 +2,7 @@
* 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.store;
package org.h2.log;
import java.sql.SQLException;
import java.util.Comparator;
......@@ -13,12 +13,17 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Trace;
import org.h2.store.DataPage;
import org.h2.store.DiskFile;
import org.h2.store.Record;
import org.h2.store.Storage;
import org.h2.util.FileUtils;
import org.h2.util.ObjectUtils;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* The log system is responsible for the write ahead log mechanism used in this database.
* A number of {@link LogFile} objects are used (one for each file).
*/
public class LogSystem {
......
......@@ -2,14 +2,16 @@
* 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.store;
package org.h2.log;
import org.h2.store.Storage;
public class RedoLogRecord {
Storage storage;
int sequenceId;
int recordId;
int offset;
byte[] data;
public Storage storage;
public int sequenceId;
public int recordId;
public int offset;
public byte[] data;
public int getSize() {
// estimated memory size in bytes ((5 variables+myself) * 4 bytes each)
......
......@@ -2,7 +2,8 @@
* 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.store;
package org.h2.log;
public class SessionState {
int sessionId;
......
......@@ -2,7 +2,7 @@
* 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.store;
package org.h2.log;
import java.sql.SQLException;
......@@ -11,6 +11,8 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.store.DataPage;
import org.h2.store.FileStore;
import org.h2.util.ObjectArray;
public class UndoLog {
......
......@@ -2,7 +2,7 @@
* 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.store;
package org.h2.log;
import java.sql.SQLException;
......@@ -14,6 +14,8 @@ import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.message.Message;
import org.h2.result.Row;
import org.h2.store.DataPage;
import org.h2.store.FileStore;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
import org.h2.value.Value;
......
......@@ -8,6 +8,10 @@ import java.sql.SQLException;
import org.h2.value.Value;
/**
* A data handler contains a number of callback methods.
* The most important implementing class is a database.
*/
public interface DataHandler {
boolean getTextStorage();
String getDatabasePath();
......
......@@ -37,7 +37,7 @@ import org.h2.value.ValueTimestamp;
import org.h2.value.ValueUuid;
/**
* @author Thomas
* A data page is a byte buffer that contains persistent data of a row or index page.
*/
public abstract class DataPage {
......
......@@ -7,7 +7,8 @@ package org.h2.store;
import java.sql.SQLException;
/**
* @author Thomas
* This class represents a byte buffer optimized for performance.
* It is the standard mechanism to convert data to a byte array and vice versa.
*/
public class DataPageBinary extends DataPage {
// private final static boolean UTF8 = true;
......
......@@ -9,6 +9,11 @@ import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
/**
* This class represents a byte buffer that is human readable up to some point.
* Number are stored in hex format.
* It is mainly used to debug storage problems.
*/
public class DataPageText extends DataPage {
public DataPageText(DataHandler handler, byte[] data) {
......
......@@ -19,6 +19,8 @@ import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.log.LogSystem;
import org.h2.log.RedoLogRecord;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.util.BitField;
......@@ -33,7 +35,12 @@ import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
/**
* @author Thomas
* This class represents a file that is usually written to disk.
* The two main files are .data.db and .index.db.
* For each such file, a number of {@link Storage} objects exists.
* The disk file is responsible for caching; each object contains a {@link Cache} object.
* Changes in the file are logged in a {@link LogSystem} object.
* Reading and writing to the file is delegated to the {@link FileStore} class.
*/
public class DiskFile implements CacheWriter {
......@@ -313,7 +320,7 @@ public class DiskFile implements CacheWriter {
init = true;
}
synchronized void flush() throws SQLException {
public synchronized void flush() throws SQLException {
database.checkPowerOff();
ObjectArray list = cache.getAllChanged();
CacheObject.sort(list);
......@@ -517,7 +524,7 @@ public class DiskFile implements CacheWriter {
return pageOwners.get(page);
}
void setPageOwner(int page, int storageId) throws SQLException {
public void setPageOwner(int page, int storageId) throws SQLException {
int old = pageOwners.get(page);
if (old == storageId) {
return;
......@@ -765,7 +772,7 @@ public class DiskFile implements CacheWriter {
this.logChanges = b;
}
synchronized void addRedoLog(Storage storage, int recordId, int blockCount, DataPage rec) throws SQLException {
public synchronized void addRedoLog(Storage storage, int recordId, int blockCount, DataPage rec) throws SQLException {
byte[] data = null;
if (rec != null) {
DataPage all = rowBuff;
......@@ -797,7 +804,7 @@ public class DiskFile implements CacheWriter {
}
}
synchronized void flushRedoLog() throws SQLException {
public synchronized void flushRedoLog() throws SQLException {
if (redoBuffer.size() == 0) {
return;
}
......
......@@ -12,9 +12,8 @@ import org.h2.engine.Constants;
import org.h2.util.FileUtils;
/**
* @author Thomas
* Utility class to list the files of a database.
*/
public class FileLister {
public static String getDatabaseNameFromFileName(String fileName) {
......
......@@ -27,7 +27,8 @@ import org.h2.util.RandomUtils;
import org.h2.util.SortedProperties;
/**
* @author Thomas
* The file lock is used to lock a database so that only one process can write to it.
* Usually a .lock.db file is used, but locking by creating a socket is supported as well.
*/
public class FileLock {
......
......@@ -18,6 +18,11 @@ import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
import org.h2.util.TempFileDeleter;
/**
* This class is an abstraction of a random access file.
* Each file contains a magic header, and reading / writing is done in blocks.
* See also {@link MemoryFileStore} and {@link SecureFileStore}
*/
public class FileStore {
public static final int HEADER_LENGTH = 3 * Constants.FILE_BLOCK_SIZE;
......
......@@ -13,6 +13,9 @@ import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.tools.CompressTool;
/**
* An input stream that is backed by a file store.
*/
public class FileStoreInputStream extends InputStream {
private FileStore store;
......
......@@ -12,6 +12,9 @@ import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.tools.CompressTool;
/**
* An output stream that is backed by a file store.
*/
public class FileStoreOutputStream extends OutputStream {
private FileStore store;
private DataPage page;
......
......@@ -10,6 +10,10 @@ import java.sql.SQLException;
import org.h2.util.FileUtils;
import org.h2.util.MemoryFile;
/**
* This class is an abstraction of an in-memory file.
* A {@link MemoryFile} contains the actual bytes.
*/
public class MemoryFileStore extends FileStore {
private MemoryFile memFile;
......
......@@ -5,10 +5,13 @@
package org.h2.store;
import java.sql.SQLException;
import org.h2.log.LogSystem;
import org.h2.util.CacheObject;
/**
* @author Thomas
* A record represents a persisted row in a table, or a index page.
* When a record is persisted to disk, it is first written into a {@link DataPage} buffer.
*/
public abstract class Record extends CacheObject {
private boolean deleted;
......
......@@ -8,7 +8,7 @@ import java.sql.SQLException;
import org.h2.engine.Session;
/**
* @author Thomas
* A record reader is able to create a {@link Record} from a {@link DataPage}.
*/
public interface RecordReader {
Record read(Session session, DataPage s) throws SQLException;
......
......@@ -15,16 +15,22 @@ import org.h2.util.IntArray;
import org.h2.util.MathUtils;
/**
* This class represents an persistent container that stores data of a table or an index.
* An object contains a list of records, see {@link Record}.
* For each storage there is a {@link RecordReader} object that knows how to
* convert records into a byte array and vice versa.
* The data is stored in a {@link DiskFile}. A storage occupies a number of pages
* in a file.
*
* File format:
* intFixed block size
* intFixed storage id
* <pre>
* int block size
* int storage id
* record data
* byte checksum
* [bytes * fillerLength]
*
* @author Thomas
* </pre>
*/
public class Storage {
public static final int ALLOCATE_POS = -1;
......
......@@ -12,6 +12,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.index.BtreeIndex;
import org.h2.log.LogSystem;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.table.Table;
......
......@@ -34,6 +34,7 @@ import org.h2.expression.ValueExpression;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.MetaIndex;
import org.h2.log.InDoubtTransaction;
import org.h2.message.Message;
import org.h2.result.Row;
import org.h2.result.SearchRow;
......@@ -42,7 +43,6 @@ import org.h2.schema.Schema;
import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject;
import org.h2.store.DiskFile;
import org.h2.store.InDoubtTransaction;
import org.h2.tools.Csv;
import org.h2.util.ObjectArray;
import org.h2.util.Resources;
......
......@@ -15,6 +15,7 @@ import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.result.Row;
......@@ -25,7 +26,6 @@ import org.h2.schema.Schema;
import org.h2.schema.SchemaObjectBase;
import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject;
import org.h2.store.UndoLogRecord;
import org.h2.util.ObjectArray;
import org.h2.value.DataType;
import org.h2.value.Value;
......
......@@ -19,10 +19,10 @@ import org.h2.engine.Session;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.LinkedIndex;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message;
import org.h2.result.Row;
import org.h2.schema.Schema;
import org.h2.store.UndoLogRecord;
import org.h2.util.JdbcUtils;
import org.h2.util.ObjectArray;
import org.h2.util.StringUtils;
......
......@@ -522,7 +522,7 @@ public class Csv implements SimpleRowSource {
/**
* Override the end-of-row marker for writing. The default is null.
*
* @param fieldSeparatorWrite
* @param rowSeparatorWrite
*/
public void setRowSeparatorWrite(String rowSeparatorWrite) {
this.rowSeparatorWrite = rowSeparatorWrite;
......
......@@ -25,6 +25,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.engine.MetaRecord;
import org.h2.log.LogFile;
import org.h2.message.Message;
import org.h2.result.SimpleRow;
import org.h2.security.SHA256;
......@@ -34,7 +35,6 @@ import org.h2.store.DiskFile;
import org.h2.store.FileLister;
import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream;
import org.h2.store.LogFile;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
......
/* * 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.util;
import java.util.Collection;
......
......@@ -11,6 +11,10 @@ import org.h2.compress.CompressLZF;
import org.h2.constant.ErrorCode;
import org.h2.message.Message;
/**
* This class is an abstraction of an in-memory random access file.
* Data compression using the LZF algorithm is supported as well.
*/
public class MemoryFile {
private static final int CACHE_SIZE = 8;
private static final int BLOCK_SIZE_SHIFT = 16;
......
......@@ -137,37 +137,42 @@ java org.h2.test.TestAll timer
test.printSystem();
//int testMVCC;
// System.setProperty("h2.mvcc", "true");
/*
Sorry.... I just read the doc and it says using LOG=0 can lead to
corruption...
"At startup, when corrupted, say if LOG=0 was used before"
In fact, the reason I mentioned this is that I found out it was slow
when used in a sub query, thus I split it in two queries and forgot to
mention it. Try this and you will see why:
DROP TABLE TEST;
CREATE TABLE TEST(COL1 BIGINT PRIMARY KEY, COL2 VARCHAR);
INSERT INTO TEST SELECT X, CONCAT('Test', X) FROM SYSTEM_RANGE(1,
1000000);
SELECT MAX(COL1) FROM TEST;
SELECT * FROM TEST where col1=(select MAX(COL1) from test)
SELECT MAX(COL1) FROM TEST;
MAX(COL1)
1000000
(1 row, 0 ms)
SELECT * FROM TEST where col1=(select MAX(COL1) from test);
COL1 COL2
1000000 Test1000000
(1 row, 6815 ms)
I generally felt that sub queries were not properly optimized in h2
and I had to split them all (I understand it's a complex thing (I've
worked a (very) little on db2 a long long time ago...))
2007-09-11 22:58:09 TestCrashAPI 882584503
ERROR: new TestCrashAPI().init(test).testCase(882584503); // Bug 31183214 seed=882584503 id=-1219 callCount=1663 openCount=30 Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] ------------------------------
ERROR: new TestCrashAPI().init(test).testCase(882584503); // Bug 31183214 seed=882584503 id=-1220 callCount=1663 openCount=30 Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] ------------------------------
2007-09-11 22:58:31 TestCrashAPI 1611223775
2007-09-11 22:58:43 TestCrashAPI 1427414070
2007-09-11 22:58:49 TestCrashAPI 917384493
2007-09-11 22:59:10 TestCrashAPI 2045795338
2007-09-11 22:59:27 TestCrashAPI 1598830588
2007-09-11 22:59:45 TestCrashAPI 1674631584
2007-09-11 22:59:50 TestCrashAPI 378816468
2007-09-11 23:00:03 TestCrashAPI 1917055637
2007-09-11 23:00:06 TestCrashAPI 1095371615
2007-09-11 23:00:25 TestCrashAPI 613705034
2007-09-11 23:00:29 TestCrashAPI 1827006581
ERROR: new TestCrashAPI().init(test).testCase(1827006581); // Bug 31183214 seed=1827006581 id=-1219 callCount=1247 openCount=36 Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] ------------------------------
ERROR: new TestCrashAPI().init(test).testCase(1827006581); // Bug 31183214 seed=1827006581 id=-1220 callCount=1247 openCount=36 Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] org.h2.jdbc.JdbcSQLException: Allgemeiner Fehler: java.lang.Error: type=-1
General error: java.lang.Error: type=-1 [HY000-57] ------------------------------
2007-09-11 23:00:49 TestCrashAPI 324193595
add MVCC
......
......@@ -59,9 +59,9 @@ public class TestCrashAPI extends TestBase {
// the database in the finalize method
String add = ""; // ";STORAGE=TEXT";
// int testing;
int testing;
// add = ";STORAGE=TEXT";
if (openCount >= 42 && callCount > 1200 && seed == 437623957) {
if (openCount >= 33) {
System.exit(1);
}
// add = ";LOG=2";
......@@ -96,6 +96,10 @@ public class TestCrashAPI extends TestBase {
String sql = (String) statements.get(i);
try {
if(openCount == 32 && i == 1219) {
int test;
System.out.println("stop!");
}
stat.execute(sql);
} catch (Throwable t) {
printIfBad(seed, -i, -1, t);
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
CREATE TABLE PARENT(ID INT PRIMARY KEY);
> ok
CREATE TABLE CHILD(ID INT PRIMARY KEY);
> ok
INSERT INTO PARENT VALUES(1);
> update count: 1
SELECT * FROM PARENT P LEFT OUTER JOIN CHILD C ON C.PARENTID=P.ID;
> exception
DROP TABLE PARENT, CHILD;
> ok
create table test(id smallint primary key);
> ok
......@@ -11,6 +26,12 @@ explain select * from test where id = 1;
> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ WHERE ID = 1
> rows: 1
EXPLAIN SELECT * FROM TEST WHERE ID = (SELECT MAX(ID) FROM TEST);
> PLAN
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_1: ID = (SELECT MAX(ID) FROM PUBLIC.TEST /++ PUBLIC.TEST_TABLE_SCAN ++/ /++ direct lookup query ++/) */ WHERE ID = (SELECT MAX(ID) FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ /* direct lookup query */)
> rows: 1
drop table test;
> ok
......@@ -1483,11 +1504,11 @@ select * from test order by id;
> rows (ordered): 3
select rownum, (select count(*) from test), rownum from test;
> ROWNUM() SELECT COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ LIMIT 2 ROWNUM()
> -------- --------------------------------------------------------------------- --------
> 1 3 1
> 2 3 2
> 3 3 3
> ROWNUM() SELECT COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ LIMIT 2 /* direct lookup query */ ROWNUM()
> -------- ----------------------------------------------------------------------------------------------- --------
> 1 3 1
> 2 3 2
> 3 3 3
> rows: 3
delete from test t0 where rownum<2;
......
......@@ -506,4 +506,6 @@ lightweight builder
tunes elephant codewave incorrectly mytunesrss speeds cte honoured httpdocs department whereever dog dept edh oops flower music appends research plant
testview gaps birth vid weblog blojsom unsubscribe
imports bnot severity colon braces suppress star bxor band bor unary bsr puppy lor rcurly lcurly puppycrawl crawl ctor subclasses ell slist lnot land unchecked curly dtds question
forge
forge chr trunc gabealbert tunebackup manifest
lumber thus taking repositories ago delegated mention leaks pgsql seeded felt efficiently mill mentioned forgot leaked restarted clearing occupies randomness warn implementing abstraction
spfile svr pkey synced
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论