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