提交 3b93e5aa authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 eecb57d7
......@@ -38,15 +38,20 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / TODO</h3><ul>
<li>Some file operations didn't work for files in the root directory. Fixed.
</li>
</ul>
<h3>Version 1.0 / 2007-08-02</h3><ul>
<li>The column name C_CURRENT_TIMESTAMP did not work in the last release.
<h3>Version 1.0 / TODO (Build xx)</h3><ul>
<li>PG server: data was truncated when reading large VARCHAR columns and decimal columns.
</li><li>PG server: when the same database was accessed multiple times using the PostgreSQL ODBC driver,
the pg_catalog schema update failed, and connecting to the database was not possible. Fixed.
</li><li>Some file operations didn't work for files in the root directory. Fixed.
</li><li>In the Restore tool, the parameter -file did not work. Fixed.
</li><li>Two-phase commit: commit with transaction name was only supported in the recovery scan.
Now it is always supported.
</li><li>The column name C_CURRENT_TIMESTAMP did not work in the last release.
</li><li>OpenOffice compatibility: support database name in column names.
</li><li>A new tool to help translation has been implemented: src/tools/org/h2/tools/i18n/PrepareTranslation.
</li></ul>
<h3>Version 1.0 / 2007-08-02 (Build 56)</h3><ul>
<li>A new tool to help translation has been implemented: src/tools/org/h2/tools/i18n/PrepareTranslation.
This tool can detect delta changes in the original (English) and prepends '#' in translation if the original
text was changed. It can also extract text from the user documentation (however, it is incomplete).
</li><li>The error messages (src/main/org/h2/res/_*.*) can now be translated.
......@@ -798,13 +803,15 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>In Version 1.1</h3>
<ul>
<li>ALTER TABLE on a table with a LOB could result in 'Cannot delete file' on some systems. Fixed.
<li>Add version number. Install directory: h2-1.0, jar file: h2-1.0.jar. Micro version: use build number, staring with 1.1.100
</li><li>ALTER TABLE on a table with a LOB could result in 'Cannot delete file' on some systems. Fixed.
</li><li>Change Constants.DEFAULT_MAX_MEMORY_UNDO to 10000 (and change the docs). Test.
</li><li>Enable and document optimizations, LOB files in directories
</li><li>Special methods for DataPage.writeByte / writeShort and so on
</li><li>Index organized tables CREATE TABLE...(...) ORGANIZATION INDEX (store in data file) (probably file format changes are required for rowId)
</li><li>Change the default for NULL || 'x' to NULL
</li><li>Change the default isolation level to read committed
</li><li>Automatic upgrade if there is a file format change
</li></ul>
<h3>Priority 1</h3>
......
......@@ -201,7 +201,7 @@ public abstract class Query extends Prepared {
}
idx -= 1;
if(idx < 0 || idx >= originalLength) {
throw Message.getSQLException(Message.ORDER_BY_NOT_IN_RESULT, "index " + idx);
throw Message.getSQLException(Message.ORDER_BY_NOT_IN_RESULT, "" + (idx + 1));
}
}
index[i] = idx;
......
......@@ -66,6 +66,7 @@ public class Session implements SessionInterface {
private int serialId = nextSerialId++;
private boolean undoLogEnabled = true;
private boolean autoCommitAtTransactionEnd;
private String currentTransactionName;
public Session() {
}
......@@ -182,6 +183,7 @@ public class Session implements SessionInterface {
}
public void commit(boolean ddl) throws SQLException {
currentTransactionName = null;
if(containsUncommitted()) {
// need to commit even if rollback is not possible (create/drop table and so on)
logSystem.commit(this);
......@@ -211,6 +213,7 @@ public class Session implements SessionInterface {
}
public void rollback() throws SQLException {
currentTransactionName = null;
boolean needCommit = false;
if (undoLog.size() > 0) {
rollbackTo(0);
......@@ -407,15 +410,30 @@ public class Session implements SessionInterface {
// need to commit even if rollback is not possible (create/drop table and so on)
logSystem.prepareCommit(this, transactionName);
}
currentTransactionName = transactionName;
}
public void setPreparedTransaction(String transactionName, boolean commit) throws SQLException {
if(currentTransactionName != null && currentTransactionName.equals(transactionName)) {
if(commit) {
commit(false);
} else {
rollback();
}
} else {
ObjectArray list = logSystem.getInDoubtTransactions();
int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK;
boolean found = false;
for(int i=0; list!=null && i<list.size(); i++) {
InDoubtTransaction p = (InDoubtTransaction)list.get(i);
if(p.getTransaction().equals(transactionName)) {
p.setState(state);
found = true;
break;
}
}
if(!found) {
throw Message.getSQLException(Message.TRANSACTION_NOT_FOUND_1, transactionName);
}
}
}
......
......@@ -19,11 +19,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
*
* @author Thomas
*/
public class Message {
......@@ -224,6 +223,22 @@ public class Message {
public static final int FUNCTION_MUST_RETURN_RESULT_SET_1 = 90000;
public static final int METHOD_NOT_ALLOWED_FOR_QUERY = 90001;
public static final int METHOD_ONLY_ALLOWED_FOR_QUERY = 90002;
/**
* Thrown when trying to convert a String to a binary value. Two hex digits
* per byte are required. Example:
*
* <pre>
* CALL X'00023';
* Hexadecimal string with odd number of characters: 00023
* </pre>
*
* Correct:
*
* <pre>
* CALL X'000023';
* </pre>
*/
public static final int HEX_STRING_ODD_1 = 90003;
public static final int HEX_STRING_WRONG_1 = 90004;
public static final int VALUE_TOO_LONG_1 = 90005;
......@@ -237,8 +252,46 @@ public class Message {
public static final int DATABASE_NOT_FOUND_1 = 90013;
public static final int PARSE_ERROR_1 = 90014;
public static final int SUM_OR_AVG_ON_WRONG_DATATYPE_1 = 90015;
/**
* The column must be included in the group by clause. Example:
*
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
* SELECT ID, MAX(NAME) FROM TEST;
* Column ID must be in group by list.
* </pre>
*
* Correct:
*
* <pre>
* SELECT ID, MAX(NAME) FROM TEST GROUP BY ID;
* </pre>
*/
public static final int MUST_GROUP_BY_COLUMN_1 = 90016;
public static final int SECOND_PRIMARY_KEY = 90017;
/**
* The connection was opened, but never closed. In the finalizer of the
* connection, this forgotten close was detected and the connection was
* closed automatically, but relying on the finalizer is not good practice
* as it is not guaranteed and behavior is virtual machine dependent. The
* application should close the connection. This exception only appears in
* the .trace.db file. Example:
*
* <pre>
* Connection conn = DriverManager.getConnection(&quot;jdbc:h2:&tilde;/test&quot;);
* conn = null;
* The connection was not closed by the application and is garbage collected
* </pre>
*
* Correct:
*
* <pre>
* conn.close();
*
*/
public static final int TRACE_CONNECTION_NOT_CLOSED = 90018;
public static final int CANNOT_DROP_CURRENT_USER = 90019;
public static final int DATABASE_ALREADY_OPEN_1 = 90020;
......@@ -289,6 +342,20 @@ public class Message {
public static final int SAVEPOINT_IS_NAMED = 90065;
public static final int DUPLICATE_PROPERTY_1 = 90066;
public static final int CONNECTION_BROKEN = 90067;
/**
* The given expression that is used in the ORDER BY clause must be in the result list, otherwise the result would be ambiguous.
* <pre>
* CREATE TABLE TEST(ID INT, NAME VARCHAR);
* INSERT INTO TEST VALUES(2, 'Hello'), (1, 'Hello');
* SELECT DISTINCT NAME FROM TEST ORDER BY ID;
* Order by expression ID must be in the result list in this case
* </pre>
* Correct:
* <pre>
* SELECT DISTINCT ID, NAME FROM TEST ORDER BY ID;
* </pre>
*/
public static final int ORDER_BY_NOT_IN_RESULT = 90068;
public static final int ROLE_ALREADY_EXISTS_1 = 90069;
public static final int ROLE_NOT_FOUND_1 = 90070;
......@@ -306,10 +373,40 @@ public class Message {
public static final int SEQUENCE_BELONGS_TO_A_TABLE_1 = 90082;
public static final int COLUMN_MAY_BE_REFERENCED_1 = 90083;
public static final int CANNOT_DROP_LAST_COLUMN = 90084;
/**
* The index was generated by the system because of a unique constraint,
* and it is not allowed to drop it manually.
* <pre>
* CREATE TABLE TEST(ID INT, CONSTRAINT UID UNIQUE(ID));
* DROP INDEX UID_INDEX_0;
* Index UID_INDEX_0 belongs to a constraint
* </pre>
* Correct:
* <pre>
* ALTER TABLE TEST DROP CONSTRAINT UID;
* </pre>
*/
public static final int INDEX_BELONGS_TO_CONSTRAINT_1 = 90085;
public static final int CLASS_NOT_FOUND_1 = 90086;
public static final int METHOD_NOT_FOUND_1 = 90087;
public static final int UNKNOWN_MODE_1 = 90088;
/**
* The collection of the database must be set when the database is empty.
* <pre>
* CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
* INSERT INTO TEST VALUES('Hello', 'World');
* SET COLLATION DE;
* Collation cannot be changed because there is a data table: PUBLIC.TEST
* </pre>
* Correct:
* <pre>
* SET COLLATION DE;
* CREATE TABLE TEST(NAME VARCHAR PRIMARY KEY);
* INSERT INTO TEST VALUES('Hello', 'World');
* </pre>
*/
public static final int COLLATION_CHANGE_WITH_DATA_TABLE_1 = 90089;
public static final int SCHEMA_CAN_NOT_BE_DROPPED_1 = 90090;
public static final int ROLE_CAN_NOT_BE_DROPPED_1 = 90091;
......@@ -333,6 +430,15 @@ public class Message {
public static final int VIEW_IS_INVALID_2 = 90109;
public static final int OVERFLOW_FOR_TYPE_1 = 90110;
public static final int ERROR_ACCESSING_LINKED_TABLE_1 = 90111;
/**
* When locking was disabled, a row was deleted twice.
* This is an intern exception that should never be thrown to the application,
* because such deleted should be detected and the resulting exception ignored inside the database engine.
* <pre>
* Row not found when trying to delete from index UID_INDEX_0
* </pre>
*/
public static final int ROW_NOT_FOUND_WHEN_DELETING_1 = 90112;
public static final int UNSUPPORTED_SETTING_1 = 90113;
public static final int CONSTANT_ALREADY_EXISTS_1 = 90114;
......@@ -346,10 +452,28 @@ public class Message {
public static final int OPERATION_NOT_SUPPORTED_WITH_VIEWS_2 = 90122;
public static final int CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS = 90123;
public static final int FILE_NOT_FOUND_1 = 90124;
/**
* This exception is thrown when PreparedStatement.setBigDecimal is called
* with object that extends the class BigDecimal, and the system property
* h2.allowBigDecimalExtensions is not set. Using extensions of BigDecimal is
* dangerous because the database relies on the behavior of BigDecimal.
* <pre>
* BigDecimal bd = new MyDecimal("$10.3");
* prep.setBigDecimal(1, bd);
* Invalid class, expected java.math.BigDecimal but got MyDecimal
* </pre>
* Correct:
* <pre>
* BigDecimal bd = new BigDecimal("10.3");
* prep.setBigDecimal(1, bd);
* </pre>
*/
public static final int INVALID_CLASS_2 = 90125;
public static final int DATABASE_IS_NOT_PERSISTENT = 90126;
public static final int RESULT_SET_NOT_UPDATABLE = 90127;
public static final int RESULT_SET_NOT_SCROLLABLE = 90128;
public static final int TRANSACTION_NOT_FOUND_1 = 90129;
public static SQLException addSQL(SQLException e, String sql) {
if(e instanceof JdbcSQLException) {
......
......@@ -109,7 +109,7 @@
90086=Klasse {0} nicht gefunden
90087=Methode {0} nicht gefunden
90088=Unbekannter Modus {0}
90089=Textvergleich-Modus kann nicht ge\u00E4ndert werden wenn Tabellen vorhanden sind {0}
90089=Textvergleich-Modus kann nicht ge\u00E4ndert werden wenn eine Daten-Tabelle existiert \: {0}
90090=Schema {0} kann nicht gel\u00F6scht werden
90091=Rolle {0} kann nicht gel\u00F6scht werden
90092=Diese Java-Version wird nicht unterst\u00FCtzt (Java 1.4 oder neuer wird ben\u00F6tigt)
......@@ -149,6 +149,7 @@
90126=Datenbank ist nicht persistent
90127=Die Resultat-Zeilen k\u00F6nnen nicht ver\u00E4ndert werden. Die Abfrage muss alle Felder eines eindeutigen Schl\u00FCssels enthalten, und nur eine Tabelle enthalten.
90128=Kann nicht an den Anfang der Resultat-Zeilen springen. M\u00F6gliche L\u00F6sung\: conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY).
90129=Transaktion {0} nicht gefunden
HY000=Allgemeiner Fehler\: {0}
HY004=Unbekannter Datentyp\: {0}
HYC00=Dieses Feature wird unterst\u00FCtzt
......
......@@ -109,7 +109,7 @@
90086=Class {0} not found
90087=Method {0} not found
90088=Unknown mode {0}
90089=Collation cannot be changed because there is a data table {0}
90089=Collation cannot be changed because there is a data table\: {0}
90090=Schema {0} cannot be dropped
90091=Role {0} cannot be dropped
90092=This Java version is not supported (Java 1.4 is required)
......@@ -149,6 +149,7 @@
90126=Database is not persistent
90127=The result set is not updatable. The query must select all columns from a unique key. Only one table may be selected.
90128=The result set is not scrollable and can not be reset. You may need to use conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY).
90129=Transaction {0} not found
HY000=General error\: {0}
HY004=Unknown data type\: {0}
HYC00=Feature not supported
......
......@@ -512,10 +512,12 @@ public class PgServerThread implements Runnable {
} else {
int columns = meta.getColumnCount();
int[] types = new int[columns];
int[] precision = new int[columns];
String[] names = new String[columns];
for(int i=0; i<columns; i++) {
names[i] = meta.getColumnName(i + 1);
int type = meta.getColumnType(i + 1);
precision[i] = meta.getColumnDisplaySize(i + 1);
checkType(type);
types[i] = type;
}
......@@ -526,7 +528,7 @@ public class PgServerThread implements Runnable {
writeInt(0); // object ID
writeShort(0); // attribute number of the column
writeInt(types[i]); // data type
writeShort(getTypeSize(types[i])); // pg_type.typlen
writeShort(getTypeSize(types[i], precision[i])); // pg_type.typlen
writeInt(getModifier(types[i])); // pg_attribute.atttypmod
writeShort(0); // text
}
......@@ -537,12 +539,12 @@ public class PgServerThread implements Runnable {
}
}
private int getTypeSize(int type) {
private int getTypeSize(int type, int precision) {
switch(type) {
case Types.VARCHAR:
return 255;
return Math.max(255, precision + 10);
}
return type;
return precision + 4;
}
private int getModifier(int type) {
......@@ -584,6 +586,7 @@ public class PgServerThread implements Runnable {
if(rs.next()) {
if(rs.getInt(1) == 1) {
// already installed
stat.execute("set search_path = PUBLIC, pg_catalog");
return;
}
}
......
......@@ -8,8 +8,6 @@ create schema pg_catalog;
create table pg_catalog.pg_version as select 1 as version;
set search_path = PUBLIC, pg_catalog;
create view pg_catalog.pg_roles -- (oid, rolname, rolcreaterole, rolcreatedb)
as
select
......
......@@ -56,6 +56,8 @@ public class Restore {
for(int i=0; args != null && i<args.length; i++) {
if(args[i].equals("-dir")) {
dir = args[++i];
} else if(args[i].equals("-file")) {
zipFileName = args[++i];
} else if(args[i].equals("-db")) {
db = args[++i];
} else if(args[i].equals("-quiet")) {
......
......@@ -4,10 +4,7 @@
*/
package org.h2.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.h2.server.TcpServer;
......@@ -97,15 +94,7 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
create table test(id int);
update test t set t.id=1;
update public.test set public.test.id=1;
select count(test.public.test.id) from test.public.test;
update test.public.test set test.public.test.id=1;
drop table test.public.test;
search from a frame (but usually don't use frames)
Add version number. Install directory: h2-1.0, jar file: h2-1.0.jar
Class.forName("org.h2.Driver");
DeleteDbFiles.execute("~", null, true);
......@@ -119,6 +108,16 @@ search from a frame (but usually don't use frames)
Connection conn2 = DriverManager.getConnection("jdbc:h2:~/test");
conn2.createStatement().execute("select * from test");
create table test(id int);
set autocommit off;
insert into test values(1);
prepare commit tx1;
commit transaction tx1;
rollback;
select * from test;
drop table test;
call N'@name';
......@@ -241,6 +240,10 @@ io: wrapped streams are closed: simplify code
document SET SEARCH_PATH, BEGIN, EXECUTE, $ parameters
Complete Javadocs for Messages and add to docs
write tests using the PostgreSQL JDBC driver
*/
/*
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
create table test(id int);
> ok
set autocommit false;
> ok
insert into test values(1);
> update count: 1
prepare commit tx1;
> ok
commit transaction tx1;
> ok
rollback;
> ok
select * from test;
> ID
> --
> 1
> rows: 1
drop table test;
> ok
set autocommit true;
> ok
CALL REGEXP_REPLACE('abckaboooom', 'o+', 'o');
> 'abckabom'
> ----------
......
......@@ -124,9 +124,9 @@ public class Doclet {
writer.println("<tr><td class=\"return\">" + type + "</td><td class=\"method\">");
//writer.println("<a href=\"#f" + fieldId + "\">" + name + "</a>");
writer.println(name + " = " + field.constantValueExpression());
String firstSentence = getFirstSentence(field.firstSentenceTags());
if(firstSentence != null) {
writer.println("<div class=\"methodText\">"+firstSentence+"</div>");
String text = field.commentText();
if(text != null) {
writer.println("<div class=\"methodText\">"+text+"</div>");
}
writer.println("</td></tr>");
fieldId++;
......@@ -234,7 +234,6 @@ public class Doclet {
}
private static String getFirstSentence(Tag[] tags) {
String firstSentence = null;
if(tags.length>0) {
Tag first = tags[0];
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论