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

--no commit message

--no commit message
上级 681e0c20
...@@ -228,6 +228,20 @@ ...@@ -228,6 +228,20 @@
</copy> </copy>
</target> </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"> <target name="manifest">
<mkdir dir="bin/META-INF"/> <mkdir dir="bin/META-INF"/>
<manifest file="bin/META-INF/MANIFEST.MF"> <manifest file="bin/META-INF/MANIFEST.MF">
......
...@@ -358,6 +358,11 @@ Therefore, the PostgreSQL ODBC driver can be used. ...@@ -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 Support for the PostgreSQL network protocol is quite new and should be viewed
as experimental. It should not be used for production applications. as experimental. It should not be used for production applications.
</p> </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> <h3>ODBC Installation</h3>
<p> <p>
...@@ -896,6 +901,7 @@ INFORMATION_SCHEMA.SETTINGS ...@@ -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.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.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.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.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.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> <tr><td>h2.optimizeSubqueryCache</td><td>true</td><td>Cache subquery results</td></tr>
......
...@@ -40,11 +40,16 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -40,11 +40,16 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3> <h3>Version 1.0 (Current)</h3>
<h3>Version 1.0.x (2007-09-x)</h3><ul> <h3>Version 1.0.x (2007-09-x)</h3><ul>
<li>When using IFNULL, NULLIF, COALESCE, LEAST, or GREATEST, <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. and the first parameter was ?, an exception was thrown.
Now the higest data type of all parameters is used. 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>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 default value for MAX_MEMORY_UNDO is now 100000.
</li><li>The documentation indexer does no longer index Japanese pages. </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.
...@@ -752,7 +757,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -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>Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6
</li><li>Document org.h2.samples.MixedMode </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>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><li>Support data type INTERVAL
</li></ul> </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; ...@@ -18,12 +18,12 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.log.LogFile;
import org.h2.log.LogSystem;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.store.DiskFile; import org.h2.store.DiskFile;
import org.h2.store.FileLister; import org.h2.store.FileLister;
import org.h2.store.LogFile;
import org.h2.store.LogSystem;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
......
...@@ -10,9 +10,9 @@ import org.h2.command.Prepared; ...@@ -10,9 +10,9 @@ import org.h2.command.Prepared;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.log.UndoLogRecord;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.PlanItem; import org.h2.table.PlanItem;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
......
...@@ -12,10 +12,10 @@ import org.h2.constant.ErrorCode; ...@@ -12,10 +12,10 @@ import org.h2.constant.ErrorCode;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
......
...@@ -14,10 +14,10 @@ import org.h2.engine.Session; ...@@ -14,10 +14,10 @@ import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
......
...@@ -9,7 +9,6 @@ import java.util.HashMap; ...@@ -9,7 +9,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Comparison; import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
...@@ -534,6 +533,8 @@ public class Select extends Query { ...@@ -534,6 +533,8 @@ public class Select extends Query {
if (on != null) { if (on != null) {
if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) { if (!on.isEverything(ExpressionVisitor.EVALUATABLE)) {
f.removeJoinCondition(); f.removeJoinCondition();
// need to check that all added are bound to a table
on = on.optimize(session);
addCondition(on); addCondition(on);
} }
} }
...@@ -544,9 +545,13 @@ public class Select extends Query { ...@@ -544,9 +545,13 @@ public class Select extends Query {
addCondition(on); 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(); f = f.getJoin();
} }
topTableFilter.prepare(); topTableFilter.prepare();
return cost; return cost;
} }
...@@ -621,6 +626,11 @@ public class Select extends Query { ...@@ -621,6 +626,11 @@ public class Select extends Query {
if (isForUpdate) { if (isForUpdate) {
buff.append("\nFOR UPDATE"); buff.append("\nFOR UPDATE");
} }
if (isQuickQuery) {
buff.append("\n/* direct lookup query */");
}
return buff.toString(); return buff.toString();
} }
...@@ -739,13 +749,11 @@ public class Select extends Query { ...@@ -739,13 +749,11 @@ public class Select extends Query {
} }
} }
if (visitor.type == ExpressionVisitor.EVALUATABLE) { if (visitor.type == ExpressionVisitor.EVALUATABLE) {
if (!Constants.OPTIMIZE_EVALUATABLE_SUBQUERIES) { if (!SysProperties.OPTIMIZE_EVALUATABLE_SUBQUERIES) {
return false; return false;
} }
} }
if (visitor.type != ExpressionVisitor.EVALUATABLE) {
visitor.queryLevel(1); visitor.queryLevel(1);
}
boolean result = true; boolean result = true;
for (int i = 0; i < expressions.size(); i++) { for (int i = 0; i < expressions.size(); i++) {
Expression e = (Expression) expressions.get(i); Expression e = (Expression) expressions.get(i);
...@@ -760,9 +768,7 @@ public class Select extends Query { ...@@ -760,9 +768,7 @@ public class Select extends Query {
if (result && having != null && !having.isEverything(visitor)) { if (result && having != null && !having.isEverything(visitor)) {
result = false; result = false;
} }
if (visitor.type != ExpressionVisitor.EVALUATABLE) {
visitor.queryLevel(-1); visitor.queryLevel(-1);
}
return result; return result;
} }
......
...@@ -25,11 +25,15 @@ public class SysProperties { ...@@ -25,11 +25,15 @@ public class SysProperties {
public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5); public static final int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
public static final boolean CHECK = getBooleanSetting("h2.check", true); public static final boolean CHECK = getBooleanSetting("h2.check", true);
public static final boolean CHECK2 = getBooleanSetting("h2.check2", false); 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_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 int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
public static final boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false); 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 OVERFLOW_EXCEPTIONS = getBooleanSetting("h2.overflowExceptions", true);
public static final boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false); public static final boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false);
public static final String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt"); public static final String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt");
...@@ -49,8 +53,6 @@ public class SysProperties { ...@@ -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_DEFAULT = getIntSetting("h2.cacheSizeDefault", 16 * 1024);
public static final int CACHE_SIZE_INDEX_SHIFT = getIntSetting("h2.cacheSizeIndexShift", 3); 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_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 final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED);
public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true); public static boolean runFinalize = getBooleanSetting("h2.runFinalize", true);
public static String scriptDirectory = getStringSetting("h2.scriptDirectory", ""); public static String scriptDirectory = getStringSetting("h2.scriptDirectory", "");
......
...@@ -24,7 +24,9 @@ import org.h2.constant.SysProperties; ...@@ -24,7 +24,9 @@ import org.h2.constant.SysProperties;
* set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_01 * set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_01
* ant codeswitchJdk16 * ant codeswitchJdk16
* ant compile * ant compile
* ant javadocImpl
* ant codeswitchJdk14 * ant codeswitchJdk14
* ant javadocImpl
* *
* - Change FAQ (next release planned, known bugs) * - Change FAQ (next release planned, known bugs)
* - Check version, change build number in Constants.java and ant-build.properties * - Check version, change build number in Constants.java and ant-build.properties
...@@ -169,9 +171,6 @@ public class Constants { ...@@ -169,9 +171,6 @@ public class Constants {
public static final int VIEW_COST_CACHE_MAX_AGE = 10000; // 10 seconds public static final int VIEW_COST_CACHE_MAX_AGE = 10000; // 10 seconds
public static final int MAX_PARAMETER_INDEX = 100000; 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 // to slow down dictionary attacks
public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024; public static final int ENCRYPTION_KEY_HASH_ITERATIONS = 1024;
public static final String SCRIPT_SQL = "script.sql"; public static final String SCRIPT_SQL = "script.sql";
......
...@@ -19,6 +19,8 @@ import org.h2.index.Cursor; ...@@ -19,6 +19,8 @@ import org.h2.index.Cursor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcSQLException;
import org.h2.log.LogSystem;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
...@@ -32,10 +34,8 @@ import org.h2.store.DataPage; ...@@ -32,10 +34,8 @@ import org.h2.store.DataPage;
import org.h2.store.DiskFile; import org.h2.store.DiskFile;
import org.h2.store.FileLock; import org.h2.store.FileLock;
import org.h2.store.FileStore; import org.h2.store.FileStore;
import org.h2.store.LogSystem;
import org.h2.store.RecordReader; import org.h2.store.RecordReader;
import org.h2.store.Storage; import org.h2.store.Storage;
import org.h2.store.UndoLogRecord;
import org.h2.store.WriterThread; import org.h2.store.WriterThread;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.MetaTable; import org.h2.table.MetaTable;
......
...@@ -19,16 +19,16 @@ import org.h2.command.dml.SetTypes; ...@@ -19,16 +19,16 @@ import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.jdbc.JdbcConnection; 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.Message;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.store.DataHandler; 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.table.Table;
import org.h2.util.ObjectUtils; import org.h2.util.ObjectUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
......
...@@ -35,7 +35,7 @@ public class Comparison extends Condition { ...@@ -35,7 +35,7 @@ public class Comparison extends Condition {
private final int compareType; private final int compareType;
private Expression left; private Expression left;
private Expression right; private Expression right;
private int dataType = -1; private int dataType = -2;
public Comparison(Session session, int compareType, Expression left, Expression right) { public Comparison(Session session, int compareType, Expression left, Expression right) {
this.database = session.getDatabase(); this.database = session.getDatabase();
...@@ -318,11 +318,9 @@ public class Comparison extends Condition { ...@@ -318,11 +318,9 @@ public class Comparison extends Condition {
public void addFilterConditions(TableFilter filter, boolean outerJoin) { public void addFilterConditions(TableFilter filter, boolean outerJoin) {
if (compareType == IS_NULL && outerJoin) { if (compareType == IS_NULL && outerJoin) {
// can not optimize: // can not optimize:
// select * from test t1 left join test t2 on t1.id = t2.id where // select * from test t1 left join test t2 on t1.id = t2.id where t2.id is null
// t2.id is null
// to // to
// select * from test t1 left join test t2 on t1.id = t2.id and // select * from test t1 left join test t2 on t1.id = t2.id and t2.id is null
// t2.id is null
return; return;
} }
super.addFilterConditions(filter, outerJoin); super.addFilterConditions(filter, outerJoin);
......
...@@ -11,11 +11,11 @@ import java.util.HashSet; ...@@ -11,11 +11,11 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.store.Storage; import org.h2.store.Storage;
import org.h2.store.UndoLogRecord;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.TableData; import org.h2.table.TableData;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
......
...@@ -840,9 +840,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat ...@@ -840,9 +840,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
* Sets the value of a parameter as an input stream. * Sets the value of a parameter as an input stream.
* *
* @param parameterIndex the parameter index (1, 2, ...) * @param parameterIndex the parameter index (1, 2, ...)
* @param x the value * @param x the value * @throws SQLException if this object is closed
* @param length the number of bytes
* @throws SQLException if this object is closed
*/ */
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
setBinaryStream(parameterIndex, x, -1); setBinaryStream(parameterIndex, x, -1);
......
...@@ -910,7 +910,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -910,7 +910,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/** /**
* Returns the value of the specified column as a Blob. * 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 * @return the value
* @throws SQLException if the column is not found or if the result set is closed * @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 { ...@@ -929,7 +929,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/** /**
* Returns the value of the specified column as a Blob. * 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 * @return the value
* @throws SQLException if the column is not found or if the result set is closed * @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 { ...@@ -1013,7 +1013,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/** /**
* Returns the value of the specified column as a Clob. * 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 * @return the value
* @throws SQLException if the column is not found or if the result set is closed * @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 { ...@@ -1032,7 +1032,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/** /**
* Returns the value of the specified column as a Clob. * 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 * @return the value
* @throws SQLException if the column is not found or if the result set is closed * @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 { ...@@ -1695,7 +1695,6 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
* *
* @param columnIndex (1,2,...) * @param columnIndex (1,2,...)
* @param x the value * @param x the value
* @param length the number of characters
* @throws SQLException if the result set is closed * @throws SQLException if the result set is closed
*/ */
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
...@@ -1740,7 +1739,6 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -1740,7 +1739,6 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
* *
* @param columnName the name of the column label * @param columnName the name of the column label
* @param x the value * @param x the value
* @param length the number of characters
* @throws SQLException if the result set is closed * @throws SQLException if the result set is closed
*/ */
public void updateAsciiStream(String columnName, InputStream x) throws SQLException { public void updateAsciiStream(String columnName, InputStream x) throws SQLException {
...@@ -3029,7 +3027,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -3029,7 +3027,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
/** /**
* Updates a column in the current or insert row. * 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 * @param x the value
* @throws SQLException if the result set is closed * @throws SQLException if the result set is closed
*/ */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 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.store; package org.h2.log;
import java.sql.SQLException; import java.sql.SQLException;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 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.store; package org.h2.log;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -14,17 +14,27 @@ import org.h2.engine.Database; ...@@ -14,17 +14,27 @@ import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.message.Trace; 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.FileUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
/* /**
* Each log file contains a number of log records.
*
* Header format: * Header format:
* intFixed logId (<0 means ignore: rolled back already) * <pre>
* intFixed firstUncommittedLogRecordId (-1 if none) * int logId (<0 means ignore: rolled back already)
* intFixed firstUnwrittenLogRecordId (-1 if none) * int firstUncommittedLogRecordId (-1 if none)
* int firstUnwrittenLogRecordId (-1 if none)
* </pre>
* *
* Record format: * Record format:
* <pre>
* int block size * int block size
* byte 'D' (delete) / 'I' (insert) / 'C' (commit) / 'R' (rollback) / 'P' (prepare commit) / 'T' (truncate) * byte 'D' (delete) / 'I' (insert) / 'C' (commit) / 'R' (rollback) / 'P' (prepare commit) / 'T' (truncate)
* int session * int session
...@@ -34,6 +44,7 @@ import org.h2.util.ObjectArray; ...@@ -34,6 +44,7 @@ import org.h2.util.ObjectArray;
* int record.blockCount * int record.blockCount
* [prepare commit only:] * [prepare commit only:]
* string transaction * string transaction
* </pre>
*/ */
public class LogFile { public class LogFile {
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* 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.store; package org.h2.log;
public class LogRecord { public class LogRecord {
LogFile log; LogFile log;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 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.store; package org.h2.log;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Comparator; import java.util.Comparator;
...@@ -13,12 +13,17 @@ import org.h2.engine.Constants; ...@@ -13,12 +13,17 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Trace; 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.FileUtils;
import org.h2.util.ObjectUtils; import org.h2.util.ObjectUtils;
import org.h2.util.ObjectArray; 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 { public class LogSystem {
......
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
* 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.store; package org.h2.log;
import org.h2.store.Storage;
public class RedoLogRecord { public class RedoLogRecord {
Storage storage; public Storage storage;
int sequenceId; public int sequenceId;
int recordId; public int recordId;
int offset; public int offset;
byte[] data; public byte[] data;
public int getSize() { public int getSize() {
// estimated memory size in bytes ((5 variables+myself) * 4 bytes each) // estimated memory size in bytes ((5 variables+myself) * 4 bytes each)
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
* 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.store; package org.h2.log;
public class SessionState { public class SessionState {
int sessionId; int sessionId;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 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.store; package org.h2.log;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -11,6 +11,8 @@ import org.h2.engine.Constants; ...@@ -11,6 +11,8 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.store.DataPage;
import org.h2.store.FileStore;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
public class UndoLog { public class UndoLog {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* 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.store; package org.h2.log;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -14,6 +14,8 @@ import org.h2.index.Cursor; ...@@ -14,6 +14,8 @@ import org.h2.index.Cursor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.store.DataPage;
import org.h2.store.FileStore;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.Value; import org.h2.value.Value;
......
...@@ -8,6 +8,10 @@ import java.sql.SQLException; ...@@ -8,6 +8,10 @@ import java.sql.SQLException;
import org.h2.value.Value; 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 { public interface DataHandler {
boolean getTextStorage(); boolean getTextStorage();
String getDatabasePath(); String getDatabasePath();
......
...@@ -37,7 +37,7 @@ import org.h2.value.ValueTimestamp; ...@@ -37,7 +37,7 @@ import org.h2.value.ValueTimestamp;
import org.h2.value.ValueUuid; 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 { public abstract class DataPage {
......
...@@ -7,7 +7,8 @@ package org.h2.store; ...@@ -7,7 +7,8 @@ package org.h2.store;
import java.sql.SQLException; 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 { public class DataPageBinary extends DataPage {
// private final static boolean UTF8 = true; // private final static boolean UTF8 = true;
......
...@@ -9,6 +9,11 @@ import java.sql.SQLException; ...@@ -9,6 +9,11 @@ import java.sql.SQLException;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.message.Message; 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 class DataPageText extends DataPage {
public DataPageText(DataHandler handler, byte[] data) { public DataPageText(DataHandler handler, byte[] data) {
......
...@@ -19,6 +19,8 @@ import org.h2.constant.SysProperties; ...@@ -19,6 +19,8 @@ import org.h2.constant.SysProperties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.log.LogSystem;
import org.h2.log.RedoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.util.BitField; import org.h2.util.BitField;
...@@ -33,7 +35,12 @@ import org.h2.util.MathUtils; ...@@ -33,7 +35,12 @@ import org.h2.util.MathUtils;
import org.h2.util.ObjectArray; 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 { public class DiskFile implements CacheWriter {
...@@ -313,7 +320,7 @@ public class DiskFile implements CacheWriter { ...@@ -313,7 +320,7 @@ public class DiskFile implements CacheWriter {
init = true; init = true;
} }
synchronized void flush() throws SQLException { public synchronized void flush() throws SQLException {
database.checkPowerOff(); database.checkPowerOff();
ObjectArray list = cache.getAllChanged(); ObjectArray list = cache.getAllChanged();
CacheObject.sort(list); CacheObject.sort(list);
...@@ -517,7 +524,7 @@ public class DiskFile implements CacheWriter { ...@@ -517,7 +524,7 @@ public class DiskFile implements CacheWriter {
return pageOwners.get(page); 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); int old = pageOwners.get(page);
if (old == storageId) { if (old == storageId) {
return; return;
...@@ -765,7 +772,7 @@ public class DiskFile implements CacheWriter { ...@@ -765,7 +772,7 @@ public class DiskFile implements CacheWriter {
this.logChanges = b; 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; byte[] data = null;
if (rec != null) { if (rec != null) {
DataPage all = rowBuff; DataPage all = rowBuff;
...@@ -797,7 +804,7 @@ public class DiskFile implements CacheWriter { ...@@ -797,7 +804,7 @@ public class DiskFile implements CacheWriter {
} }
} }
synchronized void flushRedoLog() throws SQLException { public synchronized void flushRedoLog() throws SQLException {
if (redoBuffer.size() == 0) { if (redoBuffer.size() == 0) {
return; return;
} }
......
...@@ -12,9 +12,8 @@ import org.h2.engine.Constants; ...@@ -12,9 +12,8 @@ import org.h2.engine.Constants;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
/** /**
* @author Thomas * Utility class to list the files of a database.
*/ */
public class FileLister { public class FileLister {
public static String getDatabaseNameFromFileName(String fileName) { public static String getDatabaseNameFromFileName(String fileName) {
......
...@@ -27,7 +27,8 @@ import org.h2.util.RandomUtils; ...@@ -27,7 +27,8 @@ import org.h2.util.RandomUtils;
import org.h2.util.SortedProperties; 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 { public class FileLock {
......
...@@ -18,6 +18,11 @@ import org.h2.util.ByteUtils; ...@@ -18,6 +18,11 @@ import org.h2.util.ByteUtils;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.TempFileDeleter; 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 class FileStore {
public static final int HEADER_LENGTH = 3 * Constants.FILE_BLOCK_SIZE; public static final int HEADER_LENGTH = 3 * Constants.FILE_BLOCK_SIZE;
......
...@@ -13,6 +13,9 @@ import org.h2.engine.Constants; ...@@ -13,6 +13,9 @@ import org.h2.engine.Constants;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.tools.CompressTool; import org.h2.tools.CompressTool;
/**
* An input stream that is backed by a file store.
*/
public class FileStoreInputStream extends InputStream { public class FileStoreInputStream extends InputStream {
private FileStore store; private FileStore store;
......
...@@ -12,6 +12,9 @@ import org.h2.engine.Constants; ...@@ -12,6 +12,9 @@ import org.h2.engine.Constants;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.tools.CompressTool; import org.h2.tools.CompressTool;
/**
* An output stream that is backed by a file store.
*/
public class FileStoreOutputStream extends OutputStream { public class FileStoreOutputStream extends OutputStream {
private FileStore store; private FileStore store;
private DataPage page; private DataPage page;
......
...@@ -10,6 +10,10 @@ import java.sql.SQLException; ...@@ -10,6 +10,10 @@ import java.sql.SQLException;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.MemoryFile; 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 { public class MemoryFileStore extends FileStore {
private MemoryFile memFile; private MemoryFile memFile;
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
package org.h2.store; package org.h2.store;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.log.LogSystem;
import org.h2.util.CacheObject; 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 { public abstract class Record extends CacheObject {
private boolean deleted; private boolean deleted;
......
...@@ -8,7 +8,7 @@ import java.sql.SQLException; ...@@ -8,7 +8,7 @@ import java.sql.SQLException;
import org.h2.engine.Session; import org.h2.engine.Session;
/** /**
* @author Thomas * A record reader is able to create a {@link Record} from a {@link DataPage}.
*/ */
public interface RecordReader { public interface RecordReader {
Record read(Session session, DataPage s) throws SQLException; Record read(Session session, DataPage s) throws SQLException;
......
...@@ -15,16 +15,22 @@ import org.h2.util.IntArray; ...@@ -15,16 +15,22 @@ import org.h2.util.IntArray;
import org.h2.util.MathUtils; 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: * File format:
* intFixed block size * <pre>
* intFixed storage id * int block size
* int storage id
* record data * record data
* byte checksum * byte checksum
* [bytes * fillerLength] * [bytes * fillerLength]
* * </pre>
* @author Thomas
*/ */
public class Storage { public class Storage {
public static final int ALLOCATE_POS = -1; public static final int ALLOCATE_POS = -1;
......
...@@ -12,6 +12,7 @@ import org.h2.engine.Constants; ...@@ -12,6 +12,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.index.BtreeIndex; import org.h2.index.BtreeIndex;
import org.h2.log.LogSystem;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.table.Table; import org.h2.table.Table;
......
...@@ -34,6 +34,7 @@ import org.h2.expression.ValueExpression; ...@@ -34,6 +34,7 @@ import org.h2.expression.ValueExpression;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.index.MetaIndex; import org.h2.index.MetaIndex;
import org.h2.log.InDoubtTransaction;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
...@@ -42,7 +43,6 @@ import org.h2.schema.Schema; ...@@ -42,7 +43,6 @@ import org.h2.schema.Schema;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject; import org.h2.schema.TriggerObject;
import org.h2.store.DiskFile; import org.h2.store.DiskFile;
import org.h2.store.InDoubtTransaction;
import org.h2.tools.Csv; import org.h2.tools.Csv;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.Resources; import org.h2.util.Resources;
......
...@@ -15,6 +15,7 @@ import org.h2.engine.Right; ...@@ -15,6 +15,7 @@ import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.result.Row; import org.h2.result.Row;
...@@ -25,7 +26,6 @@ import org.h2.schema.Schema; ...@@ -25,7 +26,6 @@ import org.h2.schema.Schema;
import org.h2.schema.SchemaObjectBase; import org.h2.schema.SchemaObjectBase;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject; import org.h2.schema.TriggerObject;
import org.h2.store.UndoLogRecord;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
......
...@@ -19,10 +19,10 @@ import org.h2.engine.Session; ...@@ -19,10 +19,10 @@ import org.h2.engine.Session;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.index.LinkedIndex; import org.h2.index.LinkedIndex;
import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.store.UndoLogRecord;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
......
...@@ -522,7 +522,7 @@ public class Csv implements SimpleRowSource { ...@@ -522,7 +522,7 @@ public class Csv implements SimpleRowSource {
/** /**
* Override the end-of-row marker for writing. The default is null. * Override the end-of-row marker for writing. The default is null.
* *
* @param fieldSeparatorWrite * @param rowSeparatorWrite
*/ */
public void setRowSeparatorWrite(String rowSeparatorWrite) { public void setRowSeparatorWrite(String rowSeparatorWrite) {
this.rowSeparatorWrite = rowSeparatorWrite; this.rowSeparatorWrite = rowSeparatorWrite;
......
...@@ -25,6 +25,7 @@ import org.h2.engine.Constants; ...@@ -25,6 +25,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.MetaRecord; import org.h2.engine.MetaRecord;
import org.h2.log.LogFile;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.SimpleRow; import org.h2.result.SimpleRow;
import org.h2.security.SHA256; import org.h2.security.SHA256;
...@@ -34,7 +35,6 @@ import org.h2.store.DiskFile; ...@@ -34,7 +35,6 @@ import org.h2.store.DiskFile;
import org.h2.store.FileLister; import org.h2.store.FileLister;
import org.h2.store.FileStore; import org.h2.store.FileStore;
import org.h2.store.FileStoreInputStream; import org.h2.store.FileStoreInputStream;
import org.h2.store.LogFile;
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;
......
/* * 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; package org.h2.util;
import java.util.Collection; import java.util.Collection;
......
...@@ -11,6 +11,10 @@ import org.h2.compress.CompressLZF; ...@@ -11,6 +11,10 @@ import org.h2.compress.CompressLZF;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.message.Message; 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 { public class MemoryFile {
private static final int CACHE_SIZE = 8; private static final int CACHE_SIZE = 8;
private static final int BLOCK_SIZE_SHIFT = 16; private static final int BLOCK_SIZE_SHIFT = 16;
......
...@@ -137,37 +137,42 @@ java org.h2.test.TestAll timer ...@@ -137,37 +137,42 @@ java org.h2.test.TestAll timer
test.printSystem(); test.printSystem();
//int testMVCC; //int testMVCC;
// System.setProperty("h2.mvcc", "true"); // 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 add MVCC
......
...@@ -59,9 +59,9 @@ public class TestCrashAPI extends TestBase { ...@@ -59,9 +59,9 @@ public class TestCrashAPI extends TestBase {
// the database in the finalize method // the database in the finalize method
String add = ""; // ";STORAGE=TEXT"; String add = ""; // ";STORAGE=TEXT";
// int testing; int testing;
// add = ";STORAGE=TEXT"; // add = ";STORAGE=TEXT";
if (openCount >= 42 && callCount > 1200 && seed == 437623957) { if (openCount >= 33) {
System.exit(1); System.exit(1);
} }
// add = ";LOG=2"; // add = ";LOG=2";
...@@ -96,6 +96,10 @@ public class TestCrashAPI extends TestBase { ...@@ -96,6 +96,10 @@ public class TestCrashAPI extends TestBase {
String sql = (String) statements.get(i); String sql = (String) statements.get(i);
try { try {
if(openCount == 32 && i == 1219) {
int test;
System.out.println("stop!");
}
stat.execute(sql); stat.execute(sql);
} catch (Throwable t) { } catch (Throwable t) {
printIfBad(seed, -i, -1, t); printIfBad(seed, -i, -1, t);
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- 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); create table test(id smallint primary key);
> ok > ok
...@@ -11,6 +26,12 @@ explain select * from test where id = 1; ...@@ -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 > SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ WHERE ID = 1
> rows: 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; drop table test;
> ok > ok
...@@ -1483,8 +1504,8 @@ select * from test order by id; ...@@ -1483,8 +1504,8 @@ select * from test order by id;
> rows (ordered): 3 > rows (ordered): 3
select rownum, (select count(*) from test), rownum from test; select rownum, (select count(*) from test), rownum from test;
> ROWNUM() SELECT COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ LIMIT 2 ROWNUM() > ROWNUM() SELECT COUNT(*) FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ LIMIT 2 /* direct lookup query */ ROWNUM()
> -------- --------------------------------------------------------------------- -------- > -------- ----------------------------------------------------------------------------------------------- --------
> 1 3 1 > 1 3 1
> 2 3 2 > 2 3 2
> 3 3 3 > 3 3 3
......
...@@ -506,4 +506,6 @@ lightweight builder ...@@ -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 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 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 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论