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

--no commit message

--no commit message
上级 03d85cbe
...@@ -6,6 +6,7 @@ package org.h2.index; ...@@ -6,6 +6,7 @@ package org.h2.index;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -15,6 +16,7 @@ import org.h2.result.SearchRow; ...@@ -15,6 +16,7 @@ import org.h2.result.SearchRow;
import org.h2.store.Storage; import org.h2.store.Storage;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.TableData; import org.h2.table.TableData;
import org.h2.util.IntIntHashMap;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -29,10 +31,15 @@ public class ScanIndex extends BaseIndex { ...@@ -29,10 +31,15 @@ public class ScanIndex extends BaseIndex {
private Storage storage; private Storage storage;
private TableData tableData; private TableData tableData;
private boolean containsLargeObject; private boolean containsLargeObject;
private int rowCountDiff;
private IntIntHashMap sessionRowCount;
public ScanIndex(TableData table, int id, Column[] columns, IndexType indexType) public ScanIndex(TableData table, int id, Column[] columns, IndexType indexType)
throws SQLException { throws SQLException {
super(table, id, table.getName() + "_TABLE_SCAN", columns, indexType); super(table, id, table.getName() + "_TABLE_SCAN", columns, indexType);
if(SysProperties.MVCC) {
sessionRowCount = new IntIntHashMap();
}
tableData = table; tableData = table;
Database db = table.getDatabase(); Database db = table.getDatabase();
if(!db.isPersistent() || id < 0) { if(!db.isPersistent() || id < 0) {
...@@ -114,8 +121,21 @@ public class ScanIndex extends BaseIndex { ...@@ -114,8 +121,21 @@ public class ScanIndex extends BaseIndex {
rows.set(key, row); rows.set(key, row);
} }
} }
incrementRowCount(session, 1);
rowCount++; rowCount++;
} }
private void incrementRowCount(Session session, int count) {
if(SysProperties.MVCC) {
int id = session.getId();
int current = sessionRowCount.get(id);
if(current == -1) {
current = 0;
}
sessionRowCount.put(id, current + count);
rowCountDiff += count;
}
}
public void remove(Session session, Row row) throws SQLException { public void remove(Session session, Row row) throws SQLException {
if(storage != null) { if(storage != null) {
...@@ -135,6 +155,7 @@ public class ScanIndex extends BaseIndex { ...@@ -135,6 +155,7 @@ public class ScanIndex extends BaseIndex {
rows.set(key, free); rows.set(key, free);
firstFree = key; firstFree = key;
} }
incrementRowCount(session, -1);
rowCount--; rowCount--;
} }
...@@ -149,6 +170,19 @@ public class ScanIndex extends BaseIndex { ...@@ -149,6 +170,19 @@ public class ScanIndex extends BaseIndex {
} }
return cost; return cost;
} }
public long getRowCount(Session session) {
if(SysProperties.MVCC) {
long count = sessionRowCount.get(session.getId());
if(count == -1) {
count = 0;
}
count += super.getRowCount(session);
count -= rowCountDiff;
return count;
}
return super.getRowCount(session);
}
Row getNextRow(Session session, Row row) throws SQLException { Row getNextRow(Session session, Row row) throws SQLException {
if(storage == null) { if(storage == null) {
......
...@@ -83,9 +83,11 @@ public class TableData extends Table implements RecordReader { ...@@ -83,9 +83,11 @@ public class TableData extends Table implements RecordReader {
Index index = (Index) indexes.get(i); Index index = (Index) indexes.get(i);
index.add(session, row); index.add(session, row);
if(SysProperties.CHECK) { if(SysProperties.CHECK) {
long rc = index.getRowCount(session); if(!SysProperties.MVCC) {
if(rc != rowCount+1) { long rc = index.getRowCount(session);
throw Message.getInternalError("rowCount expected "+(rowCount+1)+" got "+rc); if(rc != rowCount+1) {
throw Message.getInternalError("rowCount expected "+(rowCount+1)+" got "+rc);
}
} }
} }
} }
...@@ -96,9 +98,11 @@ public class TableData extends Table implements RecordReader { ...@@ -96,9 +98,11 @@ public class TableData extends Table implements RecordReader {
Index index = (Index) indexes.get(i); Index index = (Index) indexes.get(i);
index.remove(session, row); index.remove(session, row);
if(SysProperties.CHECK) { if(SysProperties.CHECK) {
long rc = index.getRowCount(session); if(!SysProperties.MVCC) {
if(rc != rowCount) { long rc = index.getRowCount(session);
throw Message.getInternalError("rowCount expected "+(rowCount)+" got "+rc); if(rc != rowCount) {
throw Message.getInternalError("rowCount expected "+(rowCount)+" got "+rc);
}
} }
} }
} }
...@@ -252,6 +256,9 @@ public class TableData extends Table implements RecordReader { ...@@ -252,6 +256,9 @@ public class TableData extends Table implements RecordReader {
} }
public long getRowCount(Session session) { public long getRowCount(Session session) {
if(SysProperties.MVCC) {
return getScanIndex(session).getRowCount(session);
}
return rowCount; return rowCount;
} }
...@@ -261,9 +268,11 @@ public class TableData extends Table implements RecordReader { ...@@ -261,9 +268,11 @@ public class TableData extends Table implements RecordReader {
Index index = (Index) indexes.get(i); Index index = (Index) indexes.get(i);
index.remove(session, row); index.remove(session, row);
if(SysProperties.CHECK) { if(SysProperties.CHECK) {
long rc = index.getRowCount(session); if(!SysProperties.MVCC) {
if(rc != rowCount-1) { long rc = index.getRowCount(session);
throw Message.getInternalError("rowCount expected "+(rowCount-1)+" got "+rc); if(rc != rowCount-1) {
throw Message.getInternalError("rowCount expected "+(rowCount-1)+" got "+rc);
}
} }
} }
} }
......
...@@ -33,17 +33,11 @@ public class TestMVCC { ...@@ -33,17 +33,11 @@ public class TestMVCC {
c1.setAutoCommit(false); c1.setAutoCommit(false);
c2.setAutoCommit(false); c2.setAutoCommit(false);
s1.execute("CREATE TABLE A(ID INT PRIMARY KEY, SK INT)"); s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)");
s1.execute("INSERT INTO A VALUES(1, 2)"); s1.execute("INSERT INTO TEST(NAME) VALUES('Ruebezahl')");
test(s1, "SELECT 1 FROM (SELECT SK FROM PUBLIC.A ORDER BY SK) C WHERE NOT EXISTS(SELECT 1 FROM PUBLIC.A P WHERE C.SK=P.ID)", "1"); test(s2, "SELECT COUNT(*) FROM TEST", "0");
c1.commit(); test(s1, "SELECT COUNT(*) FROM TEST", "1");
test(s1, "SELECT 1 FROM (SELECT SK FROM PUBLIC.A ORDER BY SK) C WHERE NOT EXISTS(SELECT 1 FROM PUBLIC.A P WHERE C.SK=P.ID)", "1"); s1.execute("DROP TABLE TEST");
try {
s1.execute("ALTER TABLE A ADD CONSTRAINT AC FOREIGN KEY(SK) REFERENCES A(ID)");
throw new Exception("unexpected success");
} catch(SQLException e) {
// expected
}
c1.commit(); c1.commit();
s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)"); s1.execute("CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论