提交 07240945 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 6b606ae5
...@@ -245,16 +245,23 @@ ...@@ -245,16 +245,23 @@
</jar> </jar>
</target> </target>
<target name="mavenUploadCentral" depends="jar"> <target name="mavenDeployCentral" depends="jar">
<copy tofile="bin/h2-${version.name.maven}.jar" file="bin/h2.jar" /> <copy tofile="bin/h2-${version.name.maven}.jar" file="bin/h2.jar" />
<copy tofile="bin/pom.xml" filtering="true" file="src/installer/pomUpload.xml"> <copy tofile="bin/pom.xml" filtering="true" file="src/installer/pomUpload.xml">
<filterset> <filterset>
<filter token="version" value="${version.name.maven}"/> <filter token="version" value="${version.name.maven}"/>
</filterset> </filterset>
</copy> </copy>
<exec executable="mvn.bat">
<arg value="deploy:deploy-file"/>
<arg value="-Dfile=bin/h2.jar"/>
<arg value="-Durl=file://C:/data/h2database/m2-repo"/>
<arg value="-Dpackaging=jar"/>
<arg value="-DpomFile=bin/pom.xml"/>
</exec>
</target> </target>
<target name="mavenUploadLocal" depends="jar"> <target name="mavenInstallLocal" depends="jar">
<copy tofile="bin/pom.xml" filtering="true" file="src/installer/pom.xml"> <copy tofile="bin/pom.xml" filtering="true" file="src/installer/pom.xml">
<filterset> <filterset>
<filter token="version" value="1.0-SNAPSHOT"/> <filter token="version" value="1.0-SNAPSHOT"/>
...@@ -264,8 +271,6 @@ ...@@ -264,8 +271,6 @@
<arg value="install:install-file"/> <arg value="install:install-file"/>
<arg value="-Dversion=1.0-SNAPSHOT"/> <arg value="-Dversion=1.0-SNAPSHOT"/>
<arg value="-Dfile=bin/h2.jar"/> <arg value="-Dfile=bin/h2.jar"/>
<arg value="-DgroupId=org.h2database"/>
<arg value="-DartifactId=h2"/>
<arg value="-Dpackaging=jar"/> <arg value="-Dpackaging=jar"/>
<arg value="-DpomFile=bin/pom.xml"/> <arg value="-DpomFile=bin/pom.xml"/>
</exec> </exec>
......
...@@ -81,7 +81,7 @@ The version is currently 1.0.&lt;year&gt;&lt;month&gt;&lt;day&gt;. Example: ...@@ -81,7 +81,7 @@ The version is currently 1.0.&lt;year&gt;&lt;month&gt;&lt;day&gt;. Example:
<p> <p>
To build a 'snapshot' H2 .jar file and upload it the to the local Maven 2 repository, execute the following command: To build a 'snapshot' H2 .jar file and upload it the to the local Maven 2 repository, execute the following command:
<pre> <pre>
ant mavenUploadLocal ant mavenInstallLocal
</pre> </pre>
Afterwards, you can include the database in your Maven 2 project as a dependency: Afterwards, you can include the database in your Maven 2 project as a dependency:
<pre> <pre>
......
...@@ -991,7 +991,7 @@ will always enable the trace mode when connecting. ...@@ -991,7 +991,7 @@ will always enable the trace mode when connecting.
If the database files are read-only, then the database is read-only as well. If the database files are read-only, then the database is read-only as well.
It is not possible to create new tables, add or modify data in this database. It is not possible to create new tables, add or modify data in this database.
Only SELECT statements are allowed. Only SELECT statements are allowed.
To create a read-only database, close the database so that the log file is deleted. To create a read-only database, close the database so that the log file gets smaller. Do not delete the log file.
Then, make the database files read-only using the operating system. Then, make the database files read-only using the operating system.
When you open the database now, it is read-only. When you open the database now, it is read-only.
There are two ways an application can find out a database is read-only: There are two ways an application can find out a database is read-only:
......
...@@ -43,6 +43,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -43,6 +43,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<li>New experimental feature MVCC (multi version concurrency control). <li>New experimental feature MVCC (multi version concurrency control).
Can be set as a option when opening the database (jdbc:h2:test;MVCC=TRUE) Can be set as a option when opening the database (jdbc:h2:test;MVCC=TRUE)
or as a system property (-Dh2.mvcc=true). This is work-in-progress, use it at your own risk. Feedback is welcome. or as a system property (-Dh2.mvcc=true). This is work-in-progress, use it at your own risk. Feedback is welcome.
</li><li>The backup tool (org.h2.tools.Backup) did not work. The restore tool did not work when the -db parameter was used. Fixed.
The documentation of the backup tool has been changed: only one database may be backed up at any time.
</li><li>Opening large read-only databases was very slow. Fixed.
</li><li>New Japanese translation of the error messages thanks to Ikemoto Masahiro. Thanks a lot!
</li><li>Disabling / enabling referential integrity for a table can now be used inside a transaction.
</li><li>Rights checking for dynamic tables (SELECT * FROM (SELECT ...)) did not work. Fixed.
</li><li>Creating more than 10 views that depend on each other was very slow. Reconnecting was slow as well. Fixed. </li><li>Creating more than 10 views that depend on each other was very slow. Reconnecting was slow as well. Fixed.
</li><li>When used as as Servlet, the H2 Console did not work with SSL (using Tomcat). Fixed. </li><li>When used as as Servlet, the H2 Console did not work with SSL (using Tomcat). Fixed.
</li><li>When altering a table with foreign key constraint, if there was no manual index created </li><li>When altering a table with foreign key constraint, if there was no manual index created
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -150,6 +150,8 @@ ...@@ -150,6 +150,8 @@
90127=The result set is not updatable. The query must select all columns from a unique key. Only one table may be selected. 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). 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 90129=Transaction {0} not found
90130=This method is not allowed for a prepared statement; use a regular statement instead.
90131=Concurrent update in table {0}\: another transaction has updated or deleted the same row
HY000=General error\: {0} HY000=General error\: {0}
HY004=Unknown data type\: {0} HY004=Unknown data type\: {0}
HYC00=Feature not supported HYC00=Feature not supported
......
...@@ -19,10 +19,4 @@ ...@@ -19,10 +19,4 @@
</scm> </scm>
<dependencies> <dependencies>
</dependencies> </dependencies>
<distributionManagement>
<repository>
<id>ftp-repository</id>
<url>ftp://h2database.com/httpdocs/m2-repo</url>
</repository>
</distributionManagement>
</project> </project>
\ No newline at end of file
...@@ -48,6 +48,7 @@ import org.h2.command.ddl.GrantRevoke; ...@@ -48,6 +48,7 @@ import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure; import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SetComment; import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable; import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.AlterTableSet;
import org.h2.command.dml.BackupCommand; import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call; import org.h2.command.dml.Call;
import org.h2.command.dml.Delete; import org.h2.command.dml.Delete;
...@@ -801,7 +802,9 @@ public class Parser { ...@@ -801,7 +802,9 @@ public class Parser {
s = session; s = session;
} }
String tempViewName = s.getNextTempViewName(); String tempViewName = s.getNextTempViewName();
table = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s, false); TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s, false);
v.setOwner(session.getUser());
table = v;
if(s != database.getSystemSession()) { if(s != database.getSystemSession()) {
table.setOnCommitDrop(true); table.setOnCommitDrop(true);
} }
...@@ -3837,15 +3840,13 @@ public class Parser { ...@@ -3837,15 +3840,13 @@ public class Parser {
read("REFERENTIAL_INTEGRITY"); read("REFERENTIAL_INTEGRITY");
int type; int type;
if(readIf("TRUE")) { if(readIf("TRUE")) {
type = AlterTableAddConstraint.REFERENTIAL_INTEGRITY_TRUE; type = AlterTableSet.REFERENTIAL_INTEGRITY_TRUE;
} else { } else {
read("FALSE"); read("FALSE");
type = AlterTableAddConstraint.REFERENTIAL_INTEGRITY_FALSE; type = AlterTableSet.REFERENTIAL_INTEGRITY_FALSE;
} }
AlterTableAddConstraint command = new AlterTableAddConstraint(session, table.getSchema()); AlterTableSet command = new AlterTableSet(session, table.getSchema(), type);
command.setTableName(table.getName()); command.setTableName(table.getName()); if(readIf("CHECK")) {
command.setType(type);
if(readIf("CHECK")) {
command.setCheckExisting(true); command.setCheckExisting(true);
} else if(readIf("NOCHECK")) { } else if(readIf("NOCHECK")) {
command.setCheckExisting(false); command.setCheckExisting(false);
......
...@@ -33,8 +33,6 @@ import org.h2.util.ObjectArray; ...@@ -33,8 +33,6 @@ import org.h2.util.ObjectArray;
public class AlterTableAddConstraint extends SchemaCommand { public class AlterTableAddConstraint extends SchemaCommand {
public static final int CHECK = 0, UNIQUE = 1, REFERENTIAL = 2, PRIMARY_KEY = 3; public static final int CHECK = 0, UNIQUE = 1, REFERENTIAL = 2, PRIMARY_KEY = 3;
public static final int REFERENTIAL_INTEGRITY_TRUE = 4;
public static final int REFERENTIAL_INTEGRITY_FALSE = 5;
private int type; private int type;
private String constraintName; private String constraintName;
private String tableName; private String tableName;
...@@ -164,12 +162,6 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -164,12 +162,6 @@ public class AlterTableAddConstraint extends SchemaCommand {
ref.setUpdateAction(session, updateAction); ref.setUpdateAction(session, updateAction);
break; break;
} }
case REFERENTIAL_INTEGRITY_TRUE:
table.setCheckForeignKeyConstraints(session, true, checkExisting);
return 0;
case REFERENTIAL_INTEGRITY_FALSE:
table.setCheckForeignKeyConstraints(session, false, false);
return 0;
default: default:
throw Message.getInternalError("type="+type); throw Message.getInternalError("type="+type);
} }
......
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.dml;
import java.sql.SQLException;
import org.h2.command.ddl.SchemaCommand;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.schema.Schema;
import org.h2.table.Table;
public class AlterTableSet extends SchemaCommand {
private String tableName;
private final int type;
private boolean checkExisting;
public static final int REFERENTIAL_INTEGRITY_TRUE = 4;
public static final int REFERENTIAL_INTEGRITY_FALSE = 5;
public AlterTableSet(Session session, Schema schema, int type) {
super(session, schema);
this.type = type;
}
public void setCheckExisting(boolean b) {
this.checkExisting = b;
}
public boolean isTransactional() {
return true;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public int update() throws SQLException {
Table table = getSchema().getTableOrView(session, tableName);
session.getUser().checkRight(table, Right.ALL);
table.lock(session, true, true);
switch(type) {
case REFERENTIAL_INTEGRITY_TRUE:
table.setCheckForeignKeyConstraints(session, true, checkExisting);
break;
case REFERENTIAL_INTEGRITY_FALSE:
table.setCheckForeignKeyConstraints(session, false, false);
break;
default:
throw Message.getInternalError("type="+type);
}
return 0;
}
public LocalResult queryMeta() {
return null;
}
}
...@@ -322,7 +322,6 @@ public class Select extends Query { ...@@ -322,7 +322,6 @@ public class Select extends Query {
} }
topTableFilter.startQuery(session); topTableFilter.startQuery(session);
topTableFilter.reset(); topTableFilter.reset();
// TODO lock tables of sub queries
topTableFilter.lock(session, isForUpdate, isForUpdate); topTableFilter.lock(session, isForUpdate, isForUpdate);
if(isQuickQuery) { if(isQuickQuery) {
queryQuick(columnCount, result); queryQuick(columnCount, result);
......
...@@ -312,6 +312,7 @@ public class ErrorCode { ...@@ -312,6 +312,7 @@ public class ErrorCode {
public static final int RESULT_SET_NOT_SCROLLABLE = 90128; public static final int RESULT_SET_NOT_SCROLLABLE = 90128;
public static final int TRANSACTION_NOT_FOUND_1 = 90129; public static final int TRANSACTION_NOT_FOUND_1 = 90129;
public static final int METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT = 90130; public static final int METHOD_NOT_ALLOWED_FOR_PREPARED_STATEMENT = 90130;
public static final int CONCURRENT_UPDATE_1 = 90131;
/** /**
* INTERNAL * INTERNAL
......
...@@ -436,9 +436,7 @@ public class Database implements DataHandler { ...@@ -436,9 +436,7 @@ public class Database implements DataHandler {
log = new LogSystem(this, databaseName, readOnly, accessModeLog); log = new LogSystem(this, databaseName, readOnly, accessModeLog);
openFileData(); openFileData();
openFileIndex(); openFileIndex();
if(!readOnly) {
log.recover(); log.recover();
}
fileData.init(); fileData.init();
try { try {
fileIndex.init(); fileIndex.init();
......
...@@ -194,6 +194,7 @@ public class Session implements SessionInterface { ...@@ -194,6 +194,7 @@ public class Session implements SessionInterface {
if(undoLog.size() > 0) { if(undoLog.size() > 0) {
if(database.isMultiVersion()) { if(database.isMultiVersion()) {
ArrayList rows = new ArrayList(); ArrayList rows = new ArrayList();
synchronized(database) {
while (undoLog.size() > 0) { while (undoLog.size() > 0) {
UndoLogRecord entry = undoLog.getAndRemoveLast(); UndoLogRecord entry = undoLog.getAndRemoveLast();
entry.commit(); entry.commit();
...@@ -204,6 +205,7 @@ public class Session implements SessionInterface { ...@@ -204,6 +205,7 @@ public class Session implements SessionInterface {
r.commit(); r.commit();
} }
} }
}
undoLog.clear(); undoLog.clear();
} }
if(!ddl) { if(!ddl) {
......
...@@ -13,6 +13,7 @@ import org.h2.security.SHA256; ...@@ -13,6 +13,7 @@ import org.h2.security.SHA256;
import org.h2.table.MetaTable; import org.h2.table.MetaTable;
import org.h2.table.RangeTable; import org.h2.table.RangeTable;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableView;
import org.h2.util.ByteUtils; import org.h2.util.ByteUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.RandomUtils; import org.h2.util.RandomUtils;
...@@ -78,6 +79,14 @@ public class User extends RightOwner { ...@@ -78,6 +79,14 @@ public class User extends RightOwner {
// everybody has access to the metadata information // everybody has access to the metadata information
return; return;
} }
if(Table.VIEW.equals(table.getTableType())) {
TableView v = (TableView) table;
if(v.getOwner() == this) {
// the owner of a view has access:
// SELECT * FROM (SELECT * FROM ...)
return;
}
}
if(!isRightGrantedRecursive(table, rightMask)) { if(!isRightGrantedRecursive(table, rightMask)) {
throw Message.getSQLException(ErrorCode.NOT_ENOUGH_RIGHTS_FOR_1, table.getSQL()); throw Message.getSQLException(ErrorCode.NOT_ENOUGH_RIGHTS_FOR_1, table.getSQL());
} }
......
...@@ -6,7 +6,6 @@ package org.h2.expression; ...@@ -6,7 +6,6 @@ package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.command.dml.Select; import org.h2.command.dml.Select;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package org.h2.expression; package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
......
...@@ -16,22 +16,24 @@ public class MultiVersionCursor implements Cursor { ...@@ -16,22 +16,24 @@ public class MultiVersionCursor implements Cursor {
private final MultiVersionIndex index; private final MultiVersionIndex index;
private final Session session; private final Session session;
private final Cursor baseCursor, deltaCursor; private final Cursor baseCursor, deltaCursor;
private final Object sync;
private SearchRow baseRow; private SearchRow baseRow;
private Row deltaRow; private Row deltaRow;
private boolean onBase; private boolean onBase;
private boolean end; private boolean end;
private boolean needNewDelta, needNewBase; private boolean needNewDelta, needNewBase;
MultiVersionCursor(Session session, MultiVersionIndex index, Cursor base, Cursor delta) throws SQLException { MultiVersionCursor(Session session, MultiVersionIndex index, Cursor base, Cursor delta, Object sync) throws SQLException {
this.session = session; this.session = session;
this.index = index; this.index = index;
this.baseCursor = base; this.baseCursor = base;
this.deltaCursor = delta; this.deltaCursor = delta;
this.sync = sync;
needNewDelta = needNewBase = true; needNewDelta = needNewBase = true;
} }
private void loadNext(boolean base) throws SQLException { private void loadNext(boolean base) throws SQLException {
synchronized(index) { synchronized(sync) {
if(base) { if(base) {
if(baseCursor.next()) { if(baseCursor.next()) {
baseRow = baseCursor.getSearchRow(); baseRow = baseCursor.getSearchRow();
...@@ -49,7 +51,7 @@ public class MultiVersionCursor implements Cursor { ...@@ -49,7 +51,7 @@ public class MultiVersionCursor implements Cursor {
} }
public Row get() throws SQLException { public Row get() throws SQLException {
synchronized(index) { synchronized(sync) {
if(SysProperties.CHECK && end) { if(SysProperties.CHECK && end) {
throw Message.getInternalError(); throw Message.getInternalError();
} }
...@@ -58,7 +60,7 @@ public class MultiVersionCursor implements Cursor { ...@@ -58,7 +60,7 @@ public class MultiVersionCursor implements Cursor {
} }
public int getPos() { public int getPos() {
synchronized(index) { synchronized(sync) {
if(SysProperties.CHECK && end) { if(SysProperties.CHECK && end) {
throw Message.getInternalError(); throw Message.getInternalError();
} }
...@@ -67,7 +69,7 @@ public class MultiVersionCursor implements Cursor { ...@@ -67,7 +69,7 @@ public class MultiVersionCursor implements Cursor {
} }
public SearchRow getSearchRow() throws SQLException { public SearchRow getSearchRow() throws SQLException {
synchronized(index) { synchronized(sync) {
if(SysProperties.CHECK && end) { if(SysProperties.CHECK && end) {
throw Message.getInternalError(); throw Message.getInternalError();
} }
...@@ -76,7 +78,7 @@ public class MultiVersionCursor implements Cursor { ...@@ -76,7 +78,7 @@ public class MultiVersionCursor implements Cursor {
} }
public boolean next() throws SQLException { public boolean next() throws SQLException {
synchronized(index) { synchronized(sync) {
if(SysProperties.CHECK && end) { if(SysProperties.CHECK && end) {
throw Message.getInternalError(); throw Message.getInternalError();
} }
...@@ -99,7 +101,12 @@ public class MultiVersionCursor implements Cursor { ...@@ -99,7 +101,12 @@ public class MultiVersionCursor implements Cursor {
return true; return true;
} }
} }
boolean isThisSession = deltaRow.getSessionId() == session.getId(); int sessionId = deltaRow.getSessionId();
if(sessionId == 0) {
int testing;
System.out.println("sessionId==0");
}
boolean isThisSession = sessionId == session.getId();
boolean isDeleted = deltaRow.getDeleted(); boolean isDeleted = deltaRow.getDeleted();
if(isThisSession && isDeleted) { if(isThisSession && isDeleted) {
needNewDelta = true; needNewDelta = true;
......
...@@ -21,15 +21,18 @@ public class MultiVersionIndex implements Index { ...@@ -21,15 +21,18 @@ public class MultiVersionIndex implements Index {
private final Index base; private final Index base;
private final TreeIndex delta; private final TreeIndex delta;
private final TableData table; private final TableData table;
private final Object sync;
public MultiVersionIndex(Index base, TableData table) throws SQLException { public MultiVersionIndex(Index base, TableData table) throws SQLException {
this.base = base; this.base = base;
this.table = table; this.table = table;
IndexType deltaIndexType = IndexType.createNonUnique(false); IndexType deltaIndexType = IndexType.createNonUnique(false);
this.delta = new TreeIndex(table, -1, "DELTA" ,base.getColumns(), deltaIndexType); this.delta = new TreeIndex(table, -1, "DELTA" ,base.getColumns(), deltaIndexType);
this.sync = base.getDatabase();
} }
public synchronized void add(Session session, Row row) throws SQLException { public void add(Session session, Row row) throws SQLException {
synchronized(sync) {
base.add(session, row); base.add(session, row);
// for example rolling back an delete operation // for example rolling back an delete operation
removeIfExists(session, row); removeIfExists(session, row);
...@@ -38,22 +41,27 @@ public class MultiVersionIndex implements Index { ...@@ -38,22 +41,27 @@ public class MultiVersionIndex implements Index {
delta.add(session, row); delta.add(session, row);
} }
} }
}
public synchronized void close(Session session) throws SQLException { public void close(Session session) throws SQLException {
synchronized(sync) {
base.close(session); base.close(session);
} }
}
public synchronized Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException { public Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException {
synchronized(sync) {
Cursor baseCursor = base.find(session, first, last); Cursor baseCursor = base.find(session, first, last);
Cursor deltaCursor = delta.find(session, first, last); Cursor deltaCursor = delta.find(session, first, last);
return new MultiVersionCursor(session, this, baseCursor, deltaCursor); return new MultiVersionCursor(session, this, baseCursor, deltaCursor, sync);
}
} }
public boolean canGetFirstOrLast(boolean first) { public boolean canGetFirstOrLast(boolean first) {
return false; return false;
} }
public synchronized SearchRow findFirstOrLast(Session session, boolean first) throws SQLException { public SearchRow findFirstOrLast(Session session, boolean first) throws SQLException {
throw Message.getUnsupportedException(); throw Message.getUnsupportedException();
} }
...@@ -65,7 +73,7 @@ public class MultiVersionIndex implements Index { ...@@ -65,7 +73,7 @@ public class MultiVersionIndex implements Index {
return base.needRebuild(); return base.needRebuild();
} }
private synchronized boolean removeIfExists(Session session, Row row) throws SQLException { private boolean removeIfExists(Session session, Row row) throws SQLException {
// maybe it was inserted by the same session just before // maybe it was inserted by the same session just before
Cursor c = delta.find(session, row, row); Cursor c = delta.find(session, row, row);
while(c.next()) { while(c.next()) {
...@@ -78,27 +86,43 @@ public class MultiVersionIndex implements Index { ...@@ -78,27 +86,43 @@ public class MultiVersionIndex implements Index {
return false; return false;
} }
public synchronized void remove(Session session, Row row) throws SQLException { public void remove(Session session, Row row) throws SQLException {
synchronized(sync) {
base.remove(session, row); base.remove(session, row);
if(removeIfExists(session, row)) { if(removeIfExists(session, row)) {
// added and deleted in the same transaction: no change // added and deleted in the same transaction: no change
} else { } else {
int testing;
if(row.getSessionId() == 0) {
System.out.println("stop! " + row);
System.out.flush();
new Error().printStackTrace();
Runtime.getRuntime().halt(1);
}
delta.add(session, row); delta.add(session, row);
} }
} }
}
public synchronized void remove(Session session) throws SQLException { public void remove(Session session) throws SQLException {
synchronized(sync) {
base.remove(session); base.remove(session);
} }
}
public synchronized void truncate(Session session) throws SQLException { public void truncate(Session session) throws SQLException {
synchronized(sync) {
delta.truncate(session); delta.truncate(session);
base.truncate(session); base.truncate(session);
} }
}
public synchronized void commit(int operation, Row row) throws SQLException { public void commit(int operation, Row row) throws SQLException {
synchronized(sync) {
removeIfExists(null, row); removeIfExists(null, row);
} }
}
public int compareKeys(SearchRow rowData, SearchRow compare) { public int compareKeys(SearchRow rowData, SearchRow compare) {
return base.compareKeys(rowData, compare); return base.compareKeys(rowData, compare);
...@@ -168,10 +192,12 @@ public class MultiVersionIndex implements Index { ...@@ -168,10 +192,12 @@ public class MultiVersionIndex implements Index {
return base.isNull(newRow); return base.isNull(newRow);
} }
public synchronized void removeChildrenAndResources(Session session) throws SQLException { public void removeChildrenAndResources(Session session) throws SQLException {
synchronized(sync) {
table.removeIndex(this); table.removeIndex(this);
remove(session); remove(session);
} }
}
public String getSQL() { public String getSQL() {
return base.getSQL(); return base.getSQL();
......
...@@ -52,6 +52,10 @@ public class ScanCursor implements Cursor { ...@@ -52,6 +52,10 @@ public class ScanCursor implements Cursor {
while(true) { while(true) {
if(deleted.hasNext()) { if(deleted.hasNext()) {
row = (Row) deleted.next(); row = (Row) deleted.next();
if(row.getDeleted() && row.getSessionId() == session.getId()) {
row = null;
continue;
}
} else { } else {
row = scan.getNextRow(session, row); row = scan.getNextRow(session, row);
} }
......
...@@ -128,7 +128,7 @@ public class ScanIndex extends BaseIndex { ...@@ -128,7 +128,7 @@ public class ScanIndex extends BaseIndex {
} }
if(database.isMultiVersion()) { if(database.isMultiVersion()) {
if(deleted != null) { if(deleted != null) {
deleted.add(row); deleted.remove(row);
} }
incrementRowCount(session.getId(), 1); incrementRowCount(session.getId(), 1);
} }
......
...@@ -58,7 +58,7 @@ implements ParameterMetaData ...@@ -58,7 +58,7 @@ implements ParameterMetaData
/** /**
* Returns the parameter type. * Returns the parameter type.
* Always returns Types.VARCHAR everything can be passed as a VARCHAR. * Always returns Types.VARCHAR as everything can be passed as a VARCHAR.
* *
* @return Types.VARCHAR * @return Types.VARCHAR
*/ */
......
...@@ -151,6 +151,7 @@ ...@@ -151,6 +151,7 @@
90128=Kann nicht an den Anfang der Resultat-Zeilen springen. M\u00F6gliche L\u00F6sung\: conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY). 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 90129=Transaktion {0} nicht gefunden
90130=\#This method is not allowed for a prepared statement; use a regular statement instead. 90130=\#This method is not allowed for a prepared statement; use a regular statement instead.
90131=\#Concurrent update in table {0}\: another transaction has updated or deleted the same row
HY000=Allgemeiner Fehler\: {0} HY000=Allgemeiner Fehler\: {0}
HY004=Unbekannter Datentyp\: {0} HY004=Unbekannter Datentyp\: {0}
HYC00=Dieses Feature wird unterst\u00FCtzt HYC00=Dieses Feature wird unterst\u00FCtzt
......
...@@ -151,6 +151,7 @@ ...@@ -151,6 +151,7 @@
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). 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 90129=Transaction {0} not found
90130=This method is not allowed for a prepared statement; use a regular statement instead. 90130=This method is not allowed for a prepared statement; use a regular statement instead.
90131=Concurrent update in table {0}\: another transaction has updated or deleted the same row
HY000=General error\: {0} HY000=General error\: {0}
HY004=Unknown data type\: {0} HY004=Unknown data type\: {0}
HYC00=Feature not supported HYC00=Feature not supported
......
.translator=IKEMOTO, Masahiro
02000=\u6709\u52b9\u306a\u30c7\u30fc\u30bf\u304c\u3042\u308a\u307e\u305b\u3093
07001={0} \u306f\u7121\u52b9\u306a\u30d1\u30e9\u30e1\u30fc\u30bf\u756a\u53f7\u3067\u3059, \u671f\u5f85\u3055\u308c\u308b\u756a\u53f7\: {1}
08000=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30aa\u30fc\u30d7\u30f3\u30a8\u30e9\u30fc
08004=\u30e6\u30fc\u30b6\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u304c\u4e0d\u6b63\u3067\u3059
21S02=\u5217\u756a\u53f7\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093
22003=\u7bc4\u56f2\u5916\u306e\u6570\u5024\u3067\u3059
22012=\u30bc\u30ed\u3067\u9664\u7b97\u3057\u307e\u3057\u305f\: {0}
22025=LIKE ESCAPE \u306b\u30a8\u30e9\u30fc\u304c\u3042\u308a\u307e\u3059\: {0}
23000=\u5236\u7d04\u9055\u53cd\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\: {0}
23001=\u30e6\u30cb\u30fc\u30af\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3001\u307e\u305f\u306f\u30d7\u30e9\u30a4\u30de\u30ea\u30ad\u30fc\u9055\u53cd\: {0}
23002=\u53c2\u7167\u6574\u5408\u6027\u5236\u7d04\u9055\u53cd\: {0}
23003=\u53c2\u7167\u6574\u5408\u6027\u5236\u7d04\u9055\u53cd\: {0}
42000=SQL\u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8\u306b\u6587\u6cd5\u30a8\u30e9\u30fc\u304c\u3042\u308a\u307e\u3059 {0}
42001=SQL\u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8\u306b\u6587\u6cd5\u30a8\u30e9\u30fc\u304c\u3042\u308a\u307e\u3059 {0}; \u671f\u5f85\u3055\u308c\u308b\u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8 {1}
42S01=\u30c6\u30fc\u30d6\u30eb {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
42S02=\u30c6\u30fc\u30d6\u30eb {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
42S11=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9 {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
42S12=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
42S21=\u5217\u540d {0} \u304c\u91cd\u8907\u3057\u3066\u3044\u307e\u3059
42S22=\u5217 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
42S32=\u8a2d\u5b9a {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90000=\u95a2\u6570 {0} \u306f\u30ea\u30b6\u30eb\u30c8\u30bb\u30c3\u30c8\u3092\u8fd4\u3055\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
90001=\u30e1\u30bd\u30c3\u30c9\u306f\u30af\u30a8\u30ea\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002executeUpdate\u306e\u304b\u308f\u308a\u306b\u3001excute\u3001\u307e\u305f\u306fexecuteQuery\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044
90002=\u30e1\u30bd\u30c3\u30c9\u306f\u30af\u30a8\u30ea\u3057\u304b\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002executeQuery\u306e\u304b\u308f\u308a\u306b\u3001excecute\u3001\u307e\u305f\u306fexecuteUpdate\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044
90003=\u6587\u5b57\u6570\u304c\u5947\u6570\u306e16\u9032\u6587\u5b57\u5217\u3067\u3059\: {0}
90004=16\u9032\u6587\u5b57\u5217\u306b\u4e0d\u6b63\u306a\u6587\u5b57\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\: {0}
90005=\u5217 {0} \u306e\u5024\u304c\u9577\u904e\u304e\u307e\u3059
90006=\u5217 {0} \u306b\u306fnull\u5024\u304c\u8a31\u3055\u308c\u3066\u3044\u307e\u305b\u3093
90007=\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u3059\u3067\u306b\u9589\u3058\u3089\u308c\u3066\u3044\u307e\u3059
90008=\u30d1\u30e9\u30e1\u30fc\u30bf {1} \u306b\u5bfe\u3059\u308b\u5024 {0} \u304c\u4e0d\u6b63\u3067\u3059
90009=\u65e5\u4ed8\u5b9a\u6570 {0} \u3092\u89e3\u6790\u3067\u304d\u307e\u305b\u3093
90010=\u6642\u9593\u5b9a\u6570 {0} \u3092\u89e3\u6790\u3067\u304d\u307e\u305b\u3093
90011=\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u5b9a\u6570 {0} \u3092\u89e3\u6790\u3067\u304d\u307e\u305b\u3093
90012=\u30d1\u30e9\u30e1\u30fc\u30bf {0} \u304c\u30bb\u30c3\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093
90013=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90014=\u89e3\u6790\u30a8\u30e9\u30fc {0}
90015=SUM\u3001AVG\u3092\u4e0d\u6b63\u306a\u30c7\u30fc\u30bf\u578b {0} \u306b\u4f7f\u7528\u3057\u307e\u3057\u305f
90016=\u5217 {0} \u306f\u30ea\u30b9\u30c8\u306b\u3088\u308a\u30b0\u30eb\u30fc\u30d7\u5316\u3055\u308c\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
90017=\u8907\u6570\u306e\u30d7\u30e9\u30a4\u30de\u30ea\u30ad\u30fc\u3092\u5b9a\u7fa9\u3057\u3088\u3046\u3068\u3057\u307e\u3057\u305f
90018=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u3088\u308a\u9589\u3058\u3089\u308c\u3066\u3044\u306a\u3044\u63a5\u7d9a\u304c\u30ac\u30d9\u30fc\u30b8\u30b3\u30ec\u30af\u30c8\u3055\u308c\u307e\u3057\u305f
90019=\u4f7f\u7528\u4e2d\u306e\u30e6\u30fc\u30b6\u3092drop\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
90020=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u4f7f\u7528\u4e2d\u3067\u3059\: {0}. \u53ef\u80fd\u306a\u89e3\u6c7a\u7b56\: \u4ed6\u306e\u63a5\u7d9a\u3092\u5168\u3066\u9589\u3058\u308b; \u30b5\u30fc\u30d0\u30e2\u30fc\u30c9\u3092\u4f7f\u3046
90021=\u30c7\u30fc\u30bf\u5909\u63db\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f {0}
90022=\u95a2\u6570 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90023=\u5217 {0} \u306b\u306fnull\u5024\u3092\u8a31\u3059\u3079\u304d\u3066\u306f\u3042\u308a\u307e\u305b\u3093
90024=\u30d5\u30a1\u30a4\u30eb\u540d\u3092 {0} \u304b\u3089 {1} \u306b\u5909\u66f4\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
90025=\u30d5\u30a1\u30a4\u30eb {0} \u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093
90026=\u76f4\u5217\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f
90027=\u76f4\u5217\u5316\u5fa9\u5143\u306b\u5931\u6557\u3057\u307e\u3057\u305f
90028=\u5165\u51fa\u529b\u4f8b\u5916\: {0}
90029=\u73fe\u5728\u884c\u306f\u66f4\u65b0\u4e0d\u53ef\u3067\u3059
90030=\u30ec\u30b3\u30fc\u30c9 {0} \u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u30d5\u30a1\u30a4\u30eb\u306e\u7834\u640d\u3092\u691c\u51fa\u3057\u307e\u3057\u305f\u3002\u53ef\u80fd\u306a\u89e3\u6c7a\u7b56\: \u30ea\u30ab\u30d0\u30ea\u30c4\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044
90031=\u5165\u51fa\u529b\u4f8b\u5916\: {0}; {1}
90032=\u30e6\u30fc\u30b6 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90033=\u30e6\u30fc\u30b6 {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90034=\u30ed\u30b0\u30d5\u30a1\u30a4\u30eb\u30a8\u30e9\u30fc\: {0}
90035=\u30b7\u30fc\u30b1\u30f3\u30b9 {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90036=\u30b7\u30fc\u30b1\u30f3\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90037=\u30d3\u30e5\u30fc {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90038=\u30d3\u30e5\u30fc {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90039=\u7cbe\u5ea6 {0} \u306b\u5bfe\u3057\u3066\u5024\u304c\u5927\u304d\u3059\u304e\u307e\u3059
90040=\u3053\u306e\u64cd\u4f5c\u306b\u306f\u7ba1\u7406\u6a29\u9650\u304c\u5fc5\u8981\u3067\u3059
90041=\u30c8\u30ea\u30ac {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90042=\u30c8\u30ea\u30ac {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90043=\u30c8\u30ea\u30ac {0} \u30aa\u30d6\u30b8\u30a7\u30af\u30c8, \u30af\u30e9\u30b9 {1} \u3092\u751f\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
90044=\u30c8\u30ea\u30ac {0} \u30aa\u30d6\u30b8\u30a7\u30af\u30c8, \u30af\u30e9\u30b9 {1} \u3092\u5b9f\u884c\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
90045=\u5236\u7d04 {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90046=URL\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30a8\u30e9\u30fc; {1} \u3067\u306f\u306a\u304f {0} \u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
90047=\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\u30c9\u30e9\u30a4\u30d0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f {0} \u3067\u3059\u304c\u3001\u30b5\u30fc\u30d0\u30d0\u30fc\u30b8\u30e7\u30f3\u306f {1} \u3067\u3059
90048=\u30d5\u30a1\u30a4\u30eb {0} \u306f\u3001\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u304b\u3001\u4e0d\u6b63\u306a\u30d5\u30a1\u30a4\u30eb\u30d8\u30c3\u30c0\u3092\u6301\u3064\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3067\u3059
90049=\u30d5\u30a1\u30a4\u30eb {0} \u306e\u6697\u53f7\u5316\u30a8\u30e9\u30fc\u3067\u3059
90050=\u4e0d\u6b63\u306a\u30d1\u30b9\u30ef\u30fc\u30c9\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3067\u3059\u3002\u6b63\u3057\u304f\u306f\: \u30d5\u30a1\u30a4\u30eb\u30d1\u30b9\u30ef\u30fc\u30c9 <\u7a7a\u767d> \u30e6\u30fc\u30b6\u30d1\u30b9\u30ef\u30fc\u30c9
90051=\u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
90052=\u30b5\u30d6\u30af\u30a8\u30ea\u304c\u5358\u4e00\u5217\u306e\u30af\u30a8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093
90053=\u6570\u5024\u30b5\u30d6\u30af\u30a8\u30ea\u304c\u8907\u6570\u306e\u884c\u3092\u542b\u3093\u3067\u3044\u307e\u3059
90054=\u96c6\u5408\u95a2\u6570 {0} \u306e\u4e0d\u6b63\u306a\u4f7f\u7528
90055={0} \u306f\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u6697\u53f7\u3067\u3059
90056=\u5217 {0} \u306b\u30c7\u30d5\u30a9\u30eb\u30c8\u5024\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
90057=\u5236\u7d04 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90058=\u30c6\u30fc\u30d6\u30eb\u304b\u3001\u30c6\u30fc\u30d6\u30eb\u306e\u5225\u540d {0} \u304c\u91cd\u8907\u3057\u3066\u3044\u307e\u3059
90059=\u5217\u540d {0} \u304c\u3042\u3044\u307e\u3044\u3067\u3059
90060={0} \u306f\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u30d5\u30a1\u30a4\u30eb\u30ed\u30c3\u30af\u65b9\u5f0f\u3067\u3059
90061=\u30dd\u30fc\u30c8 {0} \u3092\u30aa\u30fc\u30d7\u30f3\u4e2d\u306b\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f (\u30dd\u30fc\u30c8\u304c\u4f7f\u7528\u4e2d\u306e\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059)
90062=\u30d5\u30a1\u30a4\u30eb {0} \u3092\u4f5c\u6210\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
90063=\u30bb\u30fc\u30d6\u30dd\u30a4\u30f3\u30c8\u304c\u4e0d\u6b63\u3067\u3059\: {0}
90064=\u30bb\u30fc\u30d6\u30dd\u30a4\u30f3\u30c8\u306e\u540d\u524d\u3092\u524a\u9664\u3057\u307e\u3057\u305f
90065=\u30bb\u30fc\u30d6\u30dd\u30a4\u30f3\u30c8\u306b\u540d\u524d\u3092\u8a2d\u5b9a\u3057\u307e\u3057\u305f
90066=\u30d7\u30ed\u30d1\u30c6\u30a3 {0} \u304c\u91cd\u8907\u3057\u3066\u3044\u307e\u3059
90067=\u63a5\u7d9a\u304c\u58ca\u308c\u3066\u3044\u307e\u3059
90068=order by \u5bfe\u8c61\u306e\u5f0f {0} \u306f\u3001\u7d50\u679c\u30ea\u30b9\u30c8\u306b\u542b\u307e\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
90069=\u30ed\u30fc\u30eb {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90070=\u30ed\u30fc\u30eb {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90071=\u30e6\u30fc\u30b6\u3001\u307e\u305f\u306f\u30ed\u30fc\u30eb {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90072=\u30ed\u30fc\u30eb\u3068\u6a29\u9650\u306f\u6df7\u5728\u3067\u304d\u307e\u305b\u3093
90073=\u6a29\u9650\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90074=\u30ed\u30fc\u30eb {0} \u306f\u3059\u3067\u306b\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u3059
90075=\u5217\u306f\u30a4\u30f3\u30c7\u30c3\u30af\u30b9 {0} \u306e\u4e00\u90e8\u3067\u3059
90076=\u95a2\u6570\u306e\u5225\u540d {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90077=\u95a2\u6570\u306e\u5225\u540d {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90078=\u30b9\u30ad\u30fc\u30de {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90079=\u30b9\u30ad\u30fc\u30de {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90080=\u30b9\u30ad\u30fc\u30de\u540d\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093
90081=\u5217 {0} \u304cnull\u5024\u3092\u542b\u3093\u3067\u3044\u307e\u3059
90082=\u30b7\u30fc\u30b1\u30f3\u30b9 {0} \u306f\u30c6\u30fc\u30d6\u30eb\u306b\u5c5e\u3057\u307e\u3059
90083=\u5217\u306f {0} \u306b\u53c2\u7167\u3055\u308c\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059
90084=\u6700\u5f8c\u306e\u5217 {0} \u3092drop\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
90085=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9 {0} \u306f\u5236\u7d04\u306b\u5c5e\u3057\u3066\u3044\u307e\u3059
90086=\u30af\u30e9\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90087=\u30e1\u30bd\u30c3\u30c9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90088={0} \u306f\u4e0d\u660e\u306a\u30e2\u30fc\u30c9\u3067\u3059
90089=\u30c7\u30fc\u30bf\u30c6\u30fc\u30d6\u30eb {0} \u304c\u3042\u308b\u305f\u3081\u3001\u7167\u5408\u9806\u5e8f\u306e\u5909\u66f4\u306f\u3067\u304d\u307e\u305b\u3093
90090=\u30b9\u30ad\u30fc\u30de {0} \u306fdrop\u3067\u304d\u307e\u305b\u3093
90091=\u30ed\u30fc\u30eb {0} \u306fdrop\u3067\u304d\u307e\u305b\u3093
90092=\u3053\u306eJava\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093 (Java 1.4\u304c\u5fc5\u8981\u3067\u3059)
90093=\u30af\u30e9\u30b9\u30bf\u30ea\u30f3\u30b0\u30a8\u30e9\u30fc - \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30b9\u30bf\u30f3\u30c9\u30a2\u30ed\u30f3\u30e2\u30fc\u30c9\u3067\u52d5\u4f5c\u3057\u3066\u3044\u307e\u3059
90094=\u30af\u30e9\u30b9\u30bf\u30ea\u30f3\u30b0\u30a8\u30e9\u30fc - \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u30af\u30e9\u30b9\u30bf\u30fc\u30e2\u30fc\u30c9\u3067\u52d5\u4f5c\u3057\u3066\u3044\u307e\u3059, \u30b5\u30fc\u30d0\u30ea\u30b9\u30c8\: {0}
90095=\u6587\u5b57\u5217\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u30a8\u30e9\u30fc\: {0}
90096=\u30aa\u30d6\u30b8\u30a7\u30af\u30c8 {0} \u306b\u5bfe\u3059\u308b\u5341\u5206\u306a\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093
90097=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u8aad\u307f\u8fbc\u307f\u5c02\u7528\u3067\u3059
90098=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u3059\u3067\u306b\u9589\u3058\u3089\u308c\u3066\u3044\u307e\u3059
90099=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u306e\u8a2d\u5b9a\u30a8\u30e9\u30fc {0}
90100=\u30c7\u30a3\u30b9\u30af\u306e\u7a7a\u304d\u9818\u57df\u304c\u3042\u308a\u307e\u305b\u3093
90101=\u4e0d\u6b63\u306aXID\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\: {0}
90102=\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u5727\u7e2e\u30aa\u30d7\u30b7\u30e7\u30f3\: {0}
90103=\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u5727\u7e2e\u30a2\u30eb\u30b4\u30ea\u30ba\u30e0\: {0}
90104=\u5727\u7e2e\u30a8\u30e9\u30fc
90105=\u30e6\u30fc\u30b6\u5b9a\u7fa9\u95a2\u6570\u3092\u5b9f\u884c\u4e2d\u306b\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f
90106={0} \u3092truncate\u3067\u304d\u307e\u305b\u3093
90107={1} \u304c\u4f9d\u5b58\u3057\u3066\u3044\u308b\u305f\u3081\u3001{0} \u3092drop\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
90108=\u30b9\u30bf\u30c3\u30af\u30aa\u30fc\u30d0\u30fc\u30d5\u30ed\u30fc (\u518d\u5e30\u7684\u306a\u30af\u30a8\u30ea\u3001\u95a2\u6570\u306e\u53ef\u80fd\u6027)
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
90112=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9 {0} \u304b\u3089\u524a\u9664\u3092\u8a66\u307f\u307e\u3057\u305f\u304c\u3001\u884c\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90113=\u672a\u30b5\u30dd\u30fc\u30c8\u306e\u63a5\u7d9a\u8a2d\u5b9a {0}
90114=\u5b9a\u6570 {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90115=\u5b9a\u6570 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90116=\u3053\u306e\u7a2e\u985e\u306e\u30ea\u30c6\u30e9\u30eb\u306f\u8a31\u3055\u308c\u3066\u3044\u307e\u305b\u3093
90117=\u3053\u306e\u30b5\u30fc\u30d0\u3078\u306e\u30ea\u30e2\u30fc\u30c8\u63a5\u7d9a\u306f\u8a31\u3055\u308c\u3066\u3044\u307e\u305b\u3093, -tcpAllowOthers\u3092\u53c2\u7167
90118=\u30c6\u30fc\u30d6\u30eb {0} \u306fdrop\u3067\u304d\u307e\u305b\u3093
90119=\u30e6\u30fc\u30b6\u30c7\u30fc\u30bf\u578b {0} \u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059
90120=\u30e6\u30fc\u30b6\u30c7\u30fc\u30bf\u578b {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
90121=VM\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u6642\u306b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u547c\u3073\u51fa\u3055\u308c\u307e\u3057\u305f; \u81ea\u52d5\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30af\u30ed\u30fc\u30ba\u3092\u7121\u52b9\u306b\u3059\u308b\u305f\u3081\u306b\u3001db URL\u306b ";DB_CLOSE_ON_EXIT\=FALSE" \u3092\u8ffd\u52a0\u3057\u3066\u304f\u3060\u3055\u3044
90122=\u30d3\u30e5\u30fc\u304c\u5b58\u5728\u3059\u308b\u30c6\u30fc\u30d6\u30eb {0} \u306b\u5bfe\u3059\u308b\u64cd\u4f5c\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\: {1}
90123=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u306e\u4ed8\u3044\u305f\u30d1\u30e9\u30e1\u30fc\u30bf\u3068\u4ed8\u3044\u3066\u3044\u306a\u3044\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u6df7\u5728\u3055\u305b\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
90124=\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\: {0}
90125=\u7121\u52b9\u306a\u30af\u30e9\u30b9, {0} \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u308b\u306b\u3082\u304b\u304b\u308f\u3089\u305a {1} \u3092\u53d6\u5f97\u3057\u307e\u3057\u305f
90126=\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u6c38\u7d9a\u7684\u3067\u306f\u3042\u308a\u307e\u305b\u3093
90127=\u30ea\u30b6\u30eb\u30c8\u30bb\u30c3\u30c8\u304c\u66f4\u65b0\u53ef\u80fd\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u30af\u30a8\u30ea\u306f\u5358\u4e00\u306e\u30c6\u30fc\u30d6\u30eb\u304b\u3089\u3001\u30e6\u30cb\u30fc\u30af\u30ad\u30fc\u3092\u5168\u3066select\u3057\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
90128=\u30ea\u30b6\u30eb\u30c8\u30bb\u30c3\u30c8\u304c\u30b9\u30af\u30ed\u30fc\u30eb\u3001\u30ea\u30bb\u30c3\u30c8\u53ef\u80fd\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) \u3092\u4f7f\u3046\u5fc5\u8981\u304c\u3042\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002
90129=#Transaction {0} not found
90130=#This method is not allowed for a prepared statement; use a regular statement instead.
90131=#Concurrent update in table {0}\: another transaction has updated or deleted the same row
HY000=\u4e00\u822c\u30a8\u30e9\u30fc\: {0}
HY004=\u4e0d\u660e\u306a\u30c7\u30fc\u30bf\u578b\: {0}
HYC00=\u6a5f\u80fd\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093
HYT00=\u30c6\u30fc\u30d6\u30eb {0} \u306e\u30ed\u30c3\u30af\u8a66\u884c\u304c\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3057\u307e\u3057\u305f
\ No newline at end of file
...@@ -151,6 +151,7 @@ ...@@ -151,6 +151,7 @@
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). 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 90129=\#Transaction {0} not found
90130=\#This method is not allowed for a prepared statement; use a regular statement instead. 90130=\#This method is not allowed for a prepared statement; use a regular statement instead.
90131=\#Concurrent update in table {0}\: another transaction has updated or deleted the same row
HY000=Blad ogolny\: {0} HY000=Blad ogolny\: {0}
HY004=Nieznany typ danyche\: {0} HY004=Nieznany typ danyche\: {0}
HYC00=Cecha nie jest wspierana HYC00=Cecha nie jest wspierana
......
...@@ -248,6 +248,7 @@ ALTER TABLE TEST DROP CONSTRAINT UNIQUE_NAME ...@@ -248,6 +248,7 @@ ALTER TABLE TEST DROP CONSTRAINT UNIQUE_NAME
ALTER TABLE tableName SET REFERENTIAL_INTEGRITY {FALSE | TRUE [CHECK|NOCHECK]} ALTER TABLE tableName SET REFERENTIAL_INTEGRITY {FALSE | TRUE [CHECK|NOCHECK]}
"," ","
Disables or enables referential integrity checking for a table. Disables or enables referential integrity checking for a table.
This command can be used inside a transaction.
Enabling it does not check existing data, except if CHECK is specified. Enabling it does not check existing data, except if CHECK is specified.
Use SET REFERENTIAL_INTEGRITY to disable it for all tables (the global flag and the flag for each table are independent). Use SET REFERENTIAL_INTEGRITY to disable it for all tables (the global flag and the flag for each table are independent).
"," ","
......
...@@ -66,22 +66,22 @@ public class Row extends Record implements SearchRow { ...@@ -66,22 +66,22 @@ public class Row extends Record implements SearchRow {
return blockCount * (DiskFile.BLOCK_SIZE / 16) + memory * 4; return blockCount * (DiskFile.BLOCK_SIZE / 16) + memory * 4;
} }
public String toString() { // public String toString() {
int testing; // int testing;
StringBuffer buff = new StringBuffer(data.length*5); // StringBuffer buff = new StringBuffer(data.length*5);
buff.append('('); // buff.append('(');
for(int i=0; i<data.length; i++) { // for(int i=0; i<data.length; i++) {
if(i>0) { // if(i>0) {
buff.append(", "); // buff.append(", ");
} // }
buff.append(data[i].getSQL()); // buff.append(data[i].getSQL());
} // }
buff.append(')'); // buff.append(')');
buff.append(" /* pos: " + getPos() + "*/ "); // buff.append(" /* pos: " + getPos() + "*/ ");
if(getDeleted()) { // if(getDeleted()) {
buff.append(" /* deleted /*"); // buff.append(" /* deleted /*");
} // }
return buff.toString(); // return buff.toString();
} // }
} }
...@@ -66,7 +66,9 @@ public class LogFile { ...@@ -66,7 +66,9 @@ public class LogFile {
unwritten = new ObjectArray(); unwritten = new ObjectArray();
try { try {
readHeader(); readHeader();
if(!log.getDatabase().getReadOnly()) {
writeHeader(); writeHeader();
}
pos = getBlock(); pos = getBlock();
firstUncommittedPos = pos; firstUncommittedPos = pos;
} catch(SQLException e) { } catch(SQLException e) {
...@@ -173,7 +175,7 @@ public class LogFile { ...@@ -173,7 +175,7 @@ public class LogFile {
return s; return s;
} }
private boolean redoOrUndo(boolean undo) throws SQLException { private boolean redoOrUndo(boolean undo, boolean readOnly) throws SQLException {
int pos = getBlock(); int pos = getBlock();
DataPage in = readPage(); DataPage in = readPage();
int blocks = in.readInt(); int blocks = in.readInt();
...@@ -209,6 +211,9 @@ public class LogFile { ...@@ -209,6 +211,9 @@ public class LogFile {
throw Message.getInternalError("can't undo summary"); throw Message.getInternalError("can't undo summary");
} }
} }
if(readOnly && type != 'S') {
return true;
}
if(undo) { if(undo) {
if(logSystem.isSessionCommitted(sessionId, id, pos)) { if(logSystem.isSessionCommitted(sessionId, id, pos)) {
logSystem.removeSession(sessionId); logSystem.removeSession(sessionId);
...@@ -216,9 +221,11 @@ public class LogFile { ...@@ -216,9 +221,11 @@ public class LogFile {
} }
} else { } else {
if(type != 'S') { if(type != 'S') {
if(!readOnly) {
logSystem.addUndoLogRecord(this, pos, sessionId); logSystem.addUndoLogRecord(this, pos, sessionId);
} }
} }
}
int storageId = in.readInt(); int storageId = in.readInt();
Storage storage = logSystem.getStorageForRecovery(storageId); Storage storage = logSystem.getStorageForRecovery(storageId);
DataPage rec = null; DataPage rec = null;
...@@ -286,6 +293,7 @@ public class LogFile { ...@@ -286,6 +293,7 @@ public class LogFile {
} }
public void redoAllGoEnd() throws SQLException { public void redoAllGoEnd() throws SQLException {
boolean readOnly = logSystem.getDatabase().getReadOnly();
long length = file.length(); long length = file.length();
if(length<=FileStore.HEADER_LENGTH) { if(length<=FileStore.HEADER_LENGTH) {
return; return;
...@@ -298,7 +306,7 @@ public class LogFile { ...@@ -298,7 +306,7 @@ public class LogFile {
if((long)pos * BLOCK_SIZE >= length) { if((long)pos * BLOCK_SIZE >= length) {
break; break;
} }
boolean more = redoOrUndo(false); boolean more = redoOrUndo(false, readOnly);
if(!more) { if(!more) {
break; break;
} }
...@@ -326,7 +334,7 @@ public class LogFile { ...@@ -326,7 +334,7 @@ public class LogFile {
void undo(int pos) throws SQLException { void undo(int pos) throws SQLException {
go(pos); go(pos);
redoOrUndo(true); redoOrUndo(true, false);
} }
void flush() throws SQLException { void flush() throws SQLException {
......
...@@ -47,7 +47,7 @@ public class LogSystem { ...@@ -47,7 +47,7 @@ public class LogSystem {
this.database = database; this.database = database;
this.readOnly = readOnly; this.readOnly = readOnly;
this.accessMode = accessMode; this.accessMode = accessMode;
if (database == null || readOnly) { if (database == null) {
return; return;
} }
this.fileNamePrefix = fileNamePrefix; this.fileNamePrefix = fileNamePrefix;
...@@ -107,21 +107,31 @@ public class LogSystem { ...@@ -107,21 +107,31 @@ public class LogSystem {
for (int i = 0; i < activeLogs.size(); i++) { for (int i = 0; i < activeLogs.size(); i++) {
LogFile l = (LogFile) activeLogs.get(i); LogFile l = (LogFile) activeLogs.get(i);
if (l.getFirstUncommittedPos() == LOG_WRITTEN) { if (l.getFirstUncommittedPos() == LOG_WRITTEN) {
closeOldFile(l); // must remove the log file first
// if we don't do that, the file is closed but still in the list
activeLogs.remove(i); activeLogs.remove(i);
i--; i--;
closeOldFile(l);
} }
} }
} }
public void close() throws SQLException { public void close() throws SQLException {
if(database == null || readOnly) { if(database == null) {
return; return;
} }
synchronized (database) { synchronized (database) {
if(closed) { if(closed) {
return; return;
} }
if(readOnly) {
for (int i = 0; i < activeLogs.size(); i++) {
LogFile l = (LogFile) activeLogs.get(i);
l.close(false);
}
closed = true;
return;
}
// TODO refactor flushing and closing files when we know what to do exactly // TODO refactor flushing and closing files when we know what to do exactly
SQLException closeException = null; SQLException closeException = null;
try { try {
...@@ -202,7 +212,7 @@ public class LogSystem { ...@@ -202,7 +212,7 @@ public class LogSystem {
boolean fileChanged = undo.size() > 0; boolean fileChanged = undo.size() > 0;
undo = null; undo = null;
storages.clear(); storages.clear();
if (fileChanged && !containsInDoubtTransactions()) { if (!readOnly && fileChanged && !containsInDoubtTransactions()) {
checkpoint(); checkpoint();
} }
return fileChanged; return fileChanged;
......
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
package org.h2.store; package org.h2.store;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.util.CacheObject; import org.h2.util.CacheObject;
/** /**
...@@ -37,13 +34,15 @@ public abstract class Record extends CacheObject { ...@@ -37,13 +34,15 @@ public abstract class Record extends CacheObject {
return false; return false;
} }
public void setDeleted(Session session, boolean deleted) { public void setDeleted(boolean deleted) {
this.sessionId = session.getId();
this.deleted = deleted; this.deleted = deleted;
} }
public void setSessionId(int sessionId) {
this.sessionId = sessionId;
}
public int getSessionId() { public int getSessionId() {
int testing;
return sessionId; return sessionId;
} }
......
...@@ -110,7 +110,7 @@ public class Storage { ...@@ -110,7 +110,7 @@ public class Storage {
} }
public void updateRecord(Session session, Record record) throws SQLException { public void updateRecord(Session session, Record record) throws SQLException {
record.setDeleted(session, false); record.setDeleted(false);
file.updateRecord(session, record); file.updateRecord(session, record);
} }
...@@ -118,7 +118,7 @@ public class Storage { ...@@ -118,7 +118,7 @@ public class Storage {
record.setStorageId(id); record.setStorageId(id);
int size = file.getRecordOverhead() + record.getByteCount(dummy); int size = file.getRecordOverhead() + record.getByteCount(dummy);
size = MathUtils.roundUp(size, DiskFile.BLOCK_SIZE); size = MathUtils.roundUp(size, DiskFile.BLOCK_SIZE);
record.setDeleted(session, false); record.setDeleted(false);
int blockCount = size / DiskFile.BLOCK_SIZE; int blockCount = size / DiskFile.BLOCK_SIZE;
if(pos == ALLOCATE_POS) { if(pos == ALLOCATE_POS) {
pos = allocate(blockCount); pos = allocate(blockCount);
...@@ -137,7 +137,7 @@ public class Storage { ...@@ -137,7 +137,7 @@ public class Storage {
if(SysProperties.CHECK && record.getDeleted()) { if(SysProperties.CHECK && record.getDeleted()) {
throw Message.getInternalError("duplicate delete " + pos); throw Message.getInternalError("duplicate delete " + pos);
} }
record.setDeleted(session, true); record.setDeleted(true);
int blockCount = record.getBlockCount(); int blockCount = record.getBlockCount();
if(database.isMultiVersion()) { if(database.isMultiVersion()) {
int todoMustFreeSpaceOnCommit; int todoMustFreeSpaceOnCommit;
......
...@@ -78,6 +78,9 @@ public class TableData extends Table implements RecordReader { ...@@ -78,6 +78,9 @@ public class TableData extends Table implements RecordReader {
public void addRow(Session session, Row row) throws SQLException { public void addRow(Session session, Row row) throws SQLException {
int i = 0; int i = 0;
lastModificationId = database.getNextModificationDataId(); lastModificationId = database.getNextModificationDataId();
if(database.isMultiVersion()) {
row.setSessionId(session.getId());
}
try { try {
for (; i < indexes.size(); i++) { for (; i < indexes.size(); i++) {
Index index = (Index) indexes.get(i); Index index = (Index) indexes.get(i);
...@@ -261,8 +264,14 @@ public class TableData extends Table implements RecordReader { ...@@ -261,8 +264,14 @@ public class TableData extends Table implements RecordReader {
lastModificationId = database.getNextModificationDataId(); lastModificationId = database.getNextModificationDataId();
if(database.isMultiVersion()) { if(database.isMultiVersion()) {
if(row.getDeleted()) { if(row.getDeleted()) {
int testingWrongExceptionConcurrentUpdateOrSo; throw Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
throw Message.getSQLException(ErrorCode.LOCK_TIMEOUT_1); }
int old = row.getSessionId();
int newId = session.getId();
if(old == 0) {
row.setSessionId(newId);
} else if(old != newId) {
throw Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
} }
} }
for (int i = indexes.size() - 1; i >= 0; i--) { for (int i = indexes.size() - 1; i >= 0; i--) {
......
...@@ -55,14 +55,15 @@ public class TableFilter implements ColumnResolver { ...@@ -55,14 +55,15 @@ public class TableFilter implements ColumnResolver {
private boolean outerJoin; private boolean outerJoin;
private boolean foundOne; private boolean foundOne;
private Expression fullCondition; private Expression fullCondition;
private final boolean rightsChecked;
public TableFilter(Session session, Table table, String alias, boolean rightsChecked, Select select) { public TableFilter(Session session, Table table, String alias, boolean rightsChecked, Select select) throws SQLException {
this.session = session; this.session = session;
this.table = table; this.table = table;
this.alias = alias; this.alias = alias;
this.rightsChecked = rightsChecked;
this.select = select; this.select = select;
if(!rightsChecked) {
session.getUser().checkRight(table, Right.SELECT);
}
} }
public Select getSelect() { public Select getSelect() {
...@@ -74,9 +75,6 @@ public class TableFilter implements ColumnResolver { ...@@ -74,9 +75,6 @@ public class TableFilter implements ColumnResolver {
} }
public void lock(Session session, boolean exclusive, boolean force) throws SQLException { public void lock(Session session, boolean exclusive, boolean force) throws SQLException {
if(!rightsChecked) {
session.getUser().checkRight(table, Right.SELECT);
}
table.lock(session, exclusive, force); table.lock(session, exclusive, force);
for(int i=0; joins != null && i<joins.size(); i++) { for(int i=0; joins != null && i<joins.size(); i++) {
getTableFilter(i).lock(session, exclusive, force); getTableFilter(i).lock(session, exclusive, force);
......
...@@ -10,6 +10,7 @@ import org.h2.command.dml.Query; ...@@ -10,6 +10,7 @@ import org.h2.command.dml.Query;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.User;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
...@@ -35,6 +36,7 @@ public class TableView extends Table { ...@@ -35,6 +36,7 @@ public class TableView extends Table {
private SmallLRUCache indexCache = new SmallLRUCache(Constants.VIEW_INDEX_CACHE_SIZE); private SmallLRUCache indexCache = new SmallLRUCache(Constants.VIEW_INDEX_CACHE_SIZE);
private long lastModificationCheck; private long lastModificationCheck;
private long maxDataModificationId; private long maxDataModificationId;
private User owner;
public TableView(Schema schema, int id, String name, String querySQL, ObjectArray params, String[] columnNames, Session session, boolean recursive) throws SQLException { public TableView(Schema schema, int id, String name, String querySQL, ObjectArray params, String[] columnNames, Session session, boolean recursive) throws SQLException {
super(schema, id, name, false); super(schema, id, name, false);
...@@ -275,4 +277,12 @@ public class TableView extends Table { ...@@ -275,4 +277,12 @@ public class TableView extends Table {
} }
} }
public void setOwner(User owner) {
this.owner = owner;
}
public User getOwner() {
return owner;
}
} }
...@@ -38,7 +38,7 @@ public class Backup { ...@@ -38,7 +38,7 @@ public class Backup {
* <li>-help or -? (print the list of options) * <li>-help or -? (print the list of options)
* </li><li>-file filename (the default is backup.zip) * </li><li>-file filename (the default is backup.zip)
* </li><li>-dir database directory (the default is the current directory) * </li><li>-dir database directory (the default is the current directory)
* </li><li>-db database name (all databases if no name is specified) * </li><li>-db database name (not required if there is only one database)
* </li><li>-quiet does not print progress information * </li><li>-quiet does not print progress information
* </li></ul> * </li></ul>
* *
...@@ -76,7 +76,7 @@ public class Backup { ...@@ -76,7 +76,7 @@ public class Backup {
* *
* @param zipFileName the name of the backup file * @param zipFileName the name of the backup file
* @param directory the directory name * @param directory the directory name
* @param db the database name (null for all databases) * @param db the database name (null if there is only one database)
* @param quiet don't print progress information * @param quiet don't print progress information
* @throws SQLException * @throws SQLException
*/ */
...@@ -101,7 +101,6 @@ public class Backup { ...@@ -101,7 +101,6 @@ public class Backup {
String fileName = (String) list.get(i); String fileName = (String) list.get(i);
if(fileName.endsWith(Constants.SUFFIX_DATA_FILE)) { if(fileName.endsWith(Constants.SUFFIX_DATA_FILE)) {
base = FileUtils.getParent(fileName); base = FileUtils.getParent(fileName);
base = FileUtils.getAbsolutePath(fileName);
} }
} }
for(int i=0; i<list.size(); i++) { for(int i=0; i<list.size(); i++) {
......
...@@ -130,6 +130,9 @@ public class Restore { ...@@ -130,6 +130,9 @@ public class Restore {
if(originalDbName == null) { if(originalDbName == null) {
throw new IOException("No database named " + db + " found"); throw new IOException("No database named " + db + " found");
} }
if(originalDbName.startsWith(File.separator)) {
originalDbName = originalDbName.substring(1);
}
} }
in = FileUtils.openFileInputStream(zipFileName); in = FileUtils.openFileInputStream(zipFileName);
ZipInputStream zipIn = new ZipInputStream(in); ZipInputStream zipIn = new ZipInputStream(in);
......
...@@ -244,9 +244,6 @@ public class FileUtils { ...@@ -244,9 +244,6 @@ public class FileUtils {
if(file.exists()) { if(file.exists()) {
for(int i=0; i<SysProperties.MAX_FILE_RETRY; i++) { for(int i=0; i<SysProperties.MAX_FILE_RETRY; i++) {
trace("delete", fileName, null); trace("delete", fileName, null);
if(fileName.indexOf("1459.146") >= 0) {
new Error(fileName).printStackTrace();
}
boolean ok = file.delete(); boolean ok = file.delete();
if(ok) { if(ok) {
return; return;
......
...@@ -100,11 +100,27 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -100,11 +100,27 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/* /*
only admins can use nested tables: CREATE TABLE TEST(BIRTH TIMESTAMP);
CREATE USER TEST PASSWORD 'TEST'; INSERT INTO TEST VALUES('2006-04-03 10:20:30'), ('2006-04-03 10:20:31');
SELECT * FROM (SELECT * FROM DUAL); SELECT CAST(BIRTH AS DATE) B
FROM TEST GROUP BY CAST(BIRTH AS DATE)
HAVING CAST(BIRTH AS DATE) = '2004-05-05';
SELECT 1 FROM (SELECT CAST(BIRTH AS DATE) B
FROM TEST GROUP BY CAST(BIRTH AS DATE)) A
WHERE A.B = '2004-05-05';
DROP TABLE TEST;
CREATE TABLE TEST (ID integer NOT NULL PRIMARY KEY);
@LOOP 1000 INSERT INTO TEST VALUES(?);
CREATE VIEW TESTVIEW AS SELECT src.ID as VID FROM TEST AS h
INNER JOIN TEST AS src ON h.ID = src.ID GROUP BY src.ID;
-- slow
SELECT COUNT(*) FROM TESTVIEW AS S LEFT JOIN TESTVIEW AS T ON S.VID = T.VID;
DROP VIEW TESTVIEW;
DROP TABLE TEST;
m2-repo add to maven
http://maven.apache.org/guides/mini/guide-central-repository-upload.html
add MVCC add MVCC
...@@ -114,8 +130,6 @@ test and document fulltext search ...@@ -114,8 +130,6 @@ test and document fulltext search
clustered tables: test, document clustered tables: test, document
add to maven
Switching off and switching on constraints could be made transactional. Switching off and switching on constraints could be made transactional.
Add version number. Install directory: h2-1.0, jar file: h2-1.0.jar Add version number. Install directory: h2-1.0, jar file: h2-1.0.jar
......
...@@ -26,20 +26,32 @@ public class TestRights extends TestBase { ...@@ -26,20 +26,32 @@ public class TestRights extends TestBase {
// rights on tables and views // rights on tables and views
executeSuccess("CREATE USER PASS_READER PASSWORD 'abc'"); executeSuccess("CREATE USER PASS_READER PASSWORD 'abc'");
executeSuccess("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
executeSuccess("CREATE TABLE PASS(ID INT PRIMARY KEY, NAME VARCHAR, PASSWORD VARCHAR)"); executeSuccess("CREATE TABLE PASS(ID INT PRIMARY KEY, NAME VARCHAR, PASSWORD VARCHAR)");
executeSuccess("CREATE VIEW PASS_NAME AS SELECT ID, NAME FROM PASS"); executeSuccess("CREATE VIEW PASS_NAME AS SELECT ID, NAME FROM PASS");
executeSuccess("GRANT SELECT ON PASS_NAME TO PASS_READER"); executeSuccess("GRANT SELECT ON PASS_NAME TO PASS_READER");
executeSuccess("GRANT SELECT, INSERT, UPDATE ON TEST TO PASS_READER");
conn.close(); conn.close();
conn = getConnection("rights", "PASS_READER", "abc"); conn = getConnection("rights", "PASS_READER", "abc");
stat = conn.createStatement(); stat = conn.createStatement();
executeSuccess("SELECT * FROM PASS_NAME"); executeSuccess("SELECT * FROM PASS_NAME");
executeSuccess("SELECT * FROM (SELECT * FROM PASS_NAME)");
executeSuccess("SELECT (SELECT NAME FROM PASS_NAME) P FROM PASS_NAME");
executeError("SELECT (SELECT PASSWORD FROM PASS) P FROM PASS_NAME");
executeError("SELECT * FROM PASS"); executeError("SELECT * FROM PASS");
executeError("INSERT INTO TEST SELECT 1, PASSWORD FROM PASS");
executeError("INSERT INTO TEST VALUES(SELECT PASSWORD FROM PASS)");
executeError("UPDATE TEST SET NAME=(SELECT PASSWORD FROM PASS)");
executeError("DELETE FROM TEST WHERE NAME=(SELECT PASSWORD FROM PASS)");
executeError("SELECT * FROM (SELECT * FROM PASS)");
executeError("CREATE VIEW X AS SELECT * FROM PASS_READER");
conn.close(); conn.close();
conn = getConnection("rights"); conn = getConnection("rights");
stat = conn.createStatement(); stat = conn.createStatement();
executeSuccess("DROP TABLE TEST");
executeSuccess("CREATE USER TEST PASSWORD 'abc'"); executeSuccess("CREATE USER TEST PASSWORD 'abc'");
executeSuccess("ALTER USER TEST ADMIN TRUE"); executeSuccess("ALTER USER TEST ADMIN TRUE");
executeSuccess("CREATE TABLE TEST(ID INT)"); executeSuccess("CREATE TABLE TEST(ID INT)");
...@@ -103,6 +115,7 @@ public class TestRights extends TestBase { ...@@ -103,6 +115,7 @@ public class TestRights extends TestBase {
executeError("DELETE FROM ROLE_TABLE"); executeError("DELETE FROM ROLE_TABLE");
executeError("SELECT * FROM HIDDEN"); executeError("SELECT * FROM HIDDEN");
executeError("UPDATE TEST SET ID=0"); executeError("UPDATE TEST SET ID=0");
executeError("CALL SELECT MIN(PASSWORD) FROM PASS");
executeSuccess("SELECT * FROM SUB_TABLE"); executeSuccess("SELECT * FROM SUB_TABLE");
executeSuccess("INSERT INTO SUB_TABLE VALUES(1)"); executeSuccess("INSERT INTO SUB_TABLE VALUES(1)");
executeError("DELETE FROM SUB_TABLE"); executeError("DELETE FROM SUB_TABLE");
......
...@@ -19,9 +19,8 @@ public class TestMVCC { ...@@ -19,9 +19,8 @@ public class TestMVCC {
} }
void test() throws Exception { void test() throws Exception {
// TODO Prio 1: exception when deleting / updating the same in two transactions
// TODO Prio 1: document: exclusive table lock still used when altering tables, adding indexes, select ... for update; table level locks are checked
// TODO Prio 1: make unit test work // TODO Prio 1: make unit test work
// TODO Prio 1: document: exclusive table lock still used when altering tables, adding indexes, select ... for update; table level locks are checked
// TODO Prio 1: free up disk space (for deleted rows and old versions of updated rows) on commit // TODO Prio 1: free up disk space (for deleted rows and old versions of updated rows) on commit
// TODO Prio 1: ScanIndex: never remove uncommitted data from cache (lost sessionId) // TODO Prio 1: ScanIndex: never remove uncommitted data from cache (lost sessionId)
// TODO Prio 1: Test with Hibernate // TODO Prio 1: Test with Hibernate
...@@ -44,19 +43,34 @@ public class TestMVCC { ...@@ -44,19 +43,34 @@ public class TestMVCC {
c1.setAutoCommit(false); c1.setAutoCommit(false);
c2.setAutoCommit(false); c2.setAutoCommit(false);
s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
s1.execute("INSERT INTO TEST VALUES(1, 'Test')");
c1.commit();
test(s1, "select max(id) from test", "1");
s1.execute("INSERT INTO TEST VALUES(2, 'World')");
c1.rollback();
test(s1, "select max(id) from test", "1");
c1.commit();
c2.commit();
s1.execute("DROP TABLE TEST");
s1.execute("create table test as select * from table(id int=(1, 2))");
s1.execute("update test set id=1 where id=1");
s1.execute("select max(id) from test");
test(s1, "select max(id) from test", "2");
c1.commit();
c2.commit();
s1.execute("DROP TABLE TEST");
s1.execute("CREATE TABLE TEST(ID INT)"); s1.execute("CREATE TABLE TEST(ID INT)");
s1.execute("INSERT INTO TEST VALUES(1)"); s1.execute("INSERT INTO TEST VALUES(1)");
c1.commit(); c1.commit();
// test(s2, "SELECT COUNT(*) FROM TEST", "1");
System.out.println(s1.executeUpdate("DELETE FROM TEST"));
ResultSet rs = s2.executeQuery("SELECT * FROM TEST");
while(rs.next()) {
System.out.println(" " + rs.getString(1));
}
//
test(s2, "SELECT COUNT(*) FROM TEST", "1"); test(s2, "SELECT COUNT(*) FROM TEST", "1");
System.out.println(s2.executeUpdate("DELETE FROM TEST")); s1.executeUpdate("DELETE FROM TEST");
test(s2, "SELECT COUNT(*) FROM TEST", "1");
test(s1, "SELECT COUNT(*) FROM TEST", "0"); test(s1, "SELECT COUNT(*) FROM TEST", "0");
c1.commit();
test(s2, "SELECT COUNT(*) FROM TEST", "0"); test(s2, "SELECT COUNT(*) FROM TEST", "0");
c1.commit(); c1.commit();
c2.commit(); c2.commit();
......
...@@ -7,6 +7,8 @@ package org.h2.test.unit; ...@@ -7,6 +7,8 @@ package org.h2.test.unit;
import java.sql.*; import java.sql.*;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.Backup;
import org.h2.tools.Restore;
import org.h2.tools.Script; import org.h2.tools.Script;
import org.h2.tools.ChangePassword; import org.h2.tools.ChangePassword;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
...@@ -22,7 +24,8 @@ public class TestTools extends TestBase { ...@@ -22,7 +24,8 @@ public class TestTools extends TestBase {
testResourceGenerator(); testResourceGenerator();
testChangePassword(); testChangePassword();
testServer(); testServer();
testBackupRunscript(); testScriptRunscript();
testBackupRestore();
} }
private void testManagementDb() throws Exception { private void testManagementDb() throws Exception {
...@@ -35,7 +38,7 @@ public class TestTools extends TestBase { ...@@ -35,7 +38,7 @@ public class TestTools extends TestBase {
} }
} }
private void testBackupRunscript() throws Exception { private void testScriptRunscript() throws Exception {
Class.forName("org.h2.Driver"); Class.forName("org.h2.Driver");
String url = "jdbc:h2:" + BASE_DIR+ "/utils"; String url = "jdbc:h2:" + BASE_DIR+ "/utils";
String user = "sa", password = "abc"; String user = "sa", password = "abc";
...@@ -53,6 +56,27 @@ public class TestTools extends TestBase { ...@@ -53,6 +56,27 @@ public class TestTools extends TestBase {
conn.close(); conn.close();
} }
private void testBackupRestore() throws Exception {
Class.forName("org.h2.Driver");
String url = "jdbc:h2:" + BASE_DIR+ "/utils";
String user = "sa", password = "abc";
String fileName = BASE_DIR + "/b2.zip";
DeleteDbFiles.main(new String[]{"-dir", BASE_DIR, "-db", "utils", "-quiet"});
Connection conn = DriverManager.getConnection(url, user, password);
conn.createStatement().execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
conn.createStatement().execute("INSERT INTO TEST VALUES(1, 'Hello')");
conn.close();
Backup.main(new String[]{"-file", fileName, "-dir", BASE_DIR, "-db", "utils", "-quiet"});
DeleteDbFiles.main(new String[]{"-dir", BASE_DIR, "-db", "utils", "-quiet"});
Restore.main(new String[]{"-file", fileName, "-dir", BASE_DIR, "-db", "utils", "-quiet"});
conn = DriverManager.getConnection("jdbc:h2:" + BASE_DIR+ "/utils", "sa", "abc");
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
check(rs.next());
checkFalse(rs.next());
conn.close();
DeleteDbFiles.main(new String[]{"-dir", BASE_DIR, "-db", "utils", "-quiet"});
}
private void testResourceGenerator() throws Exception { private void testResourceGenerator() throws Exception {
Resources.main(new String[]{"."}); Resources.main(new String[]{"."});
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论