提交 77396a9a authored 作者: Thomas Mueller's avatar Thomas Mueller

Issue 368: ON DUPLICATE KEY UPDATE did not work for multi-row inserts. Test case…

Issue 368: ON DUPLICATE KEY UPDATE did not work for multi-row inserts. Test case from Angus Macdonald.
上级 ede10e18
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>OSGi: the package javax.tools is now imported (as an optional).
<ul><li>Issue 368: ON DUPLICATE KEY UPDATE did not work for multi-row inserts.
Test case from Angus Macdonald.
</li><li>OSGi: the package javax.tools is now imported (as an optional).
</li><li>H2 Console: auto-complete is now triggered by the tab key.
</li><li>H2 Console: auto-complete did not work with multi-line statements.
</li><li>CLOB and BLOB data was not immediately removed after a rollback.
......
......@@ -29,7 +29,6 @@ import org.h2.result.ResultTarget;
import org.h2.result.Row;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.New;
import org.h2.util.StatementBuilder;
import org.h2.value.Value;
......@@ -327,22 +326,26 @@ public class Insert extends Prepared implements ResultTarget {
variableNames.add(key);
session.setVariable(key, list.get(getCurrentRowNumber() - 1)[i].getValue(session));
}
Update command = new Update(session);
command.setTableFilter(new TableFilter(session, table, null, true, null));
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(table.getSQL()).append(" SET ");
for (Column column : duplicateKeyAssignmentMap.keySet()) {
command.setAssignment(column, duplicateKeyAssignmentMap.get(column));
buff.appendExceptFirst(", ");
Expression ex = duplicateKeyAssignmentMap.get(column);
buff.append(column.getSQL()).append("=").append(ex.getSQL());
}
buff.append(" WHERE ");
Index foundIndex = searchForUpdateIndex();
if (foundIndex != null) {
command.setCondition(prepareUpdateCondition(foundIndex));
} else {
if (foundIndex == null) {
throw DbException.getUnsupportedException("Unable to apply ON DUPLICATE KEY UPDATE, no index found!");
}
command.prepare();
buff.append(prepareUpdateCondition(foundIndex).getSQL());
String sql = buff.toString();
Prepared command = session.prepare(sql);
for (Parameter param : command.getParameters()) {
Parameter insertParam = parameters.get(param.getIndex());
param.setValue(insertParam.getValue(session));
}
command.update();
for (String variableName : variableNames) {
session.setVariable(variableName, ValueNull.INSTANCE);
......@@ -374,25 +377,24 @@ public class Insert extends Prepared implements ResultTarget {
}
private Expression prepareUpdateCondition(Index foundIndex) {
Expression expression = null;
Expression condition = null;
for (Column column : foundIndex.getColumns()) {
ExpressionColumn expressionColumn = new ExpressionColumn(session.getDatabase(),
session.getCurrentSchemaName(), null, column.getName());
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(),
session.getCurrentSchemaName(), table.getName(), column.getName());
for (int i = 0; i < columns.length; i++) {
if (expressionColumn.getColumnName().equals(columns[i].getName())) {
if (expression == null) {
expression = new Comparison(session, Comparison.EQUAL, expressionColumn,
list.get(getCurrentRowNumber() - 1)[i++]);
if (expr.getColumnName().equals(columns[i].getName())) {
if (condition == null) {
condition = new Comparison(session, Comparison.EQUAL,
expr, list.get(getCurrentRowNumber() - 1)[i++]);
} else {
expression = new ConditionAndOr(ConditionAndOr.AND, expression, new Comparison(session,
Comparison.EQUAL, expressionColumn, list.get(0)[i++]));
condition = new ConditionAndOr(ConditionAndOr.AND, condition,
new Comparison(session, Comparison.EQUAL,
expr, list.get(0)[i++]));
}
}
}
}
return expression;
return condition;
}
}
......@@ -36,8 +36,8 @@ public class TestDuplicateKeyUpdate extends TestBase {
testDuplicateOnUnique(conn);
testDuplicateCache(conn);
testDuplicateExpression(conn);
// testOnDuplicateKeyInsertBatch(conn);
// testOnDuplicateKeyInsertMultiValue(conn);
testOnDuplicateKeyInsertBatch(conn);
testOnDuplicateKeyInsertMultiValue(conn);
conn.close();
deleteDb("duplicateKeyUpdate");
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论