提交 3b88858e authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix update count for ON DUPLICATE KEY UPDATE

上级 06da38de
......@@ -181,11 +181,15 @@ public class Insert extends Prepared implements ResultTarget {
try {
table.addRow(session, newRow);
} catch (DbException de) {
if (!handleOnDuplicate(de)) {
if (handleOnDuplicate(de)) {
// MySQL returns 2 for updated row
// TODO: detect no-op change
rowNumber++;
} else {
// INSERT IGNORE case
rowNumber--;
continue;
}
continue;
}
generatedKeys.confirmRow(newRow);
session.log(table, UndoLogRecord.INSERT, newRow);
......@@ -399,16 +403,17 @@ public class Insert extends Prepared implements ResultTarget {
}
buff.append(prepareUpdateCondition(foundIndex).getSQL());
String sql = buff.toString();
Prepared command = session.prepare(sql);
Update command = (Update) session.prepare(sql);
command.setUpdateToCurrentValuesReturnsZero(true);
for (Parameter param : command.getParameters()) {
Parameter insertParam = parameters.get(param.getIndex());
param.setValue(insertParam.getValue(session));
}
command.update();
boolean result = command.update() > 0;
for (String variableName : variableNames) {
session.setVariable(variableName, ValueNull.INSTANCE);
}
return true;
return result;
}
private Expression prepareUpdateCondition(Index foundIndex) {
......
......@@ -49,6 +49,8 @@ public class Update extends Prepared {
/** The limit expression as specified in the LIMIT clause. */
private Expression limitExpr;
private boolean updateToCurrentValuesReturnsZero;
private final ArrayList<Column> columns = New.arrayList();
private final HashMap<Column, Expression> expressionMap = new HashMap<>();
......@@ -134,7 +136,7 @@ public class Update extends Prepared {
}
newRow.setValue(i, newValue);
}
if (setOnUpdate) {
if (setOnUpdate || updateToCurrentValuesReturnsZero) {
setOnUpdate = false;
for (int i = 0; i < columnCount; i++) {
// Use equals here to detect changes from numeric 0 to 0.0 and similar
......@@ -152,6 +154,8 @@ public class Update extends Prepared {
}
}
}
} else if (updateToCurrentValuesReturnsZero) {
count--;
}
}
table.validateConvertUpdateSequence(session, newRow);
......@@ -268,4 +272,14 @@ public class Update extends Prepared {
public void setSourceTableFilter(TableFilter sourceTableFilter) {
this.sourceTableFilter = sourceTableFilter;
}
/**
* Sets expected update count for update to current values case.
*
* @param updateToCurrentValuesReturnsZero if zero should be returned as update
* count if update set row to current values
*/
public void setUpdateToCurrentValuesReturnsZero(boolean updateToCurrentValuesReturnsZero) {
this.updateToCurrentValuesReturnsZero = updateToCurrentValuesReturnsZero;
}
}
......@@ -63,8 +63,20 @@ public class TestCompatibility extends TestBase {
stat.execute("create schema s2");
stat.execute("create table s2.test(id int primary key, name varchar(255))");
stat.execute("insert into s2.test(id, name) values(1, 'a')");
stat.execute("insert into s2.test(id, name) values(1, 'b') " +
"on duplicate key update name = values(name)");
assertEquals(2, stat.executeUpdate("insert into s2.test(id, name) values(1, 'b') " +
"on duplicate key update name = values(name)"));
assertEquals(0, stat.executeUpdate("insert into s2.test(id, name) values(1, 'b') " +
"on duplicate key update name = values(name)"));
assertEquals(1, stat.executeUpdate("insert into s2.test(id, name) values(2, 'c') " +
"on duplicate key update name = values(name)"));
ResultSet rs = stat.executeQuery("select id, name from s2.test order by id");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertEquals("b", rs.getString(2));
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertEquals("c", rs.getString(2));
assertFalse(rs.next());
stat.execute("drop schema s2 cascade");
c.close();
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论