提交 97f0f775 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 0840ef36
......@@ -18,7 +18,16 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Linked tables: compatibility with MS SQL Server has been improved.
<ul><li>The wrong parameters were bound to subqueries with parameters, specially
when using IN(SELECT ...) and IN(...).
</li><li>Unset parameters were not detected when the query was re-compiled.
</li><li>New functions ISO_YEAR, ISO_WEEK, ISO_DAY_OF_WEEK.
Thanks a lot to Robert Rathsack for implementing those!
</li><li>The date functions DAYOFYEAR, DAYOFMONTH, DAYOFWEEK are now called
DAY_OF_YEAR, DAY_OF_MONTH, DAY_OF_WEEK (the old names still work).
</li><li>An out of memory error while deleting or updating many rows could
result in a strange exception.
</li><li>Linked tables: compatibility with MS SQL Server has been improved.
</li><li>Renaming tables that have foreign keys with cascade didn't work correctly.
</li><li>The auto-reconnect feature didn't work when using the auto-server mode. Fixed.
</li><li>Fulltext search: new method FT_DROP_INDEX.
......
......@@ -379,6 +379,8 @@ Of course, patches are always welcome, but are not always applied as is. Patches
</li><li>Use http://recaptcha.net somehow to secure the Google Group.
</li><li>Support DELETE with TOP or LIMIT. See also: http://dev.mysql.com/doc/refman/5.1/de/delete.html
</li><li>Change the default for NULL || 'x' to return NULL
</li><li>ANALYZE: Use a bloom filter for each indexed column to estimate count of distinct values.
</li><li>ANALYZE: For unique indexes that allow null, count the number of null.
</li></ul>
<h2>Not Planned</h2>
......
......@@ -129,7 +129,7 @@
90105=Exception calling user-defined function
90106=Cannot truncate {0}
90107=Cannot drop {0} because {1} depends on it
90108=Out of memory. Size\: {0}
90108=Out of memory.
90109=View {0} is invalid\: {1}
90110={0} out of range
90111=Error accessing linked table with SQL statement {0}, cause\: {1}
......
......@@ -1497,10 +1497,12 @@ public class ErrorCode {
public static final int CANNOT_DROP_2 = 90107;
/**
* The error with code <code>90108</code> is thrown when
* not enough memory was available to read a value from the disk.
* The error with code <code>90108</code> is thrown when not enough heap
* memory was available. A possible solutions is to increase the memory size
* using <code>java -Xmx128m ...</code>. Another solution is to reduce
* the cache size.
*/
public static final int OUT_OF_MEMORY_1 = 90108;
public static final int OUT_OF_MEMORY = 90108;
/**
* The error with code <code>90109</code> is thrown when
......
......@@ -443,12 +443,12 @@ public class SysProperties {
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024);
/**
* System property <code>h2.reserveMemory</code> (default: 131072).<br />
* System property <code>h2.reserveMemory</code> (default: 524288).<br />
* This many bytes in main memory are allocated as a reserve. This reserve
* is freed up when if no memory is available, so that rolling back a large
* transaction is easier.
*/
public static final int RESERVE_MEMORY = getIntSetting("h2.reserveMemory", 128 * 1024);
public static final int RESERVE_MEMORY = getIntSetting("h2.reserveMemory", 512 * 1024);
/**
* System property <code>h2.reuseSpaceAfter</code> (default: 16).<br />
......
......@@ -2088,4 +2088,16 @@ public class Database implements DataHandler {
return databaseShortName + ":" + super.toString();
}
/**
* Immediately close the database.
*/
public void shutdownImmediately() {
setPowerOffCount(1);
try {
checkPowerOff();
} catch (SQLException e) {
// ignore
}
}
}
......@@ -391,9 +391,10 @@ public class Session implements SessionInterface {
ArrayList rows = new ArrayList();
synchronized (database) {
while (undoLog.size() > 0) {
UndoLogRecord entry = undoLog.getAndRemoveLast();
UndoLogRecord entry = undoLog.getLast();
entry.commit();
rows.add(entry.getRow());
undoLog.removeLast(false);
}
for (int i = 0; i < rows.size(); i++) {
Row r = (Row) rows.get(i);
......@@ -440,7 +441,7 @@ public class Session implements SessionInterface {
currentTransactionName = null;
boolean needCommit = false;
if (undoLog.size() > 0) {
rollbackTo(0);
rollbackTo(0, false);
needCommit = true;
}
if (locks.size() > 0 || needCommit) {
......@@ -459,10 +460,11 @@ public class Session implements SessionInterface {
*
* @param index the position to which should be rolled back
*/
public void rollbackTo(int index) throws SQLException {
public void rollbackTo(int index, boolean trimToSize) throws SQLException {
while (undoLog.size() > index) {
UndoLogRecord entry = undoLog.getAndRemoveLast();
UndoLogRecord entry = undoLog.getLast();
entry.undo(this);
undoLog.removeLast(trimToSize);
}
if (savepoints != null) {
String[] names = new String[savepoints.size()];
......@@ -687,7 +689,7 @@ public class Session implements SessionInterface {
throw Message.getSQLException(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
}
int i = id.intValue();
rollbackTo(i);
rollbackTo(i, false);
}
/**
......
......@@ -69,7 +69,7 @@ public class UndoLog {
*
* @return the last record
*/
public UndoLogRecord getAndRemoveLast() throws SQLException {
public UndoLogRecord getLast() throws SQLException {
int i = records.size() - 1;
UndoLogRecord entry = (UndoLogRecord) records.get(i);
if (entry.isStored()) {
......@@ -87,11 +87,23 @@ public class UndoLog {
}
first.seek(file);
}
return entry;
}
/**
* Remove the last record from the list of operations.
*
* @param trimToSize if the undo array should shrink to conserve memory
*/
public void removeLast(boolean trimToSize) {
int i = records.size() - 1;
UndoLogRecord r = (UndoLogRecord) records.remove(i);
if (!r.isStored()) {
memoryUndo--;
}
return entry;
if (trimToSize && i > 1024 && (i & 1023) == 0) {
records.trimToSize();
}
}
/**
......
......@@ -22,10 +22,10 @@ import org.h2.util.Resources;
import org.h2.util.StringUtils;
/**
* Messages used in the database engine.
* Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back.
* If the word 'SQL' appears then the whole SQL statement must be a parameter,
* otherwise this may be added: '; SQL statement: ' + sql
* Messages used in the database engine. Use the PropertiesToUTF8 tool to
* translate properties files to UTF-8 and back. If the word 'SQL' appears then
* the whole SQL statement must be a parameter, otherwise this may be added: ';
* SQL statement: ' + sql
*/
public class Message {
......@@ -39,8 +39,8 @@ public class Message {
}
String language = Locale.getDefault().getLanguage();
if (!"en".equals(language)) {
byte[] translations = Resources.get("/org/h2/res/_messages_"+language+".properties");
// message: translated message + english
byte[] translations = Resources.get("/org/h2/res/_messages_" + language + ".properties");
// message: translated message + english
// (otherwise certain applications don't work)
if (translations != null) {
Properties p = new Properties();
......@@ -61,14 +61,14 @@ public class Message {
TraceSystem.traceThrowable(e);
}
}
private Message() {
// utility class
}
/**
* Gets the SQL exception object for a specific error code.
*
*
* @param errorCode the error code
* @param p1 the first parameter of the message
* @return the SQLException object
......@@ -80,7 +80,7 @@ public class Message {
private static String translate(String key, String[] param) {
String message = MESSAGES.getProperty(key);
if (message == null) {
message = "(Message " +key+ " not found)";
message = "(Message " + key + " not found)";
}
if (param != null) {
Object[] o = param;
......@@ -91,7 +91,7 @@ public class Message {
/**
* Gets the SQL exception object for a specific error code.
*
*
* @param errorCode the error code
* @param params the list of parameters of the message
* @param cause the cause of the exception
......@@ -105,7 +105,7 @@ public class Message {
/**
* Gets the SQL exception object for a specific error code.
*
*
* @param errorCode the error code
* @param params the list of parameters of the message
* @return the SQLException object
......@@ -116,7 +116,7 @@ public class Message {
/**
* Constructs a syntax error SQL exception.
*
*
* @param sql the SQL statement
* @param index the position of the error in the SQL statement
* @return the SQLException object
......@@ -128,7 +128,7 @@ public class Message {
/**
* Constructs a syntax error SQL exception.
*
*
* @param sql the SQL statement
* @param index the position of the error in the SQL statement
* @param expected the expected keyword at the given position
......@@ -136,12 +136,12 @@ public class Message {
*/
public static SQLException getSyntaxError(String sql, int index, String expected) {
sql = StringUtils.addAsterisk(sql, index);
return getSQLException(ErrorCode.SYNTAX_ERROR_2, new String[]{sql, expected});
return getSQLException(ErrorCode.SYNTAX_ERROR_2, new String[] { sql, expected });
}
/**
* Gets the SQL exception object for a specific error code.
*
*
* @param errorCode the error code
* @return the SQLException object
*/
......@@ -166,7 +166,7 @@ public class Message {
* @return the SQLException object
*/
public static JdbcSQLException getInvalidValueException(String value, String param) {
return getSQLException(ErrorCode.INVALID_VALUE_2, new String[]{value, param});
return getSQLException(ErrorCode.INVALID_VALUE_2, new String[] { value, param });
}
/**
......@@ -180,7 +180,7 @@ public class Message {
TraceSystem.traceThrowable(e);
return e;
}
/**
* Gets an internal error.
*
......@@ -190,9 +190,9 @@ public class Message {
*/
public static Error getInternalError(String s, Exception e) {
Error e2 = new Error(s);
//## Java 1.4 begin ##
// ## Java 1.4 begin ##
e2.initCause(e);
//## Java 1.4 end ##
// ## Java 1.4 end ##
TraceSystem.traceThrowable(e2);
return e2;
}
......@@ -212,9 +212,7 @@ public class Message {
}
return j;
}
return new JdbcSQLException(e.getMessage(), sql,
e.getSQLState(),
e.getErrorCode(), e, null);
return new JdbcSQLException(e.getMessage(), sql, e.getSQLState(), e.getErrorCode(), e, null);
}
/**
......@@ -244,6 +242,8 @@ public class Message {
}
if (e instanceof SQLException) {
return (SQLException) e;
} else if (e instanceof OutOfMemoryError) {
return getSQLException(ErrorCode.OUT_OF_MEMORY, null, e);
} else if (e instanceof InvocationTargetException) {
InvocationTargetException te = (InvocationTargetException) e;
Throwable t = te.getTargetException();
......@@ -254,7 +254,7 @@ public class Message {
} else if (e instanceof IOException) {
return getSQLException(ErrorCode.IO_EXCEPTION_1, new String[] { e.toString() }, e);
}
return getSQLException(ErrorCode.GENERAL_ERROR_1, new String[]{e.toString()}, e);
return getSQLException(ErrorCode.GENERAL_ERROR_1, new String[] { e.toString() }, e);
}
/**
......@@ -266,9 +266,9 @@ public class Message {
*/
public static SQLException convertIOException(IOException e, String message) {
if (message == null) {
return getSQLException(ErrorCode.IO_EXCEPTION_1, new String[]{e.toString()}, e);
return getSQLException(ErrorCode.IO_EXCEPTION_1, new String[] { e.toString() }, e);
}
return getSQLException(ErrorCode.IO_EXCEPTION_2, new String[]{e.toString(), message}, e);
return getSQLException(ErrorCode.IO_EXCEPTION_2, new String[] { e.toString(), message }, e);
}
/**
......@@ -304,9 +304,9 @@ public class Message {
}
}
IOException io = new IOException(e.toString());
//## Java 1.4 begin ##
// ## Java 1.4 begin ##
io.initCause(e);
//## Java 1.4 end ##
// ## Java 1.4 end ##
return io;
}
......
......@@ -129,7 +129,7 @@
90105=Fehler beim Aufruf eine benutzerdefinierten Funktion
90106=Kann {0} nicht zur\u00FCcksetzen per TRUNCATE
90107=Kann {0} nicht l\u00F6schen weil {1} davon abh\u00E4ngt
90108=Nicht genug Hauptspeicher. Anzahl Bytes\: {0}
90108=Nicht genug Hauptspeicher.
90109=View {0} ist ung\u00FCltig\: {1}
90110={0} ausserhalb des Bereichts
90111=Fehler beim Zugriff auf eine verkn\u00FCpfte Tabelle mit SQL Befehl {0}, Grund\: {1}
......
......@@ -129,7 +129,7 @@
90105=Exception calling user-defined function
90106=Cannot truncate {0}
90107=Cannot drop {0} because {1} depends on it
90108=Out of memory. Size\: {0}
90108=Out of memory.
90109=View {0} is invalid\: {1}
90110={0} out of range
90111=Error accessing linked table with SQL statement {0}, cause\: {1}
......
......@@ -129,7 +129,7 @@
90105=\u30E6\u30FC\u30B6\u5B9A\u7FA9\u95A2\u6570\u3092\u5B9F\u884C\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F
90106={0} \u3092\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093
90107={1} \u304C\u4F9D\u5B58\u3057\u3066\u3044\u308B\u305F\u3081\u3001{0} \u3092\u30C9\u30ED\u30C3\u30D7\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093
90108=\u30E1\u30E2\u30EA\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059\u3002\u30B5\u30A4\u30BA\: {0}
90108=#\u30E1\u30E2\u30EA\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059\u3002\u30B5\u30A4\u30BA\
90109=\u30D3\u30E5\u30FC {0} \u304C\u7121\u52B9\u3067\u3059\: {1}
90110={0} \u306F\u7BC4\u56F2\u5916\u3067\u3059
90111=SQL\u30B9\u30C6\u30FC\u30C8\u30E1\u30F3\u30C8 {0} \u306B\u3088\u308B\u7D50\u5408\u30C6\u30FC\u30D6\u30EB\u30A2\u30AF\u30BB\u30B9\u30A8\u30E9\u30FC
......
......@@ -129,7 +129,7 @@
90105=Wyjatek wywoluje funkcje uzytkownika
90106=Nie mozna obciac {0}
90107=Nie mozna skasowac {0} poniewaz zalezy od {1}
90108=\#Out of memory. Size\: {0}
90108=\#Out of memory.
90109=Widok {0} jest nieprawidlowy
90110={0} poza zakresem
90111=\#Error accessing linked table with SQL statement {0}, cause\: {1}
......
......@@ -129,7 +129,7 @@
90105=Exce\u00E7\u00E3o na chamada da fun\u00E7\u00E3o definida pelo usu\u00E1rio
90106=N\u00E3o pode fazer o truncate {0}
90107=N\u00E3o pode apagar {0} por que depende de {1}
90108=\#Out of memory. Size\: {0}
90108=\#Out of memory.
90109=Vista {0} \u00E9 inv\u00E1lida\: {1}
90110={0} out of range
90111=Erro ao acessar a tabela lincada com a instru\u00E7\u00E3o SQL {0}, causa\: {1}
......
......@@ -2493,6 +2493,7 @@ The value is encoded as XML text.
","
CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'))
"
"Functions (String)","XMLNODE","
XMLNODE(elementString [, attributesString [, contentString]]): string
","
......@@ -2500,6 +2501,7 @@ Create an XML node element.
","
CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'), 'H2')
"
"Functions (String)","XMLCOMMENT","
XMLCOMMENT(commentString): string
","
......@@ -2507,6 +2509,7 @@ Creates an XML comment. Two dashes (--) are converted to - -.
","
CALL XMLCOMMENT('Test')
"
"Functions (String)","XMLCDATA","
XMLCDATA(valueString): string
","
......@@ -2514,6 +2517,7 @@ Creates an XML CDATA element. If the value contains ']]>', an XML text element i
","
CALL XMLCDATA('data')
"
"Functions (String)","XMLSTARTDOC","
XMLSTARTDOC(): string
","
......@@ -2521,6 +2525,7 @@ The string '<?xml version=""1.0""?>' is returned.
","
CALL XMLSTARTDOC()
"
"Functions (String)","XMLTEXT","
XMLTEXT(valueString): string
","
......@@ -2528,6 +2533,7 @@ Creates an XML text element.
","
CALL XMLTEXT('test')
"
"Functions (Time and Date)","CURRENT_DATE","
{CURRENT_DATE[()] | CURDATE() | SYSDATE | TODAY}: date
","
......@@ -2535,6 +2541,7 @@ Returns the current date.
","
CURRENT_DATE()
"
"Functions (Time and Date)","CURRENT_TIME","
{CURRENT_TIME[()] | CURTIME()}: time
","
......@@ -2542,6 +2549,7 @@ Returns the current time.
","
CURRENT_TIME()
"
"Functions (Time and Date)","CURRENT_TIMESTAMP","
{CURRENT_TIMESTAMP[([int])] | NOW([int])}: timestamp
","
......@@ -2550,24 +2558,25 @@ The precision parameter for nanoseconds precision is optional.
","
CURRENT_TIMESTAMP()
"
"Functions (Time and Date)","DATEADD","
DATEADD(unitString, addInt, timestamp): timestamp
","
Adds units to a timestamp. The string indicates the unit. Use negative values to subtract units.
The following units are supported:
YY, YEAR, MM, MONTH, DD, DAY, HH, HOUR, MI, MINUTE, SS, SECOND, MS, MILLISECOND.
The same units as in the EXTRACT function are supported.
","
DATEADD('MONTH', 1, DATE '2001-01-31')
"
"Functions (Time and Date)","DATEDIFF","
DATEDIFF(unitString, aTimestamp, bTimestamp): long
","
Returns the difference between two timestamps. The string indicates the unit.
The following units are supported:
YY, YEAR, MM, MONTH, DD, DAY, HH, HOUR, MI, MINUTE, SS, SECOND, MS, MILLISECOND.
The same units as in the EXTRACT function are supported.
","
DATEDIFF('YEAR', T1.CREATED, T2.CREATED)
"
"Functions (Time and Date)","DAYNAME","
DAYNAME(date): string
","
......@@ -2575,37 +2584,42 @@ Returns the name of the day (in English).
","
DAYNAME(CREATED)
"
"Functions (Time and Date)","DAYOFMONTH","
DAYOFMONTH(date): int
"Functions (Time and Date)","DAY_OF_MONTH","
DAY_OF_MONTH(date): int
","
Returns the day of the month (1-31).
","
DAYOFMONTH(CREATED)
DAY_OF_MONTH(CREATED)
"
"Functions (Time and Date)","DAYOFWEEK","
DAYOFWEEK(date): int
"Functions (Time and Date)","DAY_OF_WEEK","
DAY_OF_WEEK(date): int
","
Returns the day of the week (1 means Sunday).
","
DAYOFWEEK(CREATED)
DAY_OF_WEEK(CREATED)
"
"Functions (Time and Date)","DAYOFYEAR","
DAYOFYEAR(date): int
"Functions (Time and Date)","DAY_OF_YEAR","
DAY_OF_YEAR(date): int
","
Returns the day of the year (1-366).
","
DAYOFYEAR(CREATED)
DAY_OF_YEAR(CREATED)
"
"Functions (Time and Date)","EXTRACT","
EXTRACT(
{YY | YEAR | MM | MONTH | DD | DAY | HH | HOUR |
MI | MINUTE | SS | SECOND | MS | MILLISECOND}
{YEAR | YY | MONTH | MM | DAY | DD | DAY_OF_YEAR | DOY |
HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS}
FROM timestamp): int
","
Returns a specific value from a timestamps.
","
EXTRACT(SECOND FROM CURRENT_TIMESTAMP)
"
"Functions (Time and Date)","FORMATDATETIME","
FORMATDATETIME(timestamp, formatString [, localeString [, timeZoneString]]): string
","
......@@ -2615,6 +2629,7 @@ For details of the format, see java.text.SimpleDateFormat.
","
CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT')
"
"Functions (Time and Date)","HOUR","
HOUR(timestamp): int
","
......@@ -2629,6 +2644,7 @@ Returns the minute (0-59) from a timestamp.
","
MINUTE(CREATED)
"
"Functions (Time and Date)","MONTH","
MONTH(timestamp): int
","
......@@ -2636,6 +2652,7 @@ Returns the month (1-12) from a timestamp.
","
MONTH(CREATED)
"
"Functions (Time and Date)","MONTHNAME","
MONTHNAME(date): string
","
......@@ -2643,6 +2660,7 @@ Returns the name of the month (in English).
","
MONTHNAME(CREATED)
"
"Functions (Time and Date)","PARSEDATETIME","
PARSEDATETIME(string, formatString [, localeString [, timeZoneString]]): string
","
......@@ -2652,6 +2670,7 @@ For details of the format, see java.text.SimpleDateFormat.
","
CALL PARSEDATETIME('Sat, 3 Feb 2001 03:05:06 GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT')
"
"Functions (Time and Date)","QUARTER","
QUARTER(timestamp): int
","
......@@ -2659,6 +2678,7 @@ Returns the quarter (1-4) from a timestamp.
","
QUARTER(CREATED)
"
"Functions (Time and Date)","SECOND","
SECOND(timestamp): int
","
......@@ -2666,6 +2686,7 @@ Returns the second (0-59) from a timestamp.
","
SECOND(CREATED)
"
"Functions (Time and Date)","WEEK","
WEEK(timestamp): int
","
......@@ -2674,6 +2695,7 @@ This method uses the current system locale.
","
WEEK(CREATED)
"
"Functions (Time and Date)","YEAR","
YEAR(timestamp): int
","
......
......@@ -153,8 +153,10 @@ public class BitField {
* @param len the number of bits to enable or disable
*/
public void setRange(int start, int len, boolean value) {
for (int end = start + len; start < end; start++) {
set(start, value);
// go backwards so that OutOfMemory happens
// before some bytes are modified
for (int i = start + len - 1; i >= start; i--) {
set(i, value);
}
}
......
......@@ -130,10 +130,19 @@ public class ObjectArray {
private void ensureCapacity(int i) {
while (i >= data.length) {
Object[] d = new Object[Math.max(CAPACITY_INIT, data.length * 2)];
System.arraycopy(data, 0, d, 0, data.length);
System.arraycopy(data, 0, d, 0, size);
data = d;
}
}
/**
* Shrink the array to the required size.
*/
public void trimToSize() {
Object[] d = new Object[size];
System.arraycopy(data, 0, d, 0, size);
data = d;
}
/**
* Insert an element at the given position. The element at this position and
......
......@@ -102,6 +102,7 @@ import org.h2.test.unit.TestCache;
import org.h2.test.unit.TestCompress;
import org.h2.test.unit.TestDataPage;
import org.h2.test.unit.TestDate;
import org.h2.test.unit.TestDateIso8601;
import org.h2.test.unit.TestExit;
import org.h2.test.unit.TestFile;
import org.h2.test.unit.TestFileLock;
......@@ -277,14 +278,22 @@ java org.h2.test.TestAll timer
System.setProperty("h2.check2", "true");
/*
java -Xmx3m
create table test(name varchar);
set max_log_size 1024;
@LOOP 20000 insert into test values(space(10000));
delete from test;
SELECT * FROM TEST where name like 'a';
test with 1.0
document shared connections for linked tables
document osgi
document url parameter auto_server
document url parameter auto_reconnect
document url parameter open_new
document shared connections for linked tables
document osgi
merge join test case
......@@ -584,6 +593,7 @@ http://www.w3schools.com/sql/
new TestCompress().runTest(this);
new TestDataPage().runTest(this);
new TestDate().runTest(this);
new TestDateIso8601().runTest(this);
new TestExit().runTest(this);
new TestFile().runTest(this);
new TestFileLock().runTest(this);
......
......@@ -37,6 +37,7 @@ public class TestOptimizations extends TestBase {
}
public void test() throws Exception {
testInSelectJoin();
testMinMaxNullOptimization();
if (config.networked) {
return;
......@@ -53,6 +54,40 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(true);
testMinMaxCountOptimization(false);
}
private void testInSelectJoin() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
stat.execute("create table test(a int, b int, c int, d int) " +
"as select 1, 1, 1, 1 from dual;");
ResultSet rs;
PreparedStatement prep;
prep = conn.prepareStatement("SELECT 2 FROM TEST A "
+ "INNER JOIN (SELECT DISTINCT B.C AS X FROM TEST B "
+ "WHERE B.D = ?2) V ON 1=1 WHERE (A = ?1) AND (B = V.X)");
prep.setInt(1, 1);
prep.setInt(2, 1);
rs = prep.executeQuery();
assertTrue(rs.next());
assertFalse(rs.next());
boolean old = SysProperties.optimizeInJoin;
SysProperties.optimizeInJoin = true;
prep = conn.prepareStatement(
"select 2 from test a where a=? and b in(" +
"select b.c from test b where b.d=?)");
prep.setInt(1, 1);
prep.setInt(2, 1);
rs = prep.executeQuery();
assertTrue(rs.next());
assertFalse(rs.next());
conn.close();
SysProperties.optimizeInJoin = old;
}
private void testOptimizeInJoinSelect() throws SQLException {
boolean old = SysProperties.optimizeInJoin;
......
......@@ -23,6 +23,15 @@ import org.h2.test.TestBase;
public class TestOutOfMemory extends TestBase {
private LinkedList list = new LinkedList();
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String[] a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws SQLException {
if (config.memory || config.mvcc) {
......@@ -42,7 +51,7 @@ public class TestOutOfMemory extends TestBase {
prep.execute();
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.GENERAL_ERROR_1, e.getErrorCode());
assertEquals(ErrorCode.OUT_OF_MEMORY, e.getErrorCode());
}
list = null;
ResultSet rs = stat.executeQuery("select count(*) from stuff");
......
......@@ -531,7 +531,7 @@ public class TestPreparedStatement extends TestBase {
stat.execute("CREATE TABLE TEST(ID INT)");
stat.execute("INSERT INTO TEST VALUES(1),(2),(3)");
PreparedStatement prep = conn.prepareStatement("select x.id, ? from "
+ "(select * from test where id in(?, ?)) x " + "where x.id*2 <> ?");
+ "(select * from test where id in(?, ?)) x where x.id*2 <> ?");
assertEquals(prep.getParameterMetaData().getParameterCount(), 4);
prep.setInt(1, 0);
prep.setInt(2, 1);
......
......@@ -84,7 +84,7 @@ public class TestFuzzOptimizations extends TestBase {
p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]);
p.execute();
}
int len = getSize(1000, 10000);
int len = getSize(1000, 3000);
for (int i = 0; i < len / 10; i++) {
db.execute("CREATE TABLE TEST_INDEXED AS SELECT * FROM TEST");
int jLen = 1 + random.nextInt(2);
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select iso_week('2006-12-31') w, iso_year('2007-12-31') y, iso_day_of_week('2007-12-31') w;
> W Y W
> -- ---- -
> 52 2008 1
> rows: 1
create schema a;
> ok
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select iso_week('2006-12-31') w, iso_year('2007-12-31') y, iso_day_of_week('2007-12-31') w;
> W Y W
> -- ---- -
> 52 2008 1
> rows: 1
create schema a;
> ok
......
......@@ -55,12 +55,12 @@ I am sorry to say that, but it looks like a corruption problem. I am very intere
or two phase commit, linked tables, cache settings)?
- Is the application multi-threaded?
- On what operating system, file system, and virtual machine (java -version)?
- How big is the database?
- How big is the database (file sizes)?
- Is the database usually closed normally, or is process terminated forcefully
or the computer switched off?
- Is it possible to reproduce this problem using a fresh database
(sometimes, or always)?
- Are there any other exceptions (maybe in the .trace.db file)?
Could you send them to me please?
Could you send them please?
- Do you still have any .trace.db files, and if yes could you send them?
- Could you send me the .data.db file where this exception occurs?
- Could you send the .data.db file where this exception occurs?
/*
* Copyright 2004-2008 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: Robert Rathsack (firstName dot lastName at gmx dot de)
*/
package org.h2.test.unit;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.h2.test.TestBase;
import org.h2.util.DateTimeIso8601Utils;
/**
* Test cases for DateTimeIso8601Utils.
*/
public class TestDateIso8601 extends TestBase {
private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String[] a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
testIsoDayOfWeek();
testIsoWeekJanuary1thMonday();
testIsoWeekJanuary1thTuesday();
testIsoWeekJanuary1thWednesday();
testIsoWeekJanuary1thThursday();
testIsoWeekJanuary1thFriday();
testIsoWeekJanuary1thSaturday();
testIsoWeekJanuary1thSunday();
testIsoYearJanuary1thMonday();
testIsoYearJanuary1thTuesday();
testIsoYearJanuary1thWednesday();
testIsoYearJanuary1thThursday();
testIsoYearJanuary1thFriday();
testIsoYearJanuary1thSaturday();
testIsoYearJanuary1thSunday();
}
private Date parse(String s) throws ParseException {
return dateFormatter.parse(s);
}
private static int getIsoDayOfWeek(Date date) {
return DateTimeIso8601Utils.getIsoDayOfWeek(date);
}
/**
* Test if day of week is returned as Monday = 1 to Sunday = 7.
*/
private void testIsoDayOfWeek() throws Exception {
assertEquals(1, getIsoDayOfWeek(parse("2008-09-29")));
assertEquals(2, getIsoDayOfWeek(parse("2008-09-30")));
assertEquals(3, getIsoDayOfWeek(parse("2008-10-01")));
assertEquals(4, getIsoDayOfWeek(parse("2008-10-02")));
assertEquals(5, getIsoDayOfWeek(parse("2008-10-03")));
assertEquals(6, getIsoDayOfWeek(parse("2008-10-04")));
assertEquals(7, getIsoDayOfWeek(parse("2008-10-05")));
}
private static int getIsoWeek(Date date) {
Timestamp ts = new Timestamp(date.getTime());
return DateTimeIso8601Utils.getIsoWeek(ts);
}
/**
* January 1st is a Monday therefore the week belongs to the next year.
*/
private void testIsoWeekJanuary1thMonday() throws Exception {
assertEquals(52, getIsoWeek(parse("2006-12-31")));
assertEquals(1, getIsoWeek(parse("2007-01-01")));
assertEquals(1, getIsoWeek(parse("2007-01-07")));
assertEquals(2, getIsoWeek(parse("2007-01-08")));
}
/**
* January 1st is a Tuesday therefore the week belongs to the next year.
*/
private void testIsoWeekJanuary1thTuesday() throws Exception {
assertEquals(52, getIsoWeek(parse("2007-12-30")));
assertEquals(1, getIsoWeek(parse("2007-12-31")));
assertEquals(1, getIsoWeek(parse("2008-01-01")));
assertEquals(1, getIsoWeek(parse("2008-01-06")));
assertEquals(2, getIsoWeek(parse("2008-01-07")));
}
/**
* January1th is a Wednesday therefore the week belongs to the next year.
*/
private void testIsoWeekJanuary1thWednesday() throws Exception {
assertEquals(52, getIsoWeek(parse("2002-12-28")));
assertEquals(52, getIsoWeek(parse("2002-12-29")));
assertEquals(1, getIsoWeek(parse("2002-12-30")));
assertEquals(1, getIsoWeek(parse("2002-12-31")));
assertEquals(1, getIsoWeek(parse("2003-01-01")));
assertEquals(1, getIsoWeek(parse("2003-01-05")));
assertEquals(2, getIsoWeek(parse("2003-01-06")));
}
/**
* January 1st is a Thursday therefore the week belongs to the next year.
*/
private void testIsoWeekJanuary1thThursday() throws Exception {
assertEquals(52, getIsoWeek(parse("2008-12-28")));
assertEquals(1, getIsoWeek(parse("2008-12-29")));
assertEquals(1, getIsoWeek(parse("2008-12-30")));
assertEquals(1, getIsoWeek(parse("2008-12-31")));
assertEquals(1, getIsoWeek(parse("2009-01-01")));
assertEquals(1, getIsoWeek(parse("2009-01-04")));
assertEquals(2, getIsoWeek(parse("2009-01-09")));
}
/**
* January 1st is a Friday therefore the week belongs to the previous year.
*/
private void testIsoWeekJanuary1thFriday() throws Exception {
assertEquals(53, getIsoWeek(parse("2009-12-31")));
assertEquals(53, getIsoWeek(parse("2010-01-01")));
assertEquals(53, getIsoWeek(parse("2010-01-03")));
assertEquals(1, getIsoWeek(parse("2010-01-04")));
}
/**
* January 1st is a Saturday therefore the week belongs to the previous
* year.
*/
private void testIsoWeekJanuary1thSaturday() throws Exception {
assertEquals(52, getIsoWeek(parse("2010-12-31")));
assertEquals(52, getIsoWeek(parse("2011-01-01")));
assertEquals(52, getIsoWeek(parse("2011-01-02")));
assertEquals(1, getIsoWeek(parse("2011-01-03")));
}
/**
* January 1st is a Sunday therefore the week belongs to the previous year.
*/
private void testIsoWeekJanuary1thSunday() throws Exception {
assertEquals(52, getIsoWeek(parse("2011-12-31")));
assertEquals(52, getIsoWeek(parse("2012-01-01")));
assertEquals(1, getIsoWeek(parse("2012-01-02")));
assertEquals(1, getIsoWeek(parse("2012-01-08")));
assertEquals(2, getIsoWeek(parse("2012-01-09")));
}
private static int getIsoYear(Date date) {
Timestamp ts = new Timestamp(date.getTime());
return DateTimeIso8601Utils.getIsoYear(ts);
}
/**
* January 1st is a Monday therefore year is equal to isoYear.
*/
private void testIsoYearJanuary1thMonday() throws Exception {
assertEquals(2006, getIsoYear(parse("2006-12-28")));
assertEquals(2006, getIsoYear(parse("2006-12-29")));
assertEquals(2006, getIsoYear(parse("2006-12-30")));
assertEquals(2006, getIsoYear(parse("2006-12-31")));
assertEquals(2007, getIsoYear(parse("2007-01-01")));
assertEquals(2007, getIsoYear(parse("2007-01-02")));
assertEquals(2007, getIsoYear(parse("2007-01-03")));
}
/**
* January 1st is a Tuesday therefore 31th of December belong to the next
* year.
*/
private void testIsoYearJanuary1thTuesday() throws Exception {
assertEquals(2007, getIsoYear(parse("2007-12-28")));
assertEquals(2007, getIsoYear(parse("2007-12-29")));
assertEquals(2007, getIsoYear(parse("2007-12-30")));
assertEquals(2008, getIsoYear(parse("2007-12-31")));
assertEquals(2008, getIsoYear(parse("2008-01-01")));
assertEquals(2008, getIsoYear(parse("2008-01-02")));
assertEquals(2008, getIsoYear(parse("2008-01-03")));
assertEquals(2008, getIsoYear(parse("2008-01-04")));
}
/**
* January 1st is a Wednesday therefore 30th and 31th of December belong to
* the next year.
*/
private void testIsoYearJanuary1thWednesday() throws Exception {
assertEquals(2002, getIsoYear(parse("2002-12-28")));
assertEquals(2002, getIsoYear(parse("2002-12-29")));
assertEquals(2003, getIsoYear(parse("2002-12-30")));
assertEquals(2003, getIsoYear(parse("2002-12-31")));
assertEquals(2003, getIsoYear(parse("2003-01-01")));
assertEquals(2003, getIsoYear(parse("2003-01-02")));
assertEquals(2003, getIsoYear(parse("2003-12-02")));
}
/**
* January 1st is a Thursday therefore 29th - 31th of December belong to the
* next year.
*/
private void testIsoYearJanuary1thThursday() throws Exception {
assertEquals(2008, getIsoYear(parse("2008-12-28")));
assertEquals(2009, getIsoYear(parse("2008-12-29")));
assertEquals(2009, getIsoYear(parse("2008-12-30")));
assertEquals(2009, getIsoYear(parse("2008-12-31")));
assertEquals(2009, getIsoYear(parse("2009-01-01")));
assertEquals(2009, getIsoYear(parse("2009-01-02")));
assertEquals(2009, getIsoYear(parse("2009-01-03")));
assertEquals(2009, getIsoYear(parse("2009-01-04")));
}
/**
* January 1st is a Friday therefore 1st - 3rd of January belong to the
* previous year.
*/
private void testIsoYearJanuary1thFriday() throws Exception {
assertEquals(2009, getIsoYear(parse("2009-12-28")));
assertEquals(2009, getIsoYear(parse("2009-12-29")));
assertEquals(2009, getIsoYear(parse("2009-12-30")));
assertEquals(2009, getIsoYear(parse("2009-12-31")));
assertEquals(2009, getIsoYear(parse("2010-01-01")));
assertEquals(2009, getIsoYear(parse("2010-01-02")));
assertEquals(2009, getIsoYear(parse("2010-01-03")));
assertEquals(2010, getIsoYear(parse("2010-01-04")));
}
/**
* January 1st is a Saturday therefore 1st and 2nd of January belong to the
* previous year.
*/
private void testIsoYearJanuary1thSaturday() throws Exception {
assertEquals(2010, getIsoYear(parse("2010-12-28")));
assertEquals(2010, getIsoYear(parse("2010-12-29")));
assertEquals(2010, getIsoYear(parse("2010-12-30")));
assertEquals(2010, getIsoYear(parse("2010-12-31")));
assertEquals(2010, getIsoYear(parse("2011-01-01")));
assertEquals(2010, getIsoYear(parse("2011-01-02")));
assertEquals(2011, getIsoYear(parse("2011-01-03")));
assertEquals(2011, getIsoYear(parse("2011-01-04")));
}
/**
* January 1st is a Sunday therefore this day belong to the previous year.
*/
private void testIsoYearJanuary1thSunday() throws Exception {
assertEquals(2011, getIsoYear(parse("2011-12-28")));
assertEquals(2011, getIsoYear(parse("2011-12-29")));
assertEquals(2011, getIsoYear(parse("2011-12-30")));
assertEquals(2011, getIsoYear(parse("2011-12-31")));
assertEquals(2011, getIsoYear(parse("2012-01-01")));
assertEquals(2012, getIsoYear(parse("2012-01-02")));
assertEquals(2012, getIsoYear(parse("2012-01-03")));
assertEquals(2012, getIsoYear(parse("2012-01-04")));
}
}
package org.h2.dev.util;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
/**
* Filter full thread dumps from a log file.
*/
public class ThreadDumpFilter {
/**
* Usage: java ThreadDumpFilter <log.txt >threadDump.txt
* @param a ignored
*/
public static void main(String[] a) throws Exception {
LineNumberReader in = new LineNumberReader(new InputStreamReader(System.in));
for (String s; (s = in.readLine()) != null;) {
if (s.startsWith("Full thread")) {
do {
System.out.println(s);
s = in.readLine();
} while(s != null && (s.length() == 0 || "\t\"".indexOf(s.charAt(0)) >= 0));
}
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论