提交 ac4a616e authored 作者: andrei's avatar andrei

Merge remote-tracking branch 'h2database/master' into txcommit-atomic

...@@ -240,44 +240,45 @@ public class MergeUsing extends Prepared { ...@@ -240,44 +240,45 @@ public class MergeUsing extends Prepared {
} }
private boolean isTargetRowFound() { private boolean isTargetRowFound() {
ResultInterface rows = targetMatchQuery.query(0); try (ResultInterface rows = targetMatchQuery.query(0)) {
int countTargetRowsFound = 0; if (!rows.next()) {
Value[] targetRowIdValue = null; return false;
}
while (rows.next()) { Value targetRowId = rows.currentRow()[0];
countTargetRowsFound++; Integer number = targetRowidsRemembered.get(targetRowId);
targetRowIdValue = rows.currentRow();
// throw and exception if we have processed this _ROWID_ before... // throw and exception if we have processed this _ROWID_ before...
if (targetRowidsRemembered.containsKey(targetRowIdValue[0])) { if (number != null) {
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, throw DbException.get(ErrorCode.DUPLICATE_KEY_1,
"Merge using ON column expression, " + "Merge using ON column expression, " +
"duplicate _ROWID_ target record already updated, deleted or inserted:_ROWID_=" "duplicate _ROWID_ target record already updated, deleted or inserted:_ROWID_="
+ targetRowIdValue[0].toString() + ":in:" + targetRowId + ":in:"
+ targetTableFilter.getTable() + targetTableFilter.getTable()
+ ":conflicting source row number:" + ":conflicting source row number:"
+ targetRowidsRemembered + number);
.get(targetRowIdValue[0])); }
} else {
// remember the source column values we have used before (they // remember the source column values we have used before (they
// are the effective ON clause keys // are the effective ON clause keys
// and should not be repeated // and should not be repeated
targetRowidsRemembered.put(targetRowIdValue[0], targetRowidsRemembered.put(targetRowId, sourceQueryRowNumber);
sourceQueryRowNumber); if (rows.next()) {
int rowCount;
if (rows.isLazy()) {
for (rowCount = 2; rows.next(); rowCount++) {
} }
} else {
rowCount = rows.getRowCount();
} }
rows.close();
if (countTargetRowsFound > 1) {
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, throw DbException.get(ErrorCode.DUPLICATE_KEY_1,
"Duplicate key updated " + countTargetRowsFound "Duplicate key updated "
+ rowCount
+ " rows at once, only 1 expected:_ROWID_=" + " rows at once, only 1 expected:_ROWID_="
+ targetRowIdValue[0].toString() + ":in:" + targetRowId + ":in:"
+ targetTableFilter.getTable() + targetTableFilter.getTable()
+ ":conflicting source row number:" + ":conflicting source row number:"
+ targetRowidsRemembered.get(targetRowIdValue[0])); + targetRowidsRemembered.get(targetRowId));
}
return true;
} }
return countTargetRowsFound > 0;
} }
private int addRowByCommandInsert(Row sourceRow) { private int addRowByCommandInsert(Row sourceRow) {
...@@ -348,9 +349,7 @@ public class MergeUsing extends Prepared { ...@@ -348,9 +349,7 @@ public class MergeUsing extends Prepared {
onCondition.mapColumns(targetTableFilter, 1); onCondition.mapColumns(targetTableFilter, 1);
if (keys == null) { if (keys == null) {
HashSet<Column> targetColumns = buildColumnListFromOnCondition( keys = buildColumnListFromOnCondition(targetTableFilter.getTable());
targetTableFilter);
keys = targetColumns.toArray(new Column[0]);
} }
if (keys.length == 0) { if (keys.length == 0) {
throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1,
...@@ -416,19 +415,11 @@ public class MergeUsing extends Prepared { ...@@ -416,19 +415,11 @@ public class MergeUsing extends Prepared {
targetMatchQuery.prepare(); targetMatchQuery.prepare();
} }
private HashSet<Column> buildColumnListFromOnCondition( private Column[] buildColumnListFromOnCondition(Table table) {
TableFilter anyTableFilter) {
HashSet<Column> filteredColumns = new HashSet<>();
HashSet<Column> columns = new HashSet<>(); HashSet<Column> columns = new HashSet<>();
ExpressionVisitor visitor = ExpressionVisitor ExpressionVisitor visitor = ExpressionVisitor.getColumnsVisitor(columns, table);
.getColumnsVisitor(columns);
onCondition.isEverything(visitor); onCondition.isEverything(visitor);
for (Column c : columns) { return columns.toArray(new Column[0]);
if (c != null && c.getTable() == anyTableFilter.getTable()) {
filteredColumns.add(c);
}
}
return filteredColumns;
} }
private Expression appendOnCondition(Update updateCommand) { private Expression appendOnCondition(Update updateCommand) {
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package org.h2.constraint; package org.h2.constraint;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
...@@ -122,12 +121,7 @@ public class ConstraintCheck extends Constraint { ...@@ -122,12 +121,7 @@ public class ConstraintCheck extends Constraint {
@Override @Override
public HashSet<Column> getReferencedColumns(Table table) { public HashSet<Column> getReferencedColumns(Table table) {
HashSet<Column> columns = new HashSet<>(); HashSet<Column> columns = new HashSet<>();
expr.isEverything(ExpressionVisitor.getColumnsVisitor(columns)); expr.isEverything(ExpressionVisitor.getColumnsVisitor(columns, table));
for (Iterator<Column> it = columns.iterator(); it.hasNext();) {
if (it.next().getTable() != table) {
it.remove();
}
}
return columns; return columns;
} }
......
...@@ -239,10 +239,11 @@ public class ExpressionVisitor { ...@@ -239,10 +239,11 @@ public class ExpressionVisitor {
* Create a new visitor to get all referenced columns. * Create a new visitor to get all referenced columns.
* *
* @param columns the columns map * @param columns the columns map
* @param table table to gather columns from, or {@code null} to gather all columns
* @return the new visitor * @return the new visitor
*/ */
public static ExpressionVisitor getColumnsVisitor(HashSet<Column> columns) { public static ExpressionVisitor getColumnsVisitor(HashSet<Column> columns, Table table) {
return new ExpressionVisitor(GET_COLUMNS2, 0, null, null, null, null, null, columns); return new ExpressionVisitor(GET_COLUMNS2, 0, null, null, table, null, null, columns);
} }
public static ExpressionVisitor getMaxModificationIdVisitor() { public static ExpressionVisitor getMaxModificationIdVisitor() {
...@@ -269,9 +270,12 @@ public class ExpressionVisitor { ...@@ -269,9 +270,12 @@ public class ExpressionVisitor {
void addColumn1(Column column) { void addColumn1(Column column) {
columns1.add(column); columns1.add(column);
} }
void addColumn2(Column column) { void addColumn2(Column column) {
if (table == null || table == column.getTable()) {
columns2.add(column); columns2.add(column);
} }
}
/** /**
* Get the dependency set. * Get the dependency set.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论