Unverified 提交 849484e9 authored 作者: Andrei Tokar's avatar Andrei Tokar 提交者: GitHub

Merge pull request #1334 from h2database/issue#1331

Force SYS_ID.ID index always to be a MVDelegateIndex
...@@ -8,10 +8,13 @@ package org.h2.engine; ...@@ -8,10 +8,13 @@ package org.h2.engine;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
...@@ -36,6 +39,7 @@ import org.h2.jdbc.JdbcConnection; ...@@ -36,6 +39,7 @@ import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.db.MVTableEngine; import org.h2.mvstore.db.MVTableEngine;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.RowFactory; import org.h2.result.RowFactory;
...@@ -783,6 +787,7 @@ public class Database implements DataHandler { ...@@ -783,6 +787,7 @@ public class Database implements DataHandler {
data.isHidden = true; data.isHidden = true;
data.session = systemSession; data.session = systemSession;
meta = mainSchema.createTable(data); meta = mainSchema.createTable(data);
handleUpgradeIssues();
IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId }); IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId });
starting = true; starting = true;
metaIdIndex = meta.addIndex(systemSession, "SYS_ID", metaIdIndex = meta.addIndex(systemSession, "SYS_ID",
...@@ -839,6 +844,50 @@ public class Database implements DataHandler { ...@@ -839,6 +844,50 @@ public class Database implements DataHandler {
} }
} }
private void handleUpgradeIssues() {
if (mvStore != null && !isReadOnly()) {
MVStore store = mvStore.getStore();
// Version 1.4.197 erroneously handles index on SYS_ID.ID as secondary
// and does not delegate to scan index as it should.
// This code will try to fix that by converging ROW_ID and ID,
// since they may have got out of sync, and by removing map "index.0",
// which corresponds to a secondary index.
if (store.hasMap("index.0")) {
Index scanIndex = meta.getScanIndex(systemSession);
Cursor curs = scanIndex.find(systemSession, null, null);
List<Row> allMetaRows = new ArrayList<>();
boolean needRepair = false;
while (curs.next()) {
Row row = curs.get();
allMetaRows.add(row);
long rowId = row.getKey();
int id = row.getValue(0).getInt();
if (id != rowId) {
needRepair = true;
row.setKey(id);
}
}
if (needRepair) {
Row[] array = allMetaRows.toArray(new Row[0]);
Arrays.sort(array, new Comparator<Row>() {
@Override
public int compare(Row o1, Row o2) {
return Integer.compare(o1.getValue(0).getInt(), o2.getValue(0).getInt());
}
});
meta.truncate(systemSession);
for (Row row : array) {
meta.addRow(systemSession, row);
}
systemSession.commit(true);
}
store.removeMap("index.0");
store.commit();
}
}
}
private void startServer(String key) { private void startServer(String key) {
try { try {
server = Server.createTcpServer( server = Server.createTcpServer(
......
...@@ -499,12 +499,15 @@ public class MVTable extends TableBase { ...@@ -499,12 +499,15 @@ public class MVTable extends TableBase {
int mainIndexColumn = primaryIndex.getMainIndexColumn() != SearchRow.ROWID_INDEX int mainIndexColumn = primaryIndex.getMainIndexColumn() != SearchRow.ROWID_INDEX
? SearchRow.ROWID_INDEX : getMainIndexColumn(indexType, cols); ? SearchRow.ROWID_INDEX : getMainIndexColumn(indexType, cols);
if (database.isStarting()) { if (database.isStarting()) {
// if index does exists as a separate map it can't be a delegate
if (transactionStore.hasMap("index." + indexId)) { if (transactionStore.hasMap("index." + indexId)) {
// we can not reuse primary index
mainIndexColumn = SearchRow.ROWID_INDEX; mainIndexColumn = SearchRow.ROWID_INDEX;
} }
} else if (primaryIndex.getRowCountMax() != 0) { } else if (primaryIndex.getRowCountMax() != 0) {
mainIndexColumn = SearchRow.ROWID_INDEX; mainIndexColumn = SearchRow.ROWID_INDEX;
} }
if (mainIndexColumn != SearchRow.ROWID_INDEX) { if (mainIndexColumn != SearchRow.ROWID_INDEX) {
primaryIndex.setMainIndexColumn(mainIndexColumn); primaryIndex.setMainIndexColumn(mainIndexColumn);
index = new MVDelegateIndex(this, indexId, indexName, primaryIndex, index = new MVDelegateIndex(this, indexId, indexName, primaryIndex,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论