提交 66f3f69d authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 1806fdea
...@@ -16,9 +16,12 @@ Change Log ...@@ -16,9 +16,12 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul></li>Referential constraint checking improvement: now the constraint is only checked <ul><li>When using order by in a query that uses the same table multiple times, the order could
be incorrect. Fixed.
</li><li>Referential constraint checking improvement: now the constraint is only checked
if the key column values change. if the key column values change.
<li>The Lucene fulltext index was empty when opening a database with fulltext </li><li>Some database metadata calls returned the wrong data type for DATA_TYPE columns.
</li><li>The Lucene fulltext index was empty when opening a database with fulltext
index enabled, and re-indexing it didn't work. Fixed. index enabled, and re-indexing it didn't work. Fixed.
</li><li>The character '$' could not be used in identifier names (table name, </li><li>The character '$' could not be used in identifier names (table name,
column names and so on). Fixed. column names and so on). Fixed.
......
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.
...@@ -216,15 +216,16 @@ public class LogFile { ...@@ -216,15 +216,16 @@ public class LogFile {
file.readFully(buff, 0, BLOCK_SIZE); file.readFully(buff, 0, BLOCK_SIZE);
DataPage s = DataPage.create(database, buff); DataPage s = DataPage.create(database, buff);
int blocks = Math.abs(s.readInt()); int blocks = Math.abs(s.readInt());
if (blocks > 1) { if (blocks <= 0) {
// Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
s.reset();
} else {
byte[] b2 = ByteUtils.newBytes(blocks * BLOCK_SIZE); byte[] b2 = ByteUtils.newBytes(blocks * BLOCK_SIZE);
System.arraycopy(buff, 0, b2, 0, BLOCK_SIZE); System.arraycopy(buff, 0, b2, 0, BLOCK_SIZE);
buff = b2; buff = b2;
file.readFully(buff, BLOCK_SIZE, blocks * BLOCK_SIZE - BLOCK_SIZE); file.readFully(buff, BLOCK_SIZE, blocks * BLOCK_SIZE - BLOCK_SIZE);
s = DataPage.create(database, buff); s = DataPage.create(database, buff);
s.check(blocks * BLOCK_SIZE); s.check(blocks * BLOCK_SIZE);
} else {
s.reset();
} }
return s; return s;
} }
......
...@@ -1889,6 +1889,8 @@ VAR_SAMP(X) ...@@ -1889,6 +1889,8 @@ VAR_SAMP(X)
ABS({int | long | decimal | double}): value ABS({int | long | decimal | double}): value
"," ","
See also Java Math.abs. See also Java Math.abs.
Please note that Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE and
Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE.
"," ","
ABS(ID) ABS(ID)
" "
...@@ -2128,7 +2130,7 @@ SIGN(VALUE) ...@@ -2128,7 +2130,7 @@ SIGN(VALUE)
ENCRYPT(algorithmString, keyBytes, dataBytes): bytes ENCRYPT(algorithmString, keyBytes, dataBytes): bytes
"," ","
Encrypts data using a key. Supported algorithms are XTEA and AES. Encrypts data using a key. Supported algorithms are XTEA and AES.
The block size is 16 bytes The block size is 16 bytes.
"," ","
CALL ENCRYPT('AES', '00', STRINGTOUTF8('Test')) CALL ENCRYPT('AES', '00', STRINGTOUTF8('Test'))
" "
...@@ -2137,9 +2139,9 @@ CALL ENCRYPT('AES', '00', STRINGTOUTF8('Test')) ...@@ -2137,9 +2139,9 @@ CALL ENCRYPT('AES', '00', STRINGTOUTF8('Test'))
DECRYPT(algorithmString, keyBytes, dataBytes): bytes DECRYPT(algorithmString, keyBytes, dataBytes): bytes
"," ","
Decrypts data using a key. Supported algorithms are XTEA and AES. Decrypts data using a key. Supported algorithms are XTEA and AES.
The block size is 16 bytes The block size is 16 bytes.
"," ","
CALL UTF8TOSTRING(DECRYPT('AES', '00', '3fabb4de8f1ee2e97d7793bab2db1116')) CALL TRIM(CHAR(0) FROM UTF8TOSTRING(DECRYPT('AES', '00', '3fabb4de8f1ee2e97d7793bab2db1116')))
" "
"Functions (Numeric)","HASH"," "Functions (Numeric)","HASH","
......
...@@ -82,7 +82,7 @@ public class FileSystemMemory extends FileSystem { ...@@ -82,7 +82,7 @@ public class FileSystemMemory extends FileSystem {
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) { public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) {
name += "."; name += ".";
for (int i = 0;; i++) { for (int i = 0;; i++) {
String n = name + Math.abs(RandomUtils.getSecureLong()) + suffix; String n = name + (RandomUtils.getSecureLong() >>> 1) + suffix;
if (!exists(n)) { if (!exists(n)) {
// creates the file (not thread safe) // creates the file (not thread safe)
getMemoryFile(n); getMemoryFile(n);
......
...@@ -43,6 +43,7 @@ import org.h2.store.FileStoreInputStream; ...@@ -43,6 +43,7 @@ import org.h2.store.FileStoreInputStream;
import org.h2.util.ByteUtils; import org.h2.util.ByteUtils;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils; import org.h2.util.ObjectUtils;
import org.h2.util.RandomUtils; import org.h2.util.RandomUtils;
...@@ -488,7 +489,8 @@ public class Recover extends Tool implements DataHandler { ...@@ -488,7 +489,8 @@ public class Recover extends Tool implements DataHandler {
buff = new byte[blockSize]; buff = new byte[blockSize];
store.readFully(buff, 0, blockSize); store.readFully(buff, 0, blockSize);
s = DataPage.create(this, buff); s = DataPage.create(this, buff);
blocks = Math.abs(s.readInt()); // Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
blocks = MathUtils.convertLongToInt(Math.abs(s.readInt()));
if (blocks > 1) { if (blocks > 1) {
byte[] b2 = ByteUtils.newBytes(blocks * blockSize); byte[] b2 = ByteUtils.newBytes(blocks * blockSize);
System.arraycopy(buff, 0, b2, 0, blockSize); System.arraycopy(buff, 0, b2, 0, blockSize);
...@@ -502,7 +504,8 @@ public class Recover extends Tool implements DataHandler { ...@@ -502,7 +504,8 @@ public class Recover extends Tool implements DataHandler {
s.check(blocks * blockSize); s.check(blocks * blockSize);
} }
s.reset(); s.reset();
blocks = Math.abs(s.readInt()); // Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
blocks = MathUtils.convertLongToInt(Math.abs(s.readInt()));
if (blocks == 0) { if (blocks == 0) {
writer.println("// [" + pos + "] blocks: " + blocks + " (end)"); writer.println("// [" + pos + "] blocks: " + blocks + " (end)");
break; break;
......
...@@ -54,13 +54,14 @@ SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3; ...@@ -54,13 +54,14 @@ SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3;
--> 2 --> 2
; ;
-- Display the query plan - 'IDX_TEST_TYPE' means the index is used -- Display the query plan - 'index sorted' means the index is used to order
EXPLAIN SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3; EXPLAIN SELECT DISTINCT TYPE FROM TEST ORDER BY TYPE LIMIT 3;
--> SELECT DISTINCT TYPE --> SELECT DISTINCT TYPE
--> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_TYPE */ --> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_TYPE */
--> ORDER BY 1 --> ORDER BY 1
--> LIMIT 3 --> LIMIT 3
--> /* distinct */ --> /* distinct */
--> /* index sorted */
; ;
DROP TABLE TEST; DROP TABLE TEST;
...@@ -164,12 +165,13 @@ SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 3; ...@@ -164,12 +165,13 @@ SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 3;
--> 0.16 --> 0.16
; ;
-- Display the query plan - 'IDX_TEST_VALUE' means the index is used -- Display the query plan - 'index sorted' means the index is used
EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 10; EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE LIMIT 10;
--> SELECT VALUE --> SELECT VALUE
--> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE */ --> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE */
--> ORDER BY 1 --> ORDER BY 1
--> LIMIT 10 --> LIMIT 10
--> /* index sorted */
; ;
-- To optimize getting the largest values, a new descending index is required -- To optimize getting the largest values, a new descending index is required
...@@ -182,12 +184,13 @@ SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 3; ...@@ -182,12 +184,13 @@ SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 3;
--> 99.68 --> 99.68
; ;
-- Display the query plan - 'IDX_TEST_VALUE_D' means the index is used -- Display the query plan - 'index sorted' means the index is used
EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 10; EXPLAIN SELECT VALUE FROM TEST ORDER BY VALUE DESC LIMIT 10;
--> SELECT VALUE --> SELECT VALUE
--> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE_D */ --> FROM PUBLIC.TEST /* PUBLIC.IDX_TEST_VALUE_D */
--> ORDER BY 1 DESC --> ORDER BY 1 DESC
--> LIMIT 10 --> LIMIT 10
--> /* index sorted */
; ;
DROP TABLE TEST; DROP TABLE TEST;
...@@ -269,8 +269,30 @@ java org.h2.test.TestAll timer ...@@ -269,8 +269,30 @@ java org.h2.test.TestAll timer
/* /*
automate a test:
drop all objects delete files;
<reconnect>
drop table stuff;
create table stuff (id identity, text varchar(3000),
created timestamp default current_timestamp);
@LOOP 1000000 insert into stuff (text) values
('This is record ' || ? || ' and this is it''s data');
update stuff set text = text || ' updated';
select count(*) from stuff;
-Xmx16m
Support large updates (use the transaction log to undo).
document FTL_SEARCH, FTL_SEARCH_DATA document FTL_SEARCH, FTL_SEARCH_DATA
I will add a feature request to support DECODE,
and another feature request to support a variable
number of parameters for Java functions. I don't want
to use arrays because H2 also supports ARRAY as a base data type.
Varargs as in Java 1.5 would be an option however,
but then you can't support it in Java 1.4.
JaQu JaQu
row level locking row level locking
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- special grammar and test cases ---------------------------------------------------------------------------------------------
create table t (pk int primary key, attr int);
> ok
insert into t values (1, 5), (5, 1);
> update count: 2
select t1.pk from t t1, t t2 where t1.pk = t2.attr order by t1.pk;
> PK
> --
> 1
> 5
> rows (ordered): 2
drop table t;
> ok
CREATE TABLE T(A NULL); CREATE TABLE T(A NULL);
> exception > exception
...@@ -2803,14 +2819,14 @@ insert into test values(1, 'Y'); ...@@ -2803,14 +2819,14 @@ insert into test values(1, 'Y');
> update count: 1 > update count: 1
call select a from test order by id; call select a from test order by id;
> SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY =ID > SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY =ID /* index sorted */
> ----------------------------------------------------------------- > ------------------------------------------------------------------------------------
> TRUE > TRUE
> rows (ordered): 1 > rows (ordered): 1
select select a from test order by id; select select a from test order by id;
> SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY =ID > SELECT A FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY =ID /* index sorted */
> ----------------------------------------------------------------- > ------------------------------------------------------------------------------------
> TRUE > TRUE
> rows (ordered): 1 > rows (ordered): 1
...@@ -4903,8 +4919,8 @@ SELECT LIMIT (1+0) (2+0) NAME, -ID, ID _ID_ FROM TEST ORDER BY _ID_; ...@@ -4903,8 +4919,8 @@ SELECT LIMIT (1+0) (2+0) NAME, -ID, ID _ID_ FROM TEST ORDER BY _ID_;
EXPLAIN SELECT LIMIT (1+0) (2+0) * FROM TEST ORDER BY ID; EXPLAIN SELECT LIMIT (1+0) (2+0) * FROM TEST ORDER BY ID;
> PLAN > PLAN
> ------------------------------------------------------------------------------------------------- > --------------------------------------------------------------------------------------------------------------------
> SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY 1 LIMIT 2 OFFSET 1 > SELECT TEST.ID, TEST.NAME FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_2 */ ORDER BY 1 LIMIT 2 OFFSET 1 /* index sorted */
> rows (ordered): 1 > rows (ordered): 1
SELECT * FROM TEST ORDER BY ID LIMIT 2+0 OFFSET 1+0; SELECT * FROM TEST ORDER BY ID LIMIT 2+0 OFFSET 1+0;
......
...@@ -35,7 +35,7 @@ public class TestFile extends TestBase implements DataHandler { ...@@ -35,7 +35,7 @@ public class TestFile extends TestBase implements DataHandler {
byte[] buffFile = null; byte[] buffFile = null;
String prefix = compress ? "memLZF:" : "memFS:"; String prefix = compress ? "memLZF:" : "memFS:";
FileUtils.delete(prefix + "test"); FileUtils.delete(prefix + "test");
FileUtils.delete("~/test"); FileUtils.delete("~/testFile");
// config.traceTest = true; // config.traceTest = true;
...@@ -47,7 +47,7 @@ public class TestFile extends TestBase implements DataHandler { ...@@ -47,7 +47,7 @@ public class TestFile extends TestBase implements DataHandler {
} }
if (file == null) { if (file == null) {
mem = FileStore.open(this, prefix + "test", "rw", magic); mem = FileStore.open(this, prefix + "test", "rw", magic);
file = FileStore.open(this, "~/test", "rw", magic); file = FileStore.open(this, "~/testFile", "rw", magic);
} }
assertEquals(file.getFilePointer(), mem.getFilePointer()); assertEquals(file.getFilePointer(), mem.getFilePointer());
assertEquals(file.length(), mem.length()); assertEquals(file.length(), mem.length());
...@@ -120,7 +120,7 @@ public class TestFile extends TestBase implements DataHandler { ...@@ -120,7 +120,7 @@ public class TestFile extends TestBase implements DataHandler {
file.close(); file.close();
} }
FileUtils.delete("inmemory:test"); FileUtils.delete("inmemory:test");
FileUtils.delete("~/test"); FileUtils.delete("~/testFile");
} }
public int allocateObjectId(boolean needFresh, boolean dataFile) { public int allocateObjectId(boolean needFresh, boolean dataFile) {
......
...@@ -544,4 +544,5 @@ filo gumbo pasties marmalade ale suklaa scottish zaanse hokkien sauce ...@@ -544,4 +544,5 @@ filo gumbo pasties marmalade ale suklaa scottish zaanse hokkien sauce
crab northwoods escargots organic sasquatch bourgogne clam camembert tigers crab northwoods escargots organic sasquatch bourgogne clam camembert tigers
chang lumberjack roed biscuits chang lumberjack roed biscuits
usable weblica jena preserved instrumentation inspect usable weblica jena preserved instrumentation inspect jayaprakash ashwin
\ No newline at end of file varargs automate
\ No newline at end of file
...@@ -23,8 +23,8 @@ import org.h2.util.StringUtils; ...@@ -23,8 +23,8 @@ import org.h2.util.StringUtils;
/** /**
* Generic utility methods. * Generic utility methods.
*/ */
//## Java 1.5 begin ##
public class Utils { public class Utils {
//## Java 1.5 begin ##
private static volatile long counter; private static volatile long counter;
...@@ -154,5 +154,5 @@ public class Utils { ...@@ -154,5 +154,5 @@ public class Utils {
throw new RuntimeException("Can not convert the value " + o + " from " + currentType + " to " + targetType); throw new RuntimeException("Can not convert the value " + o + " from " + currentType + " to " + targetType);
} }
}
//## Java 1.5 end ## //## Java 1.5 end ##
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论