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