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

--no commit message

--no commit message
上级 f953f950
<project name="h2" default="all" basedir=".">
<property name="version.name" value="1.0"/>
<property name="version.name" value="1.0.20061217"/>
<property name="jdk" value="1.4"/>
<property name="javac" value="javac"/>
......@@ -60,19 +60,19 @@
<target name="codeswitch_jdk13" depends="codeswitch_prepare">
<java classname="org.h2.tools.code.CodeSwitch" fork="true" dir="src/tools">
<arg line="-JDK14 -JDK16 ../main/org/h2"/>
<arg line="+JDK13 -JDK14 -JDK16 ../main/org/h2"/>
</java>
</target>
<target name="codeswitch_jdk14" depends="codeswitch_prepare">
<java classname="org.h2.tools.code.CodeSwitch" fork="true" dir="src/tools">
<arg line="+JDK14 -JDK16 ../main/org/h2"/>
<arg line="-JDK13 +JDK14 -JDK16 ../main/org/h2"/>
</java>
</target>
<target name="codeswitch_jdk16" depends="codeswitch_prepare">
<java classname="org.h2.tools.code.CodeSwitch" fork="true" dir="src/tools">
<arg line="+JDK16 +JDK14 ../main/org/h2"/>
<arg line="-JDK13 +JDK16 +JDK14 ../main/org/h2"/>
</java>
</target>
......@@ -216,7 +216,25 @@
</copy>
</target>
<target name="mavenBuildCentral">
<copy tofile="bin/h2-${version.name}.jar" file="bin/h2.jar" />
<copy tofile="bin/pom.xml" filtering="true" file="src/installer/pom.xml">
<filterset>
<filter token="version" value="${version.name}"/>
</filterset>
</copy>
<zip destfile="bin/h2-maven-${version.name}.jar" basedir="bin">
<include name="pom.xml" />
<include name="h2-${version.name}.jar" />
</zip>
</target>
<target name="mavenUploadLocal" depends="jar">
<copy tofile="bin/pom.xml" filtering="true" file="src/installer/pom.xml">
<filterset>
<filter token="version" value="1.0-SNAPSHOT"/>
</filterset>
</copy>
<exec executable="mvn.bat">
<arg value="install:install-file"/>
<arg value="-Dversion=1.0-SNAPSHOT"/>
......@@ -224,7 +242,7 @@
<arg value="-DgroupId=org.h2database"/>
<arg value="-DartifactId=h2"/>
<arg value="-Dpackaging=jar"/>
<arg value="-DpomFile=src/installer/pom.xml"/>
<arg value="-DpomFile=bin/pom.xml"/>
</exec>
</target>
......
......@@ -41,6 +41,8 @@ Advanced Topics
Security Protocols</a><br />
<a href="#uuid">
Universally Unique Identifiers (UUID)</a><br />
<a href="#system_properties">
H2 System Properties</a><br />
<a href="#glossary_links">
Glossary and Links</a><br />
......@@ -644,6 +646,48 @@ Some values are:
One's annual risk of being hit by a meteorite is estimated to be one chance in 17 billion,
that means the probability is about 0.000'000'000'06.
<br /><a name="system_properties"></a>
<h2>H2 System Properties</h2>
<p>
Some settings of the database can be set on the command line using
-DpropertyName=value. It is usually not required to change those settings manually.
The settings are case sensitive.
Example:
</p>
<pre>
java -Dh2.serverCachedObjects=256 org.h2.tools.Server
</pre>
<pre>
The current value of the settings can be read in the table
INFORMATION_SCHEMA.SETTINGS
</pre>
<table><tr>
<th>Setting</th>
<th>Default</th>
<th>Description</th></tr>
<tr><td>h2.check</td><td>true</td><td>Assertions in the database engine</td></tr>
<tr><td>h2.check2</td><td>false</td><td>Additional assertions</td></tr>
<tr><td>h2.lobFilesInDirectories</td><td>false</td><td>Store LOB files in subdirectories</td></tr>
<tr><td>h2.lobFilesPerDirectory</td><td>256</td><td>Maximum number of LOB files per directory</td></tr>
<tr><td>h2.multiThreadedKernel</td><td>false</td><td>Allow multiple sessions to run concurrently</td></tr>
<tr><td>h2.runFinalizers</td><td>true</td><td>Run finalizers to detect unclosed connections</td></tr>
<tr><td>h2.optimizeMinMax</td><td>true</td><td>Optimize MIN and MAX aggregate functions</td></tr>
<tr><td>h2.optimizeIn</td><td>true</td><td>Optimize IN(...) comparisons</td></tr>
<tr><td>h2.redoBufferSize</td><td>262144</td><td>Size of the redo buffer (used at startup when recovering)</td></tr>
<tr><td>h2.recompileAlways</td><td>false</td><td>Always recompile prepared statements</td></tr>
<tr><td>h2.optimizeSubqueryCache</td><td>true</td><td>Cache subquery results</td></tr>
<tr><td>h2.overflowExceptions</td><td>true</td><td>Throw an exception on integer overflows</td></tr>
<tr><td>h2.logAllErrors</td><td>false</td><td>Write stack traces of any kind of error to a file</td></tr>
<tr><td>h2.logAllErrorsFile</td><td>h2errors.txt</td><td>File name to log errors</td></tr>
<tr><td>h2.serverCachedObjects</td><td>64</td><td>TCP Server: number of cached objects per session</td></tr>
<tr><td>h2.serverSmallResultSetSize</td><td>100</td><td>TCP Server: result sets below this size are sent in one block</td></tr>
<tr><td>h2.emergencySpaceInitial</td><td>1048576</td><td>Size of 'reserve' file to detect disk full problems early</td></tr>
<tr><td>h2.emergencySpaceMin</td><td>131072</td><td>Minimum size of 'reserve' file</td></tr>
<tr><td>h2.objectCache</td><td>true</td><td>Cache commonly used objects (integers, strings)</td></tr>
<tr><td>h2.objectCacheSize</td><td>1024</td><td>Size of object cache</td></tr>
<tr><td>h2.objectCacheMaxPerElementSize</td><td>4096</td><td>Maximum size of an object in the cache</td></tr>
</table>
<br /><a name="glossary_links"></a>
<h2>Glossary and Links</h2>
<table><tr><th>Term</th><th>Description</th></tr>
......
......@@ -44,7 +44,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Table aliases are now supported in DELETE and UPDATE. Example: DELETE FROM TEST T0.
<li>The RunScript tool can now include other files using a new syntax: @INCLUDE fileName.
It was already possible to do that using embedded RUNSCRIPT statements, but not remotely.
<li>When the database URL contains ;RECOVERY=TRUE then the index file is now deleted if it was not closed before.
<li>When the database URL contains ;RECOVER=1 then the index file is now deleted if it was not closed before.
<li>The scale of a NUMERIC(1) column is now 0. It used to be 32767.
<li>Deleting old temp files now uses a phantom reference queue. Generally, temp files should now be deleted
earlier.
......@@ -1345,7 +1345,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Documentation (FAQ) for how to connect to H2
<li>Improve performance for create table (if this is possible)
<li>Test with Spatial DB in a box / JTS (http://docs.codehaus.org/display/GEOS/SpatialDBBox)
<li>Document how to use H2 with PHP
<li>Document how to use H2 with PHP (generic database API)
<li>Optimization: result set caching (like MySQL)
<li>Server side cursors
<li>Row level locking
......@@ -1367,7 +1367,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Read-only databases inside a jar
<li>SET variable { TO | = } { value | 'value' | DEFAULT }
<li>Running totals: select @running:=if(@previous=t.ID,@running,0)+t.NUM as TOTAL, @previous:=t.ID
<li>Deleted LOB files after transaction is committed. Keep set of 'to be deleted' lobs files to the session (remove from the list on rollback)
<li>Support SET REFERENTIAL_INTEGRITY {TRUE|FALSE}
<li>Backup of BLOB / CLOB: use a stream for backup, use a block append function to restore.
</ul>
......@@ -1420,7 +1419,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Make the jar more modular
<li>Document obfuscator usage
<li>Drop with restrict (currently cascade is the default)
<li>SCRIPT to pretty-print (at least Create Table)
<li>Document ConvertTraceToJava in javadoc and features
<li>Document limitation (line length) of find "**" test.trace.db > Trace.java
<li>Tiny XML parser (ignoring unneeded stuff)
......@@ -1455,22 +1453,18 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Functional tables should accept parameters from other tables (see FunctionMultiReturn)
SELECT * FROM TEST T, P2C(T.A, T.R)
<li>Custom class loader to reload functions on demand
<li>Public CVS access
<li>Count index range query (count where id between 10 and 20)
<li>Test http://mysql-je.sourceforge.net/
<li>Close all files when closing the database (including LOB files that are open on the client side)
<li>Test Connection Pool http://jakarta.apache.org/commons/dbcp
<li>Should not print stack traces when killing the tests
<li>Implement Statement.cancel for server connections
<li>Should not throw a NullPointerException when closing the connection while an operation is running (TestCases.testDisconnect)
<li>Profiler option or profiling tool to find long running and often repeated queries
<li>Function to read/write a file from/to LOB
<li>Allow custom settings (@PATH for RUNSCRIPT for example)
<li>RUNSCRIPT: SET SCRIPT_PATH or similar to be used by RUNSCRIPT (and maybe SCRIPT)
<li>Performance test: read the data (getString) and use column names to get the data
<li>EXE file: maybe use http://jsmooth.sourceforge.net
<li>System Tray: http://jroller.com/page/stritti?entry=system_tray_implementations_for_java
<li>Test with GCJ: http://javacompiler.mtsystems.ch/
<li>SELECT ... FOR READ WAIT [maxMillisToWait]
<li>Automatically delete the index file if opening it fails
<li>Performance: Automatically build in-memory indexes if the whole table is in memory
......@@ -1482,7 +1476,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Support a property isDeterministic for Java functions
<li>SQL 2003 (http://www.wiscorp.com/sql_2003_standard.zip)
<li>http://www.jpackage.org
<li>Replace deleteOnExit with a weak reference map, or a simple loop on exit
<li>Version column (number/sequence and timestamp based)
<li>Optimize getGeneratedKey: (include last identity after each execute).
<li>Clustering: recovery needs to becomes fully automatic.
......@@ -1598,6 +1591,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>Support updatable views with join on primary keys (to extend a table)
<li>File_Read / File_Store funktionen: FILE_STORE('test.sql', ?), FILE_READ('test.sql')
<li>Public interface for functions (not public static)
<li>Index usage for IN(...), IN_ARRAY(..), and IN_ARRAY_RANGES(..); support ARRAY in JDBC API (variable size)
</ul>
<h3>Not Planned</h3>
......
......@@ -28,7 +28,7 @@ hiding the fact that it was, in fact, just HSQLDB. At this time, it seems 'bungi
Wayback Machine of http://www.archive.org and look for old web pages of http://www.bungisoft.com.
<p>
About porting the source code to another language (for example C# or C++): Converted source code (even if done manually) stays under the same
copyright and license as the original code. The copyright of the ported source code does not (automatically) go to the person ported the code.
copyright and license as the original code. The copyright of the ported source code does not (automatically) go to the person who ported the code.
<h2>H2 License, Version 1.0</h2>
......
......@@ -27,6 +27,7 @@ public abstract class Command implements CommandInterface {
public abstract boolean isTransactional();
public abstract boolean isQuery();
public abstract ObjectArray getParameters();
public abstract boolean isReadOnly();
public Command(Parser parser) {
this.session = parser.getSession();
......
......@@ -73,4 +73,8 @@ public class CommandContainer extends Command {
return prepared.query(maxrows);
}
public boolean isReadOnly() {
return prepared.isReadOnly();
}
}
......@@ -55,4 +55,8 @@ public class CommandList extends Command {
return true;
}
public boolean isReadOnly() {
return false;
}
}
......@@ -24,6 +24,7 @@ public class CommandRemote implements CommandInterface {
private ObjectArray transferList;
private int id;
private boolean isQuery;
private boolean readonly;
private ObjectArray parameters;
private Trace trace;
private String sql;
......@@ -39,6 +40,7 @@ public class CommandRemote implements CommandInterface {
transfer.writeInt(SessionRemote.SESSION_PREPARE).writeInt(id).writeString(sql);
session.done(transfer);
isQuery = transfer.readBoolean();
readonly = transfer.readBoolean();
paramCount = transfer.readInt();
} catch(IOException e) {
session.removeServer(i);
......@@ -77,7 +79,6 @@ public class CommandRemote implements CommandInterface {
}
int objectId = session.getNextId();
ResultRemote result = null;
// TODO cluster: test sequences and so on
for(int i=0; i<transferList.size(); i++) {
Transfer transfer = (Transfer) transferList.get(i);
try {
......@@ -99,6 +100,9 @@ public class CommandRemote implements CommandInterface {
result = null;
}
result = new ResultRemote(session, transfer, objectId, columnCount, readRows);
if(readonly) {
break;
}
} catch(IOException e) {
session.removeServer(i);
}
......
......@@ -38,6 +38,10 @@ public abstract class Prepared {
public abstract boolean isTransactional();
public boolean isReadOnly() {
return false;
}
public Prepared(Session session) {
this.session = session;
modificationId = session.getDatabase().getModificationMetaId();
......
......@@ -17,4 +17,8 @@ public abstract class DefineCommand extends Prepared {
return false;
}
public boolean isReadOnly() {
return false;
}
}
......@@ -10,6 +10,7 @@ import org.h2.command.Prepared;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.expression.ExpressionVisitor;
import org.h2.result.LocalResult;
import org.h2.table.Column;
import org.h2.util.ObjectArray;
......@@ -74,4 +75,9 @@ public class Call extends Prepared {
return true;
}
public boolean isReadOnly() {
return value.isEverything(ExpressionVisitor.READONLY);
}
}
......@@ -59,4 +59,8 @@ public class ExplainPlan extends Prepared {
public boolean isTransactional() {
return true;
}
public boolean isReadOnly() {
return true;
}
}
......@@ -29,4 +29,8 @@ public class NoOperation extends Prepared {
return false;
}
public boolean isReadOnly() {
return true;
}
}
......@@ -714,4 +714,8 @@ public class Select extends Query {
return result;
}
public boolean isReadOnly() {
return isEverything(ExpressionVisitor.READONLY);
}
}
......@@ -298,4 +298,8 @@ public class SelectUnion extends Query {
return left.isEverything(visitor) && right.isEverything(visitor);
}
public boolean isReadOnly() {
return left.isReadOnly() && right.isReadOnly();
}
}
......@@ -89,7 +89,6 @@ public class Constants {
public static final int DEFAULT_CACHE_SIZE = 1 << 16;
public static final int CACHE_SIZE_INDEX_SHIFT = 3;
public static int CACHE_MIN_RECORDS = 16;
public static final int DEFAULT_CACHE_SIZE_INDEX = DEFAULT_CACHE_SIZE >> CACHE_SIZE_INDEX_SHIFT;
public static final int DEFAULT_CACHE_SIZE_LINEAR_INDEX = 1 << 8;
......@@ -114,10 +113,6 @@ public class Constants {
public static final int DEFAULT_DATA_PAGE_SIZE = 512;
public static final boolean USE_OBJECT_CACHE = true;
public static final int OBJECT_CACHE_SIZE = 1024;
public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = 4096;
public static final String PRIMARY_KEY_PREFIX = "PRIMARY_KEY_";
public static final int LOCK_SLEEP = 1000;
......@@ -132,8 +127,6 @@ public class Constants {
public static final boolean DEFAULT_HTTP_ALLOW_OTHERS = false;
public static final int DEFAULT_FTP_PORT = 8021;
public static boolean MULTI_THREADED_KERNEL;
public static final int DEFAULT_MAX_MEMORY_ROWS = 10000;
public static final int DEFAULT_MAX_MEMORY_UNDO = Integer.MAX_VALUE;
......@@ -162,9 +155,6 @@ public class Constants {
public static final String CLUSTERING_DISABLED = "''";
public static final int EMERGENCY_SPACE_INITIAL = 1 * 1024 * 1024;
public static final int EMERGENCY_SPACE_MIN = 128 * 1024;
public static final int LOCK_MODE_OFF = 0;
public static final int LOCK_MODE_TABLE = 1;
public static final int LOCK_MODE_TABLE_GC = 2;
......@@ -174,40 +164,16 @@ public class Constants {
public static final int SELECTIVITY_DEFAULT = 50;
public static final int SELECTIVITY_ANALYZE_SAMPLE_ROWS = 10000;
public static final int SERVER_CACHED_OBJECTS = 64;
public static final int SERVER_SMALL_RESULTSET_SIZE = 100;
public static final boolean LOG_ALL_ERRORS = false;
// the cost is calculated on rowcount + this offset, to avoid using the wrong or no index
// if the table contains no rows _currently_ (when preparing the statement)
public static final int COST_ROW_OFFSET = 1000;
public static final long FLUSH_INDEX_DELAY = 0;
public static final int THROTTLE_DELAY = 50;
public static boolean RUN_FINALIZERS = true;
// TODO performance: change this values and recompile for higher performance
public static boolean CHECK = true;
public static boolean CHECK2;
public static final String MANAGEMENT_DB_PREFIX = "management_db_";
public static final String MANAGEMENT_DB_USER = "sa";
public static int REDO_BUFFER_SIZE = 256 * 1024;
public static final boolean SERIALIZE_JAVA_OBJECTS = true;
public static boolean RECOMPILE_ALWAYS;
public static boolean OPTIMIZE_SUBQUERY_CACHE = true;
public static boolean OVERFLOW_EXCEPTIONS = true;
public static boolean LOB_FILES_IN_DIRECTORIES;
// TODO: also remove DataHandler.allocateObjectId, createTempFile when setting this to true and removing it
public static int LOB_FILES_PER_DIRECTORY = 256;
public static boolean OPTIMIZE_MIN_MAX = true;
public static boolean OPTIMIZE_IN = true;
// TODO there is a bug currently, need to refactor & debug the code to fix this (and add more tests!)
public static boolean OPTIMIZE_EVALUATABLE_SUBQUERIES;
public static final long DEFAULT_MAX_LOG_SIZE = 32 * 1024 * 1024;
public static final long LOG_SIZE_DIVIDER = 10;
......@@ -217,8 +183,6 @@ public class Constants {
public static final int DEFAULT_ALLOW_LITERALS = ALLOW_LITERALS_ALL;
public static boolean AUTO_CONVERT_LOB_TO_FILES = true;
public static int MIN_WRITE_DELAY = 5;
public static final boolean ALLOW_EMTPY_BTREE_PAGES = true;
public static final String CONN_URL_INTERNAL = "jdbc:default:connection";
public static final String CONN_URL_COLUMNLIST = "jdbc:columnlist:connection";
......@@ -227,8 +191,70 @@ 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";
// for testing only
public static int CACHE_MIN_RECORDS = 16;
public static int MIN_WRITE_DELAY = getIntSetting("h2.minWriteDelay", 5);
public static boolean CHECK = getBooleanSetting("h2.check", true);
public static boolean CHECK2 = getBooleanSetting("h2.check2", false);
// TODO: also remove DataHandler.allocateObjectId, createTempFile when setting this to true and removing it
public static boolean LOB_FILES_IN_DIRECTORIES = getBooleanSetting("h2.lobFilesInDirectories", false);
public static int LOB_FILES_PER_DIRECTORY = getIntSetting("h2.lobFilesPerDirectory", 256);
public static boolean MULTI_THREADED_KERNEL = getBooleanSetting("h2.multiThreadedKernel", false);
public static boolean RUN_FINALIZERS = getBooleanSetting("h2.runFinalizers", true);
public static boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
public static boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
public static int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
public static boolean RECOMPILE_ALWAYS = getBooleanSetting("h2.recompileAlways", false);
public static boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
public static boolean OVERFLOW_EXCEPTIONS = getBooleanSetting("h2.overflowExceptions", true);
public static boolean LOG_ALL_ERRORS = getBooleanSetting("h2.logAllErrors", false);
public static String LOG_ALL_ERRORS_FILE = getStringSetting("h2.logAllErrorsFile", "h2errors.txt");
public static int SERVER_CACHED_OBJECTS = getIntSetting("h2.serverCachedObjects", 64);
public static final int SERVER_SMALL_RESULTSET_SIZE = getIntSetting("h2.serverSmallResultSetSize", 100);
public static final int EMERGENCY_SPACE_INITIAL = getIntSetting("h2.emergencySpaceInitial", 1 * 1024 * 1024);
public static final int EMERGENCY_SPACE_MIN = getIntSetting("h2.emergencySpaceMin", 128 * 1024);
public static final boolean OBJECT_CACHE = getBooleanSetting("h2.objectCache", true);
public static final int OBJECT_CACHE_SIZE = getIntSetting("h2.objectCacheSize", 1024);
public static final int OBJECT_CACHE_MAX_PER_ELEMENT_SIZE = getIntSetting("h2.objectCacheMaxPerElementSize", 4096);
public static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = System.getProperty(name);
if(s != null) {
try {
return Boolean.valueOf(s).booleanValue();
} catch(NumberFormatException e) {
}
}
return defaultValue;
}
public static String getStringSetting(String name, String defaultValue) {
String s = System.getProperty(name);
return s == null ? defaultValue : s;
}
public static int getIntSetting(String name, int defaultValue) {
String s = System.getProperty(name);
if(s != null) {
try {
return Integer.decode(s).intValue();
} catch(NumberFormatException e) {
}
}
return defaultValue;
}
}
......@@ -207,6 +207,7 @@ public class ExpressionColumn extends Expression {
switch(visitor.type) {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return false;
case ExpressionVisitor.READONLY:
case ExpressionVisitor.DETERMINISTIC:
return true;
case ExpressionVisitor.INDEPENDENT:
......
......@@ -22,6 +22,9 @@ public class ExpressionVisitor {
// Request to set the latest modification id
public static final int SET_MAX_DATA_MODIFICATION_ID = 4;
// Does the expression have no side effects (change the data)?
public static final int READONLY = 5;
int queryLevel;
public Table table;
public int type;
......
......@@ -89,7 +89,7 @@ public class Function extends Expression implements FunctionCall {
public static final int IFNULL = 200, CASEWHEN = 201, CONVERT = 202, CAST = 203,
COALESCE = 204, NULLIF = 205, CASE = 206, NEXTVAL = 207, CURRVAL = 208,
ARRAY_GET = 209, CSVREAD = 210, CSVWRITE = 211, MEMORY_FREE = 212,
MEMORY_USED = 213, LOCK_MODE = 214, SCHEMA = 215, SESSION_ID = 216;
MEMORY_USED = 213, LOCK_MODE = 214, SCHEMA = 215, SESSION_ID = 216, ARRAY_LENGTH = 217;
private static final int VARARGS = -1;
......@@ -277,6 +277,7 @@ public class Function extends Expression implements FunctionCall {
addFunctionNotConst("LOCK_MODE", LOCK_MODE, 0, Value.INT);
addFunctionNotConst("SCHEMA", SCHEMA, 0, Value.STRING);
addFunctionNotConst("SESSION_ID", SESSION_ID, 0, Value.INT);
addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT);
}
private static void addFunction(String name, int type, int parameterCount,
......@@ -395,6 +396,13 @@ public class Function extends Expression implements FunctionCall {
}
return ValueNull.INSTANCE;
}
case ARRAY_LENGTH: {
if(v0.getType() == Value.ARRAY) {
Value[] list = ((ValueArray) v0).getList();
return ValueInt.get(list.length);
}
return ValueNull.INSTANCE;
}
default:
// ok
}
......
......@@ -87,6 +87,7 @@ public class Parameter extends Expression implements ParameterInterface {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return value != null;
......
......@@ -68,6 +68,8 @@ public class Rownum extends Expression {
case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
// if everything else is the same, the rownum is the same
return true;
case ExpressionVisitor.READONLY:
return true;
default:
throw Message.getInternalError("type="+visitor.type);
}
......
......@@ -70,6 +70,7 @@ public class SequenceValue extends Expression {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return false;
case ExpressionVisitor.INDEPENDENT:
return false;
......
......@@ -82,6 +82,7 @@ public class ValueExpression extends Expression {
case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
return true;
case ExpressionVisitor.DETERMINISTIC:
case ExpressionVisitor.READONLY:
return true;
case ExpressionVisitor.INDEPENDENT:
return true;
......
......@@ -123,7 +123,8 @@ int count;
if(storage != null) {
storage.flushFile();
deletePage(session, head);
int todoCheckAndDocumentThisCondition;
// if we log index changes now, then the index is consistent
// if we don't log index changes, then the index is only consistent if there are no in doubt transactions
if(database.getLogIndexChanges() || !database.getLog().containsInDoubtTransactions()) {
head.setConsistent(true);
}
......@@ -166,6 +167,7 @@ int count;
public void remove(Session session, Row row) throws SQLException {
setChanged(session);
if(rowCount == 1) {
// TODO performance: maybe improve truncate performance in this case
truncate(session);
} else {
root.remove(session, row, 0);
......
......@@ -99,7 +99,7 @@ public class BtreeLeaf extends BtreePage {
}
if(comp == 0) {
index.deletePage(session, this);
if(pageData.size()==1) {
if(pageData.size()==1 && !root) {
// the last row has been deleted
return oldRow;
}
......@@ -109,10 +109,14 @@ public class BtreeLeaf extends BtreePage {
if(i > 0) {
// the first row didn't change
return null;
} else {
if(pageData.size() == 0) {
return null;
} else {
return getData(0);
}
}
}
if(comp > 0) {
r = i;
} else {
......@@ -126,10 +130,10 @@ public class BtreeLeaf extends BtreePage {
ObjectArray data = new ObjectArray();
int max = pageData.size();
int test;
// if(Constants.CHECK && index.getDatabase().getLogIndexChanges() && !getDeleted()) {
// page must have been deleted already before calling getSplitPoint()
// throw Message.getInternalError();
// }
if(Constants.CHECK && index.getDatabase().getLogIndexChanges() && !getDeleted()) {
// page must have been deleted already before calling getSplitPoint()
throw Message.getInternalError();
}
for (int i = splitPoint; i < max; i++) {
data.add(getData(splitPoint));
pageData.remove(splitPoint);
......
......@@ -177,10 +177,10 @@ public class BtreeNode extends BtreePage {
splitPoint++;
int max = pageData.size();
int test;
// if(Constants.CHECK && index.getDatabase().getLogIndexChanges() && !getDeleted()) {
if(Constants.CHECK && index.getDatabase().getLogIndexChanges() && !getDeleted()) {
// page must have been deleted already before calling getSplitPoint()
// throw Message.getInternalError();
// }
throw Message.getInternalError();
}
for (int i = splitPoint; i < max; i++) {
data.add(getData(splitPoint));
children.add(getChild(splitPoint));
......
......@@ -103,7 +103,14 @@ public class Message {
}
public static Error getInternalError(String s, Exception e) {
//#ifdef JDK14
Error e2 = new Error(s, e);
//#endif
//#ifdef JDK13
/*
Error e2 = new Error(s);
*/
//#endif
TraceSystem.traceThrowable(e2);
return e2;
}
......
......@@ -161,7 +161,7 @@ public class TraceObject {
synchronized(this.getClass()) {
// e.printStackTrace();
try {
FileWriter writer = new FileWriter("c:\\temp\\h2error.txt", true);
FileWriter writer = new FileWriter(Constants.LOG_ALL_ERRORS_FILE, true);
PrintWriter p = new PrintWriter(writer);
e.printStackTrace(p);
p.close();
......
......@@ -157,10 +157,11 @@ public class TcpServerThread implements Runnable {
int id = transfer.readInt();
String sql = transfer.readString();
Command command = session.prepareLocal(sql);
boolean readonly = command.isReadOnly();
cache.addObject(id, command);
boolean isQuery = command.isQuery();
int paramCount = command.getParameters().size();
transfer.writeInt(SessionRemote.STATUS_OK).writeBoolean(isQuery).writeInt(paramCount).flush();
transfer.writeInt(SessionRemote.STATUS_OK).writeBoolean(isQuery).writeBoolean(readonly).writeInt(paramCount).flush();
break;
}
case SessionRemote.SESSION_CLOSE: {
......
......@@ -236,7 +236,7 @@ public abstract class DataPage {
default:
throw Message.getInternalError("type=" + v.getType());
}
if(Constants.CHECK) {
if(Constants.CHECK2) {
if(pos - start != getValueLen(v)) {
throw Message.getInternalError("value size error: got " + (pos-start) + " expected " + getValueLen(v));
}
......
......@@ -649,6 +649,27 @@ public class MetaTable extends Table {
add(rows, new String[]{"FILE_INDEX_READ", "" + database.getIndexFile().getReadCount()});
}
}
add(rows, new String[]{"h2.check", "" + Constants.CHECK});
add(rows, new String[]{"h2.check2", "" + Constants.CHECK2});
add(rows, new String[]{"h2.lobFilesInDirectories", "" + Constants.LOB_FILES_IN_DIRECTORIES});
add(rows, new String[]{"h2.lobFilesPerDirectory", "" + Constants.LOB_FILES_PER_DIRECTORY});
add(rows, new String[]{"h2.multiThreadedKernel", "" + Constants.MULTI_THREADED_KERNEL});
add(rows, new String[]{"h2.runFinalizers", "" + Constants.RUN_FINALIZERS});
add(rows, new String[]{"h2.optimizeMinMax", "" + Constants.OPTIMIZE_MIN_MAX});
add(rows, new String[]{"h2.optimizeIn", "" + Constants.OPTIMIZE_IN});
add(rows, new String[]{"h2.redoBufferSize", "" + Constants.REDO_BUFFER_SIZE});
add(rows, new String[]{"h2.recompileAlways", "" + Constants.RECOMPILE_ALWAYS});
add(rows, new String[]{"h2.optimizeSubqueryCache", "" + Constants.OPTIMIZE_SUBQUERY_CACHE});
add(rows, new String[]{"h2.overflowExceptions", "" + Constants.OVERFLOW_EXCEPTIONS});
add(rows, new String[]{"h2.logAllErrors", "" + Constants.LOG_ALL_ERRORS});
add(rows, new String[]{"h2.logAllErrorsFile", "" + Constants.LOG_ALL_ERRORS_FILE});
add(rows, new String[]{"h2.serverCachedObjects", "" + Constants.SERVER_CACHED_OBJECTS});
add(rows, new String[]{"h2.serverSmallResultSetSize", "" + Constants.SERVER_SMALL_RESULTSET_SIZE});
add(rows, new String[]{"h2.emergencySpaceInitial", "" + Constants.EMERGENCY_SPACE_INITIAL});
add(rows, new String[]{"h2.emergencySpaceMin", "" + Constants.EMERGENCY_SPACE_MIN});
add(rows, new String[]{"h2.objectCache", "" + Constants.OBJECT_CACHE});
add(rows, new String[]{"h2.objectCacheSize", "" + Constants.OBJECT_CACHE_SIZE});
add(rows, new String[]{"h2.objectCacheMaxPerElementSize", "" + Constants.OBJECT_CACHE_MAX_PER_ELEMENT_SIZE});
break;
}
case TYPE_INFO: {
......
......@@ -357,15 +357,15 @@ public class TableData extends Table implements RecordReader {
buff.append(" COMMENT ");
buff.append(StringUtils.quoteStringSQL(comment));
}
buff.append('(');
buff.append("(\n ");
for (int i = 0; i < columns.length; i++) {
Column column = columns[i];
if (i > 0) {
buff.append(", ");
buff.append(",\n ");
}
buff.append(column.getCreateSQL());
}
buff.append(")");
buff.append("\n)");
return buff.toString();
}
......
......@@ -108,9 +108,9 @@ public class TableView extends Table {
}
buff.append(columns[i].getSQL());
}
buff.append(')');
buff.append(")");
}
buff.append(" AS ");
buff.append(" AS\n");
buff.append(querySQL);
return buff.toString();
}
......
......@@ -62,7 +62,7 @@ public class Recover implements DataHandler {
private boolean log;
private void showUsage() {
System.out.println("java "+getClass().getName()+" [-dir <dir>] [-db <database>]");
System.out.println("java "+getClass().getName()+" [-dir <dir>] [-db <database>] [-log true]");
}
/**
......@@ -104,7 +104,7 @@ public class Recover implements DataHandler {
if(removePassword) {
removePassword(dir, db);
} else {
execute(dir, db);
process(dir, db);
}
}
......@@ -260,7 +260,8 @@ public class Recover implements DataHandler {
} else if(fileName.endsWith(Constants.SUFFIX_LOG_FILE)) {
dumpLog(fileName);
} else if(fileName.endsWith(Constants.SUFFIX_LOB_FILE)) {
dumpLob(fileName);
dumpLob(fileName, true);
dumpLob(fileName, false);
}
}
}
......@@ -283,6 +284,8 @@ public class Recover implements DataHandler {
sb.append('?');
}
}
writer.println("-- dump: " + sb.toString());
sb = new StringBuffer();
for(int i=0; i<dumpBlocks * DiskFile.BLOCK_SIZE; i++) {
int x = (data[i] & 0xff);
sb.append(' ');
......@@ -294,17 +297,17 @@ public class Recover implements DataHandler {
writer.println("-- dump: " + sb.toString());
}
private void dumpLob(String fileName) {
private void dumpLob(String fileName, boolean lobCompression) {
FileOutputStream out = null;
FileStore store = null;
try {
out = new FileOutputStream(fileName + ".txt");
String n = fileName + (lobCompression ? ".comp" : "") + ".txt";
out = new FileOutputStream(n);
textStorage = Database.isTextStorage(fileName, false);
byte[] magic = Database.getMagic(textStorage);
store = FileStore.open(null, fileName, magic);
store.init();
boolean compression = true;
InputStream in = new BufferedInputStream(new FileStoreInputStream(store, this, compression));
InputStream in = new BufferedInputStream(new FileStoreInputStream(store, this, lobCompression));
byte[] buffer = new byte[Constants.IO_BUFFER_SIZE];
while(true) {
int l = in.read(buffer);
......@@ -583,8 +586,13 @@ public class Recover implements DataHandler {
continue;
}
if(blockCount > 1) {
if((blockCount * blockSize) < 0) {
writeDataError(writer, "wrong blockCount", s.getBytes(), 1);
blockCount = 1;
} else {
store.readFully(s.getBytes(), blockSize, blockCount * blockSize - blockSize);
}
}
try {
s.check(blockCount * blockSize);
} catch(SQLException e) {
......
......@@ -329,14 +329,6 @@ public class FileUtils {
return f.getCanonicalPath();
}
// public static void deleteOnExit(String temp) {
// if(isInMemory(temp)) {
// // nothing to do
// return;
// }
// new File(temp).deleteOnExit();
// }
public static String getParent(String fileName) {
if(isInMemory(fileName)) {
return MEMORY_PREFIX;
......
......@@ -46,7 +46,7 @@ public class StringCache {
// 3906
public static String get(String s) {
if (!Constants.USE_OBJECT_CACHE || !ENABLED) {
if (!Constants.OBJECT_CACHE || !ENABLED) {
return s;
}
if (s == null) {
......@@ -73,7 +73,7 @@ public class StringCache {
}
public static String getNew(String s) {
if (!Constants.USE_OBJECT_CACHE || !ENABLED) {
if (!Constants.OBJECT_CACHE || !ENABLED) {
return s;
}
if (s == null) {
......
......@@ -283,12 +283,19 @@ public class StringUtils {
}
public static String urlEncode(String s) {
//#ifdef JDK14
try {
return URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return s;
}
//#endif
//#ifdef JDK13
/*
return URLEncoder.encode(s);
*/
//#endif
// byte[] utf = utf8Encode(s);
// StringBuffer buff = new StringBuffer(utf.length);
// for(int i=0; i<utf.length; i++) {
......@@ -393,7 +400,14 @@ public class StringUtils {
if(locale == null) {
df = new SimpleDateFormat(format);
} else {
//#ifdef JDK14
Locale l = new Locale(locale);
//#endif
//#ifdef JDK13
/*
Locale l = new Locale(locale, "");
*/
//#endif
df = new SimpleDateFormat(format, l);
}
if(timezone != null) {
......
......@@ -158,6 +158,11 @@ public class DataType {
createString(true),
new String[]{"CLOB", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "NTEXT", "NCLOB"}
);
add(Value.ARRAY, Types.ARRAY, "Array",
createString(false),
new String[]{"ARRAY"}
);
// TODO data types: try to support other types as well (longvarchar for odbc/access,...) - maybe map them to regular types?
}
......
......@@ -53,7 +53,7 @@ public abstract class Value {
private static final BigDecimal MIN_LONG_DECIMAL = new BigDecimal("" + Long.MIN_VALUE);
static Value cache(Value v) {
if (Constants.USE_OBJECT_CACHE) {
if (Constants.OBJECT_CACHE) {
Value[] cache = (Value[]) weakCache.get();
int hash = v.hashCode();
if (cache == null) {
......
......@@ -349,7 +349,6 @@ public class ValueLob extends Value {
FileUtils.delete(temp);
// rename the current file to the temp file
FileUtils.rename(fileName, temp);
// FileUtils.deleteOnExit(temp);
tempFile = FileStore.open(handler, temp, null);
tempFile.autoDelete();
tempFile.closeSilently();
......
......@@ -86,7 +86,41 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
TestAll test = new TestAll();
test.printSystem();
// codeswitch_jdk13 doesnt work? (in FAQ)
int todoSendMail;
// here's the whole enchilada
// delete the index and log file
//create table test(id int, data array)
//document array_get, array_length
// todo: document system properties in advancaed
// lobs: rename / delete: need to check if rename works if stop in the middle
// options for java functions: readonly, deterministic
// document cluster: not allowed operations: update/insert with random data (however in a readonly select it is ok)
// test & document cluster: read only selects only go to the first cluster node
// test & document settings via -Dh2.check=false
// set path=C:\Programme\Java\jdk1.6.0\bin;%PATH%
// There is one thing I forgot: you need to change the in the build script
// <property name="jdk" value="1.4"/> to
// <property name="jdk" value="1.6"/>
new TestCrashAPI().init(test).testCase(1656916106); // Bug 2111148370 seed=1656916106 id=-1834 callCount=1787 openCount=50 General error: java.lang.Error: 0 blocks to read pos=192 [HY000-34]
new TestCrashAPI().init(test).testCase(437623957); // Bug -1343599238 seed=437623957 id=-1317 callCount=1289 openCount=42 General error: java.lang.OutOfMemoryError: Java heap space [HY000-34]
// add to maven
// http://jira.codehaus.org/browse/MAVENUPLOAD-1276
// http://maven.apache.org/guides/mini/guide-ibiblio-upload.html
// java -agentlib:yjpagent=sampling,noj2ee,dir=C:\temp\Snapshots org.h2.test.bench.TestPerformance -init -db 1
// Check if new Hibernate dialect for H2 is ok
// http://opensource.atlassian.com/projects/hibernate/browse/HHH-2300
......@@ -100,9 +134,8 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
// value="DriverClassName=org.h2.Driver,Url=jdbc:h2:c:/temp/openjpa,MaxActive=100,MaxWait=10000,TestOnBorrow=true"/>
// D:\data\h2test\openjpa\openjpa-persistence-jdbc>mvn test
// add H2 to maven
// OSGi Bundle (see Forum)
// Test and document JDK 1.6 QueryObjectFactory
// QueryObjectFactory
// test with PostgreSQL Version 8.2
......@@ -116,9 +149,13 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
// GRANT select ON new_product_view TO hr;
// http://dev.helma.org/Wiki/RhinoLoader
// use version numbers 1.0.4 and so on
// Fulltext search: Use reader for CLOB data, special reader tokenizer
// Checkstyle to verify HTML docs
// test multithreading access to blobs (one thread reads from the inputstream, the other deletes the row using the same connection)
// Dezign for Databases (http://www.datanamic.com
// SET LOCK_MODE 3 not persistent, document how to set it in the database URL
......@@ -132,8 +169,6 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
// by some other transaction when it commits. In this isolation level, read locks are not acquired on selected data.
// test with garbage at the end of the log file (must be consistently detected as such)
// describe differences between databases (Migration Guide; HSQLDB most important)
// Maven
// http://maven.apache.org/guides/mini/guide-ibiblio-upload.html
// test LIKE: compare against other databases
// autocomplete: if I type the name of a table that does not exist (should say: syntax not supported)
// autocomplete: schema support: "Other Grammar","Table Expression","{[schemaName.]tableName | (select)} [[AS] newTableAlias]
......@@ -154,7 +189,6 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
// - Datasource URL: jdbc:h2:c:/temp/test;TRACE_LEVEL_FILE=3
// - JDBC driver class: org.h2.Driver [Test class]
if(args.length>0) {
if("crash".equals(args[0])) {
new TestCrashAPI().runTest(test);
......
......@@ -66,9 +66,9 @@ public class TestCrashAPI extends TestBase {
// int testing;
// add = ";STORAGE=TEXT";
// if(openCount>=24) {
// System.exit(1);
// }
if(openCount>=42 && callCount>1200 && seed == 437623957) {
System.exit(1);
}
// add = ";LOG=2";
// System.out.println("now open " + openCount);
// add += ";TRACE_LEVEL_FILE=3";
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论