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

Databases created with version 1.3.175 and earlier that contained foreign keys…

Databases created with version 1.3.175 and earlier that contained foreign keys in combination with multi-column indexes could not be opened in some cases.
上级 5eed08af
...@@ -196,11 +196,19 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -196,11 +196,19 @@ public class AlterTableAddConstraint extends SchemaCommand {
} }
boolean isOwner = false; boolean isOwner = false;
IndexColumn.mapColumns(indexColumns, table); IndexColumn.mapColumns(indexColumns, table);
if (index != null && canUseIndex(index, table, indexColumns)) { if (index != null && canUseIndex(index, table, indexColumns, false)) {
isOwner = true; isOwner = true;
index.getIndexType().setBelongsToConstraint(true); index.getIndexType().setBelongsToConstraint(true);
} else { } else {
index = getIndex(table, indexColumns); if (db.isStarting()) {
// before version 1.3.176, an existing index was used:
// must do the same to avoid
// Unique index or primary key violation:
// "PRIMARY KEY ON """".PAGE_INDEX"
index = getIndex(table, indexColumns, true);
} else {
index = getIndex(table, indexColumns, false);
}
if (index == null) { if (index == null) {
index = createIndex(table, indexColumns, false); index = createIndex(table, indexColumns, false);
isOwner = true; isOwner = true;
...@@ -217,14 +225,14 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -217,14 +225,14 @@ public class AlterTableAddConstraint extends SchemaCommand {
} }
boolean isRefOwner = false; boolean isRefOwner = false;
if (refIndex != null && refIndex.getTable() == refTable && if (refIndex != null && refIndex.getTable() == refTable &&
canUseIndex(refIndex, refTable, refIndexColumns)) { canUseIndex(refIndex, refTable, refIndexColumns, false)) {
isRefOwner = true; isRefOwner = true;
refIndex.getIndexType().setBelongsToConstraint(true); refIndex.getIndexType().setBelongsToConstraint(true);
} else { } else {
refIndex = null; refIndex = null;
} }
if (refIndex == null) { if (refIndex == null) {
refIndex = getIndex(refTable, refIndexColumns); refIndex = getIndex(refTable, refIndexColumns, false);
if (refIndex == null) { if (refIndex == null) {
refIndex = createIndex(refTable, refIndexColumns, true); refIndex = createIndex(refTable, refIndexColumns, true);
isRefOwner = true; isRefOwner = true;
...@@ -303,9 +311,9 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -303,9 +311,9 @@ public class AlterTableAddConstraint extends SchemaCommand {
return null; return null;
} }
private static Index getIndex(Table t, IndexColumn[] cols) { private static Index getIndex(Table t, IndexColumn[] cols, boolean moreColumnOk) {
for (Index idx : t.getIndexes()) { for (Index idx : t.getIndexes()) {
if (canUseIndex(idx, t, cols)) { if (canUseIndex(idx, t, cols, moreColumnOk)) {
return idx; return idx;
} }
} }
...@@ -336,21 +344,38 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -336,21 +344,38 @@ public class AlterTableAddConstraint extends SchemaCommand {
} }
private static boolean canUseIndex(Index existingIndex, Table table, private static boolean canUseIndex(Index existingIndex, Table table,
IndexColumn[] cols) { IndexColumn[] cols, boolean moreColumnsOk) {
if (existingIndex.getTable() != table || existingIndex.getCreateSQL() == null) { if (existingIndex.getTable() != table || existingIndex.getCreateSQL() == null) {
// can't use the scan index or index of another table // can't use the scan index or index of another table
return false; return false;
} }
Column[] indexCols = existingIndex.getColumns(); Column[] indexCols = existingIndex.getColumns();
if (indexCols.length != cols.length) {
return false; if (moreColumnsOk) {
} if (indexCols.length < cols.length) {
for (IndexColumn col : cols) { return false;
// all columns of the list must be part of the index }
int idx = existingIndex.getColumnIndex(col.column); for (IndexColumn col : cols) {
if (idx < 0) { // all columns of the list must be part of the index,
// but not all columns of the index need to be part of the list
// holes are not allowed (index=a,b,c & list=a,b is ok; but list=a,c
// is not)
int idx = existingIndex.getColumnIndex(col.column);
if (idx < 0 || idx >= cols.length) {
return false;
}
}
} else {
if (indexCols.length != cols.length) {
return false; return false;
} }
for (IndexColumn col : cols) {
// all columns of the list must be part of the index
int idx = existingIndex.getColumnIndex(col.column);
if (idx < 0) {
return false;
}
}
} }
return true; return true;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论