提交 094cba01 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 b9d004da
......@@ -15,10 +15,16 @@ import org.h2.message.Message;
/**
* This is a wrapper class for the Deflater class.
* This algorithm supports the following options:
* <ul>
* <li>l or level: -1 (default), 0 (no compression), 1 (best speed), ..., 9 (best compression)
* </li><li>s or strategy: 0 (default), 1 (filtered), 2 (huffman only)
* </li></ul>
* See also java.util.zip.Deflater for details.
*/
public class CompressDeflate implements Compressor {
private int level = Deflater.BEST_SPEED;
private int level = Deflater.DEFAULT_COMPRESSION;
private int strategy = Deflater.DEFAULT_STRATEGY;
public void setOptions(String options) throws SQLException {
......@@ -34,6 +40,8 @@ public class CompressDeflate implements Compressor {
} else if ("strategy".equals(option) || "s".equals(option)) {
strategy = Integer.parseInt(tokenizer.nextToken());
}
Deflater deflater = new Deflater(level);
deflater.setStrategy(strategy);
}
} catch (Exception e) {
throw Message.getSQLException(ErrorCode.UNSUPPORTED_COMPRESSION_OPTIONS_1, options);
......
......@@ -525,10 +525,9 @@ public class ErrorCode {
* Multiple connections to the same database are supported in the following
* cases:
* <ul>
* <li>In embedded mode (URL of the form jdbc:h2:test) if all connections
* <li>In embedded mode (URL of the form jdbc:h2:~/test) if all connections
* are opened within the same process and class loader.
* </li>
* <li>In server and cluster mode (URL of the form jdbc:h2:tcp://localhost/test)
* </li><li>In server and cluster mode (URL of the form jdbc:h2:tcp://localhost/test)
* using remote connections.
* </li></ul>
* The mixed mode is also supported.
......@@ -890,7 +889,7 @@ public class ErrorCode {
* Supported are AES and XTEA.
* Example:
* <pre>
* jdbc:h2:test;CIPHER=DES
* jdbc:h2:~/test;CIPHER=DES
* </pre>
*/
public static final int UNSUPPORTED_CIPHER = 90055;
......@@ -939,7 +938,7 @@ public class ErrorCode {
* Currently only FILE (the default) and SOCKET are supported
* Example:
* <pre>
* jdbc:h2:test;FILE_LOCK=LDAP
* jdbc:h2:~/test;FILE_LOCK=LDAP
* </pre>
*/
public static final int UNSUPPORTED_LOCK_METHOD_1 = 90060;
......@@ -998,7 +997,7 @@ public class ErrorCode {
* the connection properties.
* Example:
* <pre>
* jdbc:h2:test;LOG=0;LOG=1
* jdbc:h2:~/test;LOG=0;LOG=1
* </pre>
*/
public static final int DUPLICATE_PROPERTY_1 = 90066;
......@@ -1376,11 +1375,49 @@ public class ErrorCode {
*/
public static final int WRONG_XID_FORMAT_1 = 90101;
private int todo25;
/**
* The error with code <code>90102</code> is thrown when
* trying to use unsupported options for the given compression algorithm.
* Example:
* <pre>
* CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 10');
* </pre>
* Correct:
* <pre>
* CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'DEFLATE l 9');
* </pre>
*/
public static final int UNSUPPORTED_COMPRESSION_OPTIONS_1 = 90102;
/**
* The error with code <code>90103</code> is thrown when
* trying to use an unsupported compression algorithm.
* Example:
* <pre>
* CALL COMPRESS(STRINGTOUTF8(SPACE(100)), 'BZIP');
* </pre>
*/
public static final int UNSUPPORTED_COMPRESSION_ALGORITHM_1 = 90103;
/**
* The error with code <code>90104</code> is thrown when
* the data can not be de-compressed.
* Example:
* <pre>
* CALL EXPAND(X'00FF');
* </pre>
*/
public static final int COMPRESSION_ERROR = 90104;
/**
* The error with code <code>90105</code> is thrown when
* an exception occured in a user defined method.
* Example:
* <pre>
* CREATE ALIAS SYS_PROP FOR "java.lang.System.getProperty";
* CALL SYS_PROP(NULL);
* </pre>
*/
public static final int EXCEPTION_IN_FUNCTION = 90105;
/**
......@@ -1406,7 +1443,6 @@ public class ErrorCode {
* </pre>
*/
public static final int CANNOT_DROP_2 = 90107;
public static final int STACK_OVERFLOW = 90108;
/**
* The error with code <code>90109</code> is thrown when
......@@ -1414,10 +1450,25 @@ public class ErrorCode {
* Example:
* <pre>
* CREATE FORCE VIEW TEST_VIEW AS SELECT * FROM TEST;
* SELECT * FROM TEST_VIEW; * </pre>
* SELECT * FROM TEST_VIEW;
* </pre>
*/
public static final int VIEW_IS_INVALID_2 = 90109;
/**
* The error with code <code>90110</code> is thrown when
* the result of the calculation does not fit in the given data type.
* Example:
* <pre>
* CALL -CAST(-128 AS TINYINT);
* </pre>
*/
public static final int OVERFLOW_FOR_TYPE_1 = 90110;
/**
* The error with code <code>90111</code> is thrown when
* an exception occured while accessing a linked table.
*/
public static final int ERROR_ACCESSING_LINKED_TABLE_2 = 90111;
/**
......@@ -1430,9 +1481,49 @@ public class ErrorCode {
* </pre>
*/
public static final int ROW_NOT_FOUND_WHEN_DELETING_1 = 90112;
/**
* The error with code <code>90113</code> is thrown when
* the database URL contains unsupported settings.
* Example:
* <pre>
* jdbc:h2:~/test;UNKNOWN=TRUE
* </pre>
*/
public static final int UNSUPPORTED_SETTING_1 = 90113;
/**
* The error with code <code>90114</code> is thrown when
* trying to create a constant if a constant with this name already exists.
* Example:
* <pre>
* CREATE CONSTANT TEST VALUE 1;
* CREATE CONSTANT TEST VALUE 1;
* </pre>
*/
public static final int CONSTANT_ALREADY_EXISTS_1 = 90114;
/**
* The error with code <code>90115</code> is thrown when
* trying to drop a constant that does not exists.
* Example:
* <pre>
* DROP CONSTANT UNKNOWN;
* </pre>
*/
public static final int CONSTANT_NOT_FOUND_1 = 90115;
/**
* The error with code <code>90116</code> is thrown when
* trying use a literal in a SQL statement if literals are disabled.
* If literals are disabled, use PreparedStatement and parameters instead
* of literals in the SQL statement.
* Example:
* <pre>
* SET ALLOW_LITERALS NONE;
* CALL 1+1;
* </pre>
*/
public static final int LITERALS_ARE_NOT_ALLOWED = 90116;
/**
......@@ -1460,6 +1551,9 @@ public class ErrorCode {
* </pre>
*/
public static final int CANNOT_DROP_TABLE_1 = 90118;
private int todo14;
public static final int USER_DATA_TYPE_ALREADY_EXISTS_1 = 90119;
public static final int USER_DATA_TYPE_NOT_FOUND_1 = 90120;
public static final int DATABASE_CALLED_AT_SHUTDOWN = 90121;
......@@ -1540,7 +1634,7 @@ public class ErrorCode {
*/
public static final int CAN_ONLY_ASSIGN_TO_VARIABLE_1 = 90137;
// next is 90058
// next is 90058, 90108
/**
* INTERNAL
......
......@@ -82,6 +82,7 @@ public class Session implements SessionInterface {
private HashMap variables;
private HashSet temporaryResults;
private int queryTimeout = SysProperties.getMaxQueryTimeout();
private int lastUncommittedDelete;
public Session() {
}
......@@ -226,11 +227,20 @@ public class Session implements SessionInterface {
database.setPowerOffCount(count);
}
public int getLastUncommittedDelete() {
return lastUncommittedDelete;
}
public void setLastUncommittedDelete(int deleteId) {
lastUncommittedDelete = deleteId;
}
public void commit(boolean ddl) throws SQLException {
lastUncommittedDelete = 0;
currentTransactionName = null;
if (containsUncommitted()) {
// need to commit even if rollback is not possible (create/drop
// table and so on)
// need to commit even if rollback is not possible
// (create/drop table and so on)
logSystem.commit(this);
}
if (undoLog.size() > 0) {
......
......@@ -2076,10 +2076,10 @@ COMPRESS(dataBytes [, algorithmString]): bytes
","
Compresses the data using the specified compression algorithm.
Supported algorithms are:
LZF (fast but lower compression),
DEFLATE (higher compression; default).
Compression only makes reduces the size if the
original data contains redundancy and is at least about 30 bytes long.
LZF (fast but lower compression; default),
DEFLATE (higher compression).
Compression does not always reduce size.
Very small objects and objects with little redundancy may get larger.
","
COMPRESS(STRINGTOUTF8('Test'))
"
......
......@@ -12,6 +12,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import org.h2.api.DatabaseEventListener;
import org.h2.constant.ErrorCode;
......@@ -33,6 +35,7 @@ import org.h2.util.FileUtils;
import org.h2.util.IntArray;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
/**
* This class represents a file that is usually written to disk.
......@@ -73,8 +76,10 @@ public class DiskFile implements CacheWriter {
private FileStore file;
private BitField used;
private BitField deleted;
private HashSet potentiallyFreePages;
private int fileBlockCount;
private IntArray pageOwners;
private IntArray pageDelete;
private Cache cache;
private LogSystem log;
private DataPage rowBuff;
......@@ -88,6 +93,8 @@ public class DiskFile implements CacheWriter {
private int readCount, writeCount;
private String mode;
private int nextDeleteId;
public DiskFile(Database database, String fileName, String mode, boolean dataFile, boolean logChanges, int cacheSize) throws SQLException {
reset();
this.database = database;
......@@ -129,9 +136,11 @@ public class DiskFile implements CacheWriter {
used = new BitField();
deleted = new BitField();
pageOwners = new IntArray();
pageDelete = new IntArray();
// init pageOwners
setBlockCount(fileBlockCount);
redoBuffer = new ObjectArray();
potentiallyFreePages = new HashSet();
}
private void setBlockCount(int count) {
......@@ -139,6 +148,7 @@ public class DiskFile implements CacheWriter {
int pages = getPage(count);
while (pages >= pageOwners.size()) {
pageOwners.add(FREE_PAGE);
pageDelete.add(0);
}
}
......@@ -588,18 +598,59 @@ public class DiskFile implements CacheWriter {
if (pos + blockCount > fileBlockCount) {
setBlockCount(pos + blockCount);
}
int deleteId = 0;
if (session != null) {
deleteId = nextDeleteId++;
setUncommittedDelete(session, getPage(pos), deleteId);
}
for (int i = pos; i < pos + blockCount; i++) {
used.clear(i);
if ((i % BLOCKS_PER_PAGE == 0) && (pos + blockCount >= i + BLOCKS_PER_PAGE)) {
// if this is the first page of a block and if the whole page is free
int disabledCurrently;
if (!logChanges) {
if (session != null && logChanges) {
setUncommittedDelete(session, getPage(i), deleteId);
} else {
setPageOwner(getPage(i), FREE_PAGE);
}
}
}
}
void freePage(int page) throws SQLException {
if (!logChanges) {
setPageOwner(page, FREE_PAGE);
} else {
int todoTestThis;
synchronized (potentiallyFreePages) {
potentiallyFreePages.add(ObjectUtils.getInteger(page));
if (potentiallyFreePages.size() > 20) {
Session[] sessions = database.getSessions();
int oldest = 0;
for (int i = 0; i < sessions.length; i++) {
int deleteId = sessions[i].getLastUncommittedDelete();
if (oldest == 0 || deleteId < oldest) {
oldest = deleteId;
}
}
for (Iterator it = potentiallyFreePages.iterator(); it.hasNext();) {
int p = ((Integer) it.next()).intValue();
if (oldest == 0 || oldest > pageDelete.get(p)) {
setPageOwner(p, FREE_PAGE);
//int testing;
//System.out.println("free page " + p);
it.remove();
}
}
}
}
}
}
private void setUncommittedDelete(Session session, int page, int deleteId) {
session.setLastUncommittedDelete(deleteId);
pageDelete.set(page, deleteId);
}
int getPage(int pos) {
return pos >>> BLOCK_PAGE_PAGE_SHIFT;
}
......
......@@ -201,9 +201,6 @@ public class Storage {
public void delete(Session session) throws SQLException {
truncate(session);
int disabledCurrently;
// database.removeStorage(id, file);
}
// private int allocateBest(int start, int blocks) {
......@@ -269,8 +266,7 @@ public class Storage {
pageCheckIndex = (pageCheckIndex + 1) % pages.size();
int page = pages.get(pageCheckIndex);
if (file.isPageFree(page) && file.getPageOwner(page) == id) {
int disabledCurrently;
// file.setPageOwner(page, DiskFile.FREE_PAGE);
file.freePage(page);
}
}
......
......@@ -4,13 +4,9 @@
*/
package org.h2.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.h2.Driver;
import org.h2.constant.SysProperties;
import org.h2.server.TcpServer;
import org.h2.store.fs.FileSystemDisk;
import org.h2.test.db.TestAutoRecompile;
......@@ -29,6 +25,7 @@ import org.h2.test.db.TestIndex;
import org.h2.test.db.TestLinkedTable;
import org.h2.test.db.TestListener;
import org.h2.test.db.TestLob;
import org.h2.test.db.TestLogFile;
import org.h2.test.db.TestMemoryUsage;
import org.h2.test.db.TestMultiConn;
import org.h2.test.db.TestMultiDimension;
......@@ -44,6 +41,7 @@ import org.h2.test.db.TestScript;
import org.h2.test.db.TestScriptSimple;
import org.h2.test.db.TestSequence;
import org.h2.test.db.TestSessionsLocks;
import org.h2.test.db.TestSpaceReuse;
import org.h2.test.db.TestSpeed;
import org.h2.test.db.TestTempTables;
import org.h2.test.db.TestTransaction;
......@@ -68,7 +66,6 @@ import org.h2.test.jdbcx.TestXA;
import org.h2.test.jdbcx.TestXASimple;
import org.h2.test.mvcc.TestMvcc1;
import org.h2.test.mvcc.TestMvcc2;
import org.h2.test.poweroff.TestRecover;
import org.h2.test.server.TestNestedLoop;
import org.h2.test.server.TestPgServer;
import org.h2.test.server.TestWeb;
......@@ -110,8 +107,6 @@ import org.h2.test.unit.TestValue;
import org.h2.test.unit.TestValueHashMap;
import org.h2.test.unit.TestValueMemory;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Recover;
import org.h2.tools.Restore;
import org.h2.tools.Server;
import org.h2.util.StringUtils;
......@@ -157,13 +152,7 @@ java org.h2.test.TestAll timer
/*
the user should be allowed to do everything with his own temp tables (and views).
CREATE USER IF NOT EXISTS READER PASSWORD 'READER';
<login as READER>
CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS MY_TEST(ID INT);
INSERT INTO MY_TEST VALUES(1);
SELECT * FROM MY_TEST;
DROP TABLE MY_TEST;
Test space re-use
Automate real power off tests
Extend tests that simulate power off
......@@ -182,21 +171,20 @@ Adjust cache memory usage
Test Recovery with MAX_LOG_FILE_SIZE=1; test with various log file sizes
History:
Databases can now be opened even if trigger classes are not in the classpath.
The exception is thrown when trying to fire the trigger.
Opening databases with ACCESS_MODE_DATA=r is now supported.
In this case the database is read-only, but the files don't not need
to be read-only.
Security: The database now waits 200 ms before throwing an exception if
the user name or password don't match, to slow down dictionary attacks.
The value cache is now a soft reference cache. This should help save memory.
Large result sets are now a bit faster.
ALTER TABLE ALTER COLUMN RESTART and ALTER SEQUENCE now support an expressions.
When setting the base directory on the command line, the user directory prefix ('~') was ignored.
Roadmap:
BIT VARYING (PostgreSQL)
Bitwise AND operator (1 & 3) (PostgreSQL, MySQL)
The user should be allowed to do everything with his own temp tables (and views).
CREATE USER IF NOT EXISTS READER PASSWORD 'READER';
<login as READER>
CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS MY_TEST(ID INT);
INSERT INTO MY_TEST VALUES(1);
SELECT * FROM MY_TEST;
DROP TABLE MY_TEST;
*/
if (args.length > 0) {
......@@ -420,10 +408,10 @@ Bitwise AND operator (1 & 3) (PostgreSQL, MySQL)
new TestListener().runTest(this);
new TestLob().runTest(this);
// // size problem!
int todo;
// new TestLogFile().runTest(this);
new TestMemoryUsage().runTest(this);
new TestMultiConn().runTest(this);
new TestMultiDimension().runTest(this);
new TestMultiThread().runTest(this);
......@@ -436,10 +424,7 @@ Bitwise AND operator (1 & 3) (PostgreSQL, MySQL)
new TestSQLInjection().runTest(this);
new TestSessionsLocks().runTest(this);
new TestSequence().runTest(this);
// // should fail
// new TestSpaceReuse().runTest(this);
new TestSpaceReuse().runTest(this);
new TestSpeed().runTest(this);
new TestTempTables().runTest(this);
new TestTransaction().runTest(this);
......
......@@ -514,7 +514,7 @@ opensource atlassian hhh establish pawel nice italiano ucchino paolo italian pie
uklinux credential crypt kerberos redferni routine reopen tmp configured replicating wraps jre
webtest einstellung redirects endless ran gives replication lxabcdef asf packages replayed jspa
russian backward alexahin vlad ffffffffffff bfff ffffffff webapp undeploy initializer brasil uncached slowing translating uploaded
llc computing oliver road inaccessible android velasques duplicates eduardo chunk brazilian near langpair xrmd xmkd
llc computing oliver road inaccessible android velasques duplicates eduardo chunk brazilian near langpair xrmd xmkd
encapsulates negating igor midnight fulfill prefixes communicates nesting convenience negated resides optimizing principal applets dobrovolskyi
involves ukrainian chile machines restricting summer aliased backus naur multiples avl operates grow normalized rijndael
countdown paused javac analyzing accesses solving forcefully urgent originally defect coordinates
......@@ -527,4 +527,4 @@ violate verysmallint eremainder iee cgi adjust estimation consumption occupy ikv
upgrading consecutive acting
simulates dispatcher servlets chf destruction separating consulting reached
unreferenced longest enum jira jackcess track unreleased processors nearest fits shadow
cmu cosh tanh sinh contrib
\ No newline at end of file
cmu cosh tanh sinh contrib bzip contiguous huffman bitwise des
\ No newline at end of file
......@@ -14,28 +14,17 @@ import org.hibernate.util.ReflectHelper;
/**
* A dialect compatible with the H2 database.
*
*
* @author Thomas Mueller
*
*/
public class H2Dialect extends Dialect {
private String querySequenceString;
public H2Dialect() {
super();
querySequenceString = "select sequence_name from information_schema.sequences";
try {
Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" );
Integer build = (Integer)constants.getDeclaredField("BUILD_ID" ).get(null);
int buildId = build.intValue();
if(buildId < 32) {
querySequenceString = "select name from information_schema.sequences";
}
} catch(Throwable e) {
// ignore (probably H2 not in the classpath)
}
registerColumnType(Types.BOOLEAN, "boolean");
registerColumnType(Types.BIGINT, "bigint");
registerColumnType(Types.BINARY, "binary");
......@@ -48,7 +37,7 @@ public class H2Dialect extends Dialect {
registerColumnType(Types.INTEGER, "integer");
registerColumnType(Types.LONGVARBINARY, "longvarbinary");
registerColumnType(Types.LONGVARCHAR, "longvarchar");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.TIME, "time");
......@@ -58,7 +47,7 @@ public class H2Dialect extends Dialect {
registerColumnType(Types.NUMERIC, "numeric");
registerColumnType(Types.BLOB, "blob");
registerColumnType(Types.CLOB, "clob");
// select topic, syntax from information_schema.help
// where section like 'Function%' order by section, topic
......@@ -196,10 +185,10 @@ public class H2Dialect extends Dialect {
append(hasOffset ? " limit ? offset ?" : " limit ?").
toString();
}
public boolean bindLimitParametersInReverseOrder() {
return true;
}
}
public boolean bindLimitParametersFirst() {
return false;
......@@ -268,7 +257,7 @@ public class H2Dialect extends Dialect {
public boolean supportsTemporaryTables() {
return true;
}
public String getCreateTemporaryTableString() {
return "create temporary table if not exists";
}
......@@ -276,15 +265,15 @@ public class H2Dialect extends Dialect {
public boolean supportsCurrentTimestampSelection() {
return true;
}
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
public String getCurrentTimestampSelectString() {
return "call current_timestamp()";
}
}
public boolean supportsUnionAll() {
return true;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论