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

--no commit message

--no commit message
上级 0840ef36
...@@ -18,7 +18,16 @@ Change Log ...@@ -18,7 +18,16 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <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>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>The auto-reconnect feature didn't work when using the auto-server mode. Fixed.
</li><li>Fulltext search: new method FT_DROP_INDEX. </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 ...@@ -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>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>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>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> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
90105=Exception calling user-defined function 90105=Exception calling user-defined function
90106=Cannot truncate {0} 90106=Cannot truncate {0}
90107=Cannot drop {0} because {1} depends on it 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} 90109=View {0} is invalid\: {1}
90110={0} out of range 90110={0} out of range
90111=Error accessing linked table with SQL statement {0}, cause\: {1} 90111=Error accessing linked table with SQL statement {0}, cause\: {1}
......
...@@ -1497,10 +1497,12 @@ public class ErrorCode { ...@@ -1497,10 +1497,12 @@ public class ErrorCode {
public static final int CANNOT_DROP_2 = 90107; public static final int CANNOT_DROP_2 = 90107;
/** /**
* The error with code <code>90108</code> is thrown when * The error with code <code>90108</code> is thrown when not enough heap
* not enough memory was available to read a value from the disk. * 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 * The error with code <code>90109</code> is thrown when
......
...@@ -443,12 +443,12 @@ public class SysProperties { ...@@ -443,12 +443,12 @@ public class SysProperties {
public static final int REDO_BUFFER_SIZE = getIntSetting("h2.redoBufferSize", 256 * 1024); 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 * 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 * is freed up when if no memory is available, so that rolling back a large
* transaction is easier. * 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 /> * System property <code>h2.reuseSpaceAfter</code> (default: 16).<br />
......
...@@ -2088,4 +2088,16 @@ public class Database implements DataHandler { ...@@ -2088,4 +2088,16 @@ public class Database implements DataHandler {
return databaseShortName + ":" + super.toString(); 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 { ...@@ -391,9 +391,10 @@ public class Session implements SessionInterface {
ArrayList rows = new ArrayList(); ArrayList rows = new ArrayList();
synchronized (database) { synchronized (database) {
while (undoLog.size() > 0) { while (undoLog.size() > 0) {
UndoLogRecord entry = undoLog.getAndRemoveLast(); UndoLogRecord entry = undoLog.getLast();
entry.commit(); entry.commit();
rows.add(entry.getRow()); rows.add(entry.getRow());
undoLog.removeLast(false);
} }
for (int i = 0; i < rows.size(); i++) { for (int i = 0; i < rows.size(); i++) {
Row r = (Row) rows.get(i); Row r = (Row) rows.get(i);
...@@ -440,7 +441,7 @@ public class Session implements SessionInterface { ...@@ -440,7 +441,7 @@ public class Session implements SessionInterface {
currentTransactionName = null; currentTransactionName = null;
boolean needCommit = false; boolean needCommit = false;
if (undoLog.size() > 0) { if (undoLog.size() > 0) {
rollbackTo(0); rollbackTo(0, false);
needCommit = true; needCommit = true;
} }
if (locks.size() > 0 || needCommit) { if (locks.size() > 0 || needCommit) {
...@@ -459,10 +460,11 @@ public class Session implements SessionInterface { ...@@ -459,10 +460,11 @@ public class Session implements SessionInterface {
* *
* @param index the position to which should be rolled back * @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) { while (undoLog.size() > index) {
UndoLogRecord entry = undoLog.getAndRemoveLast(); UndoLogRecord entry = undoLog.getLast();
entry.undo(this); entry.undo(this);
undoLog.removeLast(trimToSize);
} }
if (savepoints != null) { if (savepoints != null) {
String[] names = new String[savepoints.size()]; String[] names = new String[savepoints.size()];
...@@ -687,7 +689,7 @@ public class Session implements SessionInterface { ...@@ -687,7 +689,7 @@ public class Session implements SessionInterface {
throw Message.getSQLException(ErrorCode.SAVEPOINT_IS_INVALID_1, name); throw Message.getSQLException(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
} }
int i = id.intValue(); int i = id.intValue();
rollbackTo(i); rollbackTo(i, false);
} }
/** /**
......
...@@ -69,7 +69,7 @@ public class UndoLog { ...@@ -69,7 +69,7 @@ public class UndoLog {
* *
* @return the last record * @return the last record
*/ */
public UndoLogRecord getAndRemoveLast() throws SQLException { public UndoLogRecord getLast() throws SQLException {
int i = records.size() - 1; int i = records.size() - 1;
UndoLogRecord entry = (UndoLogRecord) records.get(i); UndoLogRecord entry = (UndoLogRecord) records.get(i);
if (entry.isStored()) { if (entry.isStored()) {
...@@ -87,11 +87,23 @@ public class UndoLog { ...@@ -87,11 +87,23 @@ public class UndoLog {
} }
first.seek(file); 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); UndoLogRecord r = (UndoLogRecord) records.remove(i);
if (!r.isStored()) { if (!r.isStored()) {
memoryUndo--; memoryUndo--;
} }
return entry; if (trimToSize && i > 1024 && (i & 1023) == 0) {
records.trimToSize();
}
} }
/** /**
......
...@@ -22,10 +22,10 @@ import org.h2.util.Resources; ...@@ -22,10 +22,10 @@ import org.h2.util.Resources;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
/** /**
* Messages used in the database engine. * Messages used in the database engine. Use the PropertiesToUTF8 tool to
* Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back. * translate properties files to UTF-8 and back. If the word 'SQL' appears then
* If the word 'SQL' appears then the whole SQL statement must be a parameter, * the whole SQL statement must be a parameter, otherwise this may be added: ';
* otherwise this may be added: '; SQL statement: ' + sql * SQL statement: ' + sql
*/ */
public class Message { public class Message {
...@@ -39,7 +39,7 @@ public class Message { ...@@ -39,7 +39,7 @@ public class Message {
} }
String language = Locale.getDefault().getLanguage(); String language = Locale.getDefault().getLanguage();
if (!"en".equals(language)) { if (!"en".equals(language)) {
byte[] translations = Resources.get("/org/h2/res/_messages_"+language+".properties"); byte[] translations = Resources.get("/org/h2/res/_messages_" + language + ".properties");
// message: translated message + english // message: translated message + english
// (otherwise certain applications don't work) // (otherwise certain applications don't work)
if (translations != null) { if (translations != null) {
...@@ -80,7 +80,7 @@ public class Message { ...@@ -80,7 +80,7 @@ public class Message {
private static String translate(String key, String[] param) { private static String translate(String key, String[] param) {
String message = MESSAGES.getProperty(key); String message = MESSAGES.getProperty(key);
if (message == null) { if (message == null) {
message = "(Message " +key+ " not found)"; message = "(Message " + key + " not found)";
} }
if (param != null) { if (param != null) {
Object[] o = param; Object[] o = param;
...@@ -136,7 +136,7 @@ public class Message { ...@@ -136,7 +136,7 @@ public class Message {
*/ */
public static SQLException getSyntaxError(String sql, int index, String expected) { public static SQLException getSyntaxError(String sql, int index, String expected) {
sql = StringUtils.addAsterisk(sql, index); 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 });
} }
/** /**
...@@ -166,7 +166,7 @@ public class Message { ...@@ -166,7 +166,7 @@ public class Message {
* @return the SQLException object * @return the SQLException object
*/ */
public static JdbcSQLException getInvalidValueException(String value, String param) { 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 });
} }
/** /**
...@@ -190,9 +190,9 @@ public class Message { ...@@ -190,9 +190,9 @@ public class Message {
*/ */
public static Error getInternalError(String s, Exception e) { public static Error getInternalError(String s, Exception e) {
Error e2 = new Error(s); Error e2 = new Error(s);
//## Java 1.4 begin ## // ## Java 1.4 begin ##
e2.initCause(e); e2.initCause(e);
//## Java 1.4 end ## // ## Java 1.4 end ##
TraceSystem.traceThrowable(e2); TraceSystem.traceThrowable(e2);
return e2; return e2;
} }
...@@ -212,9 +212,7 @@ public class Message { ...@@ -212,9 +212,7 @@ public class Message {
} }
return j; return j;
} }
return new JdbcSQLException(e.getMessage(), sql, return new JdbcSQLException(e.getMessage(), sql, e.getSQLState(), e.getErrorCode(), e, null);
e.getSQLState(),
e.getErrorCode(), e, null);
} }
/** /**
...@@ -244,6 +242,8 @@ public class Message { ...@@ -244,6 +242,8 @@ public class Message {
} }
if (e instanceof SQLException) { if (e instanceof SQLException) {
return (SQLException) e; return (SQLException) e;
} else if (e instanceof OutOfMemoryError) {
return getSQLException(ErrorCode.OUT_OF_MEMORY, null, e);
} else if (e instanceof InvocationTargetException) { } else if (e instanceof InvocationTargetException) {
InvocationTargetException te = (InvocationTargetException) e; InvocationTargetException te = (InvocationTargetException) e;
Throwable t = te.getTargetException(); Throwable t = te.getTargetException();
...@@ -254,7 +254,7 @@ public class Message { ...@@ -254,7 +254,7 @@ public class Message {
} else if (e instanceof IOException) { } else if (e instanceof IOException) {
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.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 { ...@@ -266,9 +266,9 @@ public class Message {
*/ */
public static SQLException convertIOException(IOException e, String message) { public static SQLException convertIOException(IOException e, String message) {
if (message == null) { 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 { ...@@ -304,9 +304,9 @@ public class Message {
} }
} }
IOException io = new IOException(e.toString()); IOException io = new IOException(e.toString());
//## Java 1.4 begin ## // ## Java 1.4 begin ##
io.initCause(e); io.initCause(e);
//## Java 1.4 end ## // ## Java 1.4 end ##
return io; return io;
} }
......
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
90105=Fehler beim Aufruf eine benutzerdefinierten Funktion 90105=Fehler beim Aufruf eine benutzerdefinierten Funktion
90106=Kann {0} nicht zur\u00FCcksetzen per TRUNCATE 90106=Kann {0} nicht zur\u00FCcksetzen per TRUNCATE
90107=Kann {0} nicht l\u00F6schen weil {1} davon abh\u00E4ngt 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} 90109=View {0} ist ung\u00FCltig\: {1}
90110={0} ausserhalb des Bereichts 90110={0} ausserhalb des Bereichts
90111=Fehler beim Zugriff auf eine verkn\u00FCpfte Tabelle mit SQL Befehl {0}, Grund\: {1} 90111=Fehler beim Zugriff auf eine verkn\u00FCpfte Tabelle mit SQL Befehl {0}, Grund\: {1}
......
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
90105=Exception calling user-defined function 90105=Exception calling user-defined function
90106=Cannot truncate {0} 90106=Cannot truncate {0}
90107=Cannot drop {0} because {1} depends on it 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} 90109=View {0} is invalid\: {1}
90110={0} out of range 90110={0} out of range
90111=Error accessing linked table with SQL statement {0}, cause\: {1} 90111=Error accessing linked table with SQL statement {0}, cause\: {1}
......
...@@ -129,7 +129,7 @@ ...@@ -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 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 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 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} 90109=\u30D3\u30E5\u30FC {0} \u304C\u7121\u52B9\u3067\u3059\: {1}
90110={0} \u306F\u7BC4\u56F2\u5916\u3067\u3059 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 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 @@ ...@@ -129,7 +129,7 @@
90105=Wyjatek wywoluje funkcje uzytkownika 90105=Wyjatek wywoluje funkcje uzytkownika
90106=Nie mozna obciac {0} 90106=Nie mozna obciac {0}
90107=Nie mozna skasowac {0} poniewaz zalezy od {1} 90107=Nie mozna skasowac {0} poniewaz zalezy od {1}
90108=\#Out of memory. Size\: {0} 90108=\#Out of memory.
90109=Widok {0} jest nieprawidlowy 90109=Widok {0} jest nieprawidlowy
90110={0} poza zakresem 90110={0} poza zakresem
90111=\#Error accessing linked table with SQL statement {0}, cause\: {1} 90111=\#Error accessing linked table with SQL statement {0}, cause\: {1}
......
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
90105=Exce\u00E7\u00E3o na chamada da fun\u00E7\u00E3o definida pelo usu\u00E1rio 90105=Exce\u00E7\u00E3o na chamada da fun\u00E7\u00E3o definida pelo usu\u00E1rio
90106=N\u00E3o pode fazer o truncate {0} 90106=N\u00E3o pode fazer o truncate {0}
90107=N\u00E3o pode apagar {0} por que depende de {1} 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} 90109=Vista {0} \u00E9 inv\u00E1lida\: {1}
90110={0} out of range 90110={0} out of range
90111=Erro ao acessar a tabela lincada com a instru\u00E7\u00E3o SQL {0}, causa\: {1} 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. ...@@ -2493,6 +2493,7 @@ The value is encoded as XML text.
"," ","
CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com')) CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'))
" "
"Functions (String)","XMLNODE"," "Functions (String)","XMLNODE","
XMLNODE(elementString [, attributesString [, contentString]]): string XMLNODE(elementString [, attributesString [, contentString]]): string
"," ","
...@@ -2500,6 +2501,7 @@ Create an XML node element. ...@@ -2500,6 +2501,7 @@ Create an XML node element.
"," ","
CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'), 'H2') CALL XMLNODE('a', XMLATTR('href', 'http://h2database.com'), 'H2')
" "
"Functions (String)","XMLCOMMENT"," "Functions (String)","XMLCOMMENT","
XMLCOMMENT(commentString): string XMLCOMMENT(commentString): string
"," ","
...@@ -2507,6 +2509,7 @@ Creates an XML comment. Two dashes (--) are converted to - -. ...@@ -2507,6 +2509,7 @@ Creates an XML comment. Two dashes (--) are converted to - -.
"," ","
CALL XMLCOMMENT('Test') CALL XMLCOMMENT('Test')
" "
"Functions (String)","XMLCDATA"," "Functions (String)","XMLCDATA","
XMLCDATA(valueString): string XMLCDATA(valueString): string
"," ","
...@@ -2514,6 +2517,7 @@ Creates an XML CDATA element. If the value contains ']]>', an XML text element i ...@@ -2514,6 +2517,7 @@ Creates an XML CDATA element. If the value contains ']]>', an XML text element i
"," ","
CALL XMLCDATA('data') CALL XMLCDATA('data')
" "
"Functions (String)","XMLSTARTDOC"," "Functions (String)","XMLSTARTDOC","
XMLSTARTDOC(): string XMLSTARTDOC(): string
"," ","
...@@ -2521,6 +2525,7 @@ The string '<?xml version=""1.0""?>' is returned. ...@@ -2521,6 +2525,7 @@ The string '<?xml version=""1.0""?>' is returned.
"," ","
CALL XMLSTARTDOC() CALL XMLSTARTDOC()
" "
"Functions (String)","XMLTEXT"," "Functions (String)","XMLTEXT","
XMLTEXT(valueString): string XMLTEXT(valueString): string
"," ","
...@@ -2528,6 +2533,7 @@ Creates an XML text element. ...@@ -2528,6 +2533,7 @@ Creates an XML text element.
"," ","
CALL XMLTEXT('test') CALL XMLTEXT('test')
" "
"Functions (Time and Date)","CURRENT_DATE"," "Functions (Time and Date)","CURRENT_DATE","
{CURRENT_DATE[()] | CURDATE() | SYSDATE | TODAY}: date {CURRENT_DATE[()] | CURDATE() | SYSDATE | TODAY}: date
"," ","
...@@ -2535,6 +2541,7 @@ Returns the current date. ...@@ -2535,6 +2541,7 @@ Returns the current date.
"," ","
CURRENT_DATE() CURRENT_DATE()
" "
"Functions (Time and Date)","CURRENT_TIME"," "Functions (Time and Date)","CURRENT_TIME","
{CURRENT_TIME[()] | CURTIME()}: time {CURRENT_TIME[()] | CURTIME()}: time
"," ","
...@@ -2542,6 +2549,7 @@ Returns the current time. ...@@ -2542,6 +2549,7 @@ Returns the current time.
"," ","
CURRENT_TIME() CURRENT_TIME()
" "
"Functions (Time and Date)","CURRENT_TIMESTAMP"," "Functions (Time and Date)","CURRENT_TIMESTAMP","
{CURRENT_TIMESTAMP[([int])] | NOW([int])}: timestamp {CURRENT_TIMESTAMP[([int])] | NOW([int])}: timestamp
"," ","
...@@ -2550,24 +2558,25 @@ The precision parameter for nanoseconds precision is optional. ...@@ -2550,24 +2558,25 @@ The precision parameter for nanoseconds precision is optional.
"," ","
CURRENT_TIMESTAMP() CURRENT_TIMESTAMP()
" "
"Functions (Time and Date)","DATEADD"," "Functions (Time and Date)","DATEADD","
DATEADD(unitString, addInt, timestamp): timestamp DATEADD(unitString, addInt, timestamp): timestamp
"," ","
Adds units to a timestamp. The string indicates the unit. Use negative values to subtract units. Adds units to a timestamp. The string indicates the unit. Use negative values to subtract units.
The following units are supported: The same units as in the EXTRACT function are supported.
YY, YEAR, MM, MONTH, DD, DAY, HH, HOUR, MI, MINUTE, SS, SECOND, MS, MILLISECOND.
"," ","
DATEADD('MONTH', 1, DATE '2001-01-31') DATEADD('MONTH', 1, DATE '2001-01-31')
" "
"Functions (Time and Date)","DATEDIFF"," "Functions (Time and Date)","DATEDIFF","
DATEDIFF(unitString, aTimestamp, bTimestamp): long DATEDIFF(unitString, aTimestamp, bTimestamp): long
"," ","
Returns the difference between two timestamps. The string indicates the unit. Returns the difference between two timestamps. The string indicates the unit.
The following units are supported: The same units as in the EXTRACT function are supported.
YY, YEAR, MM, MONTH, DD, DAY, HH, HOUR, MI, MINUTE, SS, SECOND, MS, MILLISECOND.
"," ","
DATEDIFF('YEAR', T1.CREATED, T2.CREATED) DATEDIFF('YEAR', T1.CREATED, T2.CREATED)
" "
"Functions (Time and Date)","DAYNAME"," "Functions (Time and Date)","DAYNAME","
DAYNAME(date): string DAYNAME(date): string
"," ","
...@@ -2575,37 +2584,42 @@ Returns the name of the day (in English). ...@@ -2575,37 +2584,42 @@ Returns the name of the day (in English).
"," ","
DAYNAME(CREATED) 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). 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). 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). Returns the day of the year (1-366).
"," ","
DAYOFYEAR(CREATED) DAY_OF_YEAR(CREATED)
" "
"Functions (Time and Date)","EXTRACT"," "Functions (Time and Date)","EXTRACT","
EXTRACT( EXTRACT(
{YY | YEAR | MM | MONTH | DD | DAY | HH | HOUR | {YEAR | YY | MONTH | MM | DAY | DD | DAY_OF_YEAR | DOY |
MI | MINUTE | SS | SECOND | MS | MILLISECOND} HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS}
FROM timestamp): int FROM timestamp): int
"," ","
Returns a specific value from a timestamps. Returns a specific value from a timestamps.
"," ","
EXTRACT(SECOND FROM CURRENT_TIMESTAMP) EXTRACT(SECOND FROM CURRENT_TIMESTAMP)
" "
"Functions (Time and Date)","FORMATDATETIME"," "Functions (Time and Date)","FORMATDATETIME","
FORMATDATETIME(timestamp, formatString [, localeString [, timeZoneString]]): string FORMATDATETIME(timestamp, formatString [, localeString [, timeZoneString]]): string
"," ","
...@@ -2615,6 +2629,7 @@ For details of the format, see java.text.SimpleDateFormat. ...@@ -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') CALL FORMATDATETIME(TIMESTAMP '2001-02-03 04:05:06', 'EEE, d MMM yyyy HH:mm:ss z', 'en', 'GMT')
" "
"Functions (Time and Date)","HOUR"," "Functions (Time and Date)","HOUR","
HOUR(timestamp): int HOUR(timestamp): int
"," ","
...@@ -2629,6 +2644,7 @@ Returns the minute (0-59) from a timestamp. ...@@ -2629,6 +2644,7 @@ Returns the minute (0-59) from a timestamp.
"," ","
MINUTE(CREATED) MINUTE(CREATED)
" "
"Functions (Time and Date)","MONTH"," "Functions (Time and Date)","MONTH","
MONTH(timestamp): int MONTH(timestamp): int
"," ","
...@@ -2636,6 +2652,7 @@ Returns the month (1-12) from a timestamp. ...@@ -2636,6 +2652,7 @@ Returns the month (1-12) from a timestamp.
"," ","
MONTH(CREATED) MONTH(CREATED)
" "
"Functions (Time and Date)","MONTHNAME"," "Functions (Time and Date)","MONTHNAME","
MONTHNAME(date): string MONTHNAME(date): string
"," ","
...@@ -2643,6 +2660,7 @@ Returns the name of the month (in English). ...@@ -2643,6 +2660,7 @@ Returns the name of the month (in English).
"," ","
MONTHNAME(CREATED) MONTHNAME(CREATED)
" "
"Functions (Time and Date)","PARSEDATETIME"," "Functions (Time and Date)","PARSEDATETIME","
PARSEDATETIME(string, formatString [, localeString [, timeZoneString]]): string PARSEDATETIME(string, formatString [, localeString [, timeZoneString]]): string
"," ","
...@@ -2652,6 +2670,7 @@ For details of the format, see java.text.SimpleDateFormat. ...@@ -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') 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"," "Functions (Time and Date)","QUARTER","
QUARTER(timestamp): int QUARTER(timestamp): int
"," ","
...@@ -2659,6 +2678,7 @@ Returns the quarter (1-4) from a timestamp. ...@@ -2659,6 +2678,7 @@ Returns the quarter (1-4) from a timestamp.
"," ","
QUARTER(CREATED) QUARTER(CREATED)
" "
"Functions (Time and Date)","SECOND"," "Functions (Time and Date)","SECOND","
SECOND(timestamp): int SECOND(timestamp): int
"," ","
...@@ -2666,6 +2686,7 @@ Returns the second (0-59) from a timestamp. ...@@ -2666,6 +2686,7 @@ Returns the second (0-59) from a timestamp.
"," ","
SECOND(CREATED) SECOND(CREATED)
" "
"Functions (Time and Date)","WEEK"," "Functions (Time and Date)","WEEK","
WEEK(timestamp): int WEEK(timestamp): int
"," ","
...@@ -2674,6 +2695,7 @@ This method uses the current system locale. ...@@ -2674,6 +2695,7 @@ This method uses the current system locale.
"," ","
WEEK(CREATED) WEEK(CREATED)
" "
"Functions (Time and Date)","YEAR"," "Functions (Time and Date)","YEAR","
YEAR(timestamp): int YEAR(timestamp): int
"," ","
......
...@@ -153,8 +153,10 @@ public class BitField { ...@@ -153,8 +153,10 @@ public class BitField {
* @param len the number of bits to enable or disable * @param len the number of bits to enable or disable
*/ */
public void setRange(int start, int len, boolean value) { public void setRange(int start, int len, boolean value) {
for (int end = start + len; start < end; start++) { // go backwards so that OutOfMemory happens
set(start, value); // before some bytes are modified
for (int i = start + len - 1; i >= start; i--) {
set(i, value);
} }
} }
......
...@@ -130,11 +130,20 @@ public class ObjectArray { ...@@ -130,11 +130,20 @@ public class ObjectArray {
private void ensureCapacity(int i) { private void ensureCapacity(int i) {
while (i >= data.length) { while (i >= data.length) {
Object[] d = new Object[Math.max(CAPACITY_INIT, data.length * 2)]; 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; 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 * Insert an element at the given position. The element at this position and
* all elements with a higher index move one element. * all elements with a higher index move one element.
......
...@@ -102,6 +102,7 @@ import org.h2.test.unit.TestCache; ...@@ -102,6 +102,7 @@ import org.h2.test.unit.TestCache;
import org.h2.test.unit.TestCompress; import org.h2.test.unit.TestCompress;
import org.h2.test.unit.TestDataPage; import org.h2.test.unit.TestDataPage;
import org.h2.test.unit.TestDate; import org.h2.test.unit.TestDate;
import org.h2.test.unit.TestDateIso8601;
import org.h2.test.unit.TestExit; import org.h2.test.unit.TestExit;
import org.h2.test.unit.TestFile; import org.h2.test.unit.TestFile;
import org.h2.test.unit.TestFileLock; import org.h2.test.unit.TestFileLock;
...@@ -278,13 +279,21 @@ java org.h2.test.TestAll timer ...@@ -278,13 +279,21 @@ java org.h2.test.TestAll timer
/* /*
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 test with 1.0
document shared connections for linked tables
document osgi
document url parameter auto_server document url parameter auto_server
document url parameter auto_reconnect document url parameter auto_reconnect
document url parameter open_new document url parameter open_new
document shared connections for linked tables
document osgi
merge join test case merge join test case
...@@ -584,6 +593,7 @@ http://www.w3schools.com/sql/ ...@@ -584,6 +593,7 @@ http://www.w3schools.com/sql/
new TestCompress().runTest(this); new TestCompress().runTest(this);
new TestDataPage().runTest(this); new TestDataPage().runTest(this);
new TestDate().runTest(this); new TestDate().runTest(this);
new TestDateIso8601().runTest(this);
new TestExit().runTest(this); new TestExit().runTest(this);
new TestFile().runTest(this); new TestFile().runTest(this);
new TestFileLock().runTest(this); new TestFileLock().runTest(this);
......
...@@ -37,6 +37,7 @@ public class TestOptimizations extends TestBase { ...@@ -37,6 +37,7 @@ public class TestOptimizations extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testInSelectJoin();
testMinMaxNullOptimization(); testMinMaxNullOptimization();
if (config.networked) { if (config.networked) {
return; return;
...@@ -54,6 +55,40 @@ public class TestOptimizations extends TestBase { ...@@ -54,6 +55,40 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(false); 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 { private void testOptimizeInJoinSelect() throws SQLException {
boolean old = SysProperties.optimizeInJoin; boolean old = SysProperties.optimizeInJoin;
SysProperties.optimizeInJoin = true; SysProperties.optimizeInJoin = true;
......
...@@ -24,6 +24,15 @@ public class TestOutOfMemory extends TestBase { ...@@ -24,6 +24,15 @@ public class TestOutOfMemory extends TestBase {
private LinkedList list = new LinkedList(); 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 { public void test() throws SQLException {
if (config.memory || config.mvcc) { if (config.memory || config.mvcc) {
return; return;
...@@ -42,7 +51,7 @@ public class TestOutOfMemory extends TestBase { ...@@ -42,7 +51,7 @@ public class TestOutOfMemory extends TestBase {
prep.execute(); prep.execute();
fail(); fail();
} catch (SQLException e) { } catch (SQLException e) {
assertEquals(ErrorCode.GENERAL_ERROR_1, e.getErrorCode()); assertEquals(ErrorCode.OUT_OF_MEMORY, e.getErrorCode());
} }
list = null; list = null;
ResultSet rs = stat.executeQuery("select count(*) from stuff"); ResultSet rs = stat.executeQuery("select count(*) from stuff");
......
...@@ -531,7 +531,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -531,7 +531,7 @@ public class TestPreparedStatement extends TestBase {
stat.execute("CREATE TABLE TEST(ID INT)"); stat.execute("CREATE TABLE TEST(ID INT)");
stat.execute("INSERT INTO TEST VALUES(1),(2),(3)"); stat.execute("INSERT INTO TEST VALUES(1),(2),(3)");
PreparedStatement prep = conn.prepareStatement("select x.id, ? from " 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); assertEquals(prep.getParameterMetaData().getParameterCount(), 4);
prep.setInt(1, 0); prep.setInt(1, 0);
prep.setInt(2, 1); prep.setInt(2, 1);
......
...@@ -84,7 +84,7 @@ public class TestFuzzOptimizations extends TestBase { ...@@ -84,7 +84,7 @@ public class TestFuzzOptimizations extends TestBase {
p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]); p.set(new String[] { null, "0", "1", "2" }[random.nextInt(4)]);
p.execute(); p.execute();
} }
int len = getSize(1000, 10000); int len = getSize(1000, 3000);
for (int i = 0; i < len / 10; i++) { for (int i = 0; i < len / 10; i++) {
db.execute("CREATE TABLE TEST_INDEXED AS SELECT * FROM TEST"); db.execute("CREATE TABLE TEST_INDEXED AS SELECT * FROM TEST");
int jLen = 1 + random.nextInt(2); int jLen = 1 + random.nextInt(2);
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- 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; create schema a;
> ok > ok
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- 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; create schema a;
> ok > ok
......
...@@ -55,12 +55,12 @@ I am sorry to say that, but it looks like a corruption problem. I am very intere ...@@ -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)? or two phase commit, linked tables, cache settings)?
- Is the application multi-threaded? - Is the application multi-threaded?
- On what operating system, file system, and virtual machine (java -version)? - 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 - Is the database usually closed normally, or is process terminated forcefully
or the computer switched off? or the computer switched off?
- Is it possible to reproduce this problem using a fresh database - Is it possible to reproduce this problem using a fresh database
(sometimes, or always)? (sometimes, or always)?
- Are there any other exceptions (maybe in the .trace.db file)? - 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? - 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?
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论