提交 9f7ef4b1 authored 作者: XEHA6284's avatar XEHA6284

Add support for INSERT IGNORE from SELECT in MySQL Mode

上级 c433682f
...@@ -23,6 +23,7 @@ import org.h2.expression.Expression; ...@@ -23,6 +23,7 @@ import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn; import org.h2.expression.ExpressionColumn;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.expression.SequenceValue; import org.h2.expression.SequenceValue;
import org.h2.expression.ValueExpression;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.PageDataIndex; import org.h2.index.PageDataIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -207,10 +208,21 @@ public class Insert extends Prepared implements ResultTarget { ...@@ -207,10 +208,21 @@ public class Insert extends Prepared implements ResultTarget {
while (rows.next()) { while (rows.next()) {
generatedKeys.nextRow(); generatedKeys.nextRow();
Value[] r = rows.currentRow(); Value[] r = rows.currentRow();
try {
Row newRow = addRowImpl(r); Row newRow = addRowImpl(r);
if (newRow != null) { if (newRow != null) {
generatedKeys.confirmRow(newRow); generatedKeys.confirmRow(newRow);
} }
} catch (DbException de) {
if (handleOnDuplicate(de)) {
// MySQL returns 2 for updated row
// TODO: detect no-op change
rowNumber++;
} else {
// INSERT IGNORE case
rowNumber--;
}
}
} }
rows.close(); rows.close();
} }
...@@ -227,12 +239,14 @@ public class Insert extends Prepared implements ResultTarget { ...@@ -227,12 +239,14 @@ public class Insert extends Prepared implements ResultTarget {
private Row addRowImpl(Value[] values) { private Row addRowImpl(Value[] values) {
Row newRow = table.getTemplateRow(); Row newRow = table.getTemplateRow();
setCurrentRowNumber(++rowNumber); setCurrentRowNumber(++rowNumber);
Expression[] exp = new Expression[columns.length];
for (int j = 0, len = columns.length; j < len; j++) { for (int j = 0, len = columns.length; j < len; j++) {
Column c = columns[j]; Column c = columns[j];
int index = c.getColumnId(); int index = c.getColumnId();
try { try {
Value v = c.convert(values[j], session.getDatabase().getMode()); Value v = c.convert(values[j], session.getDatabase().getMode());
newRow.setValue(index, v); newRow.setValue(index, v);
exp[j] = ValueExpression.get(v);
} catch (DbException ex) { } catch (DbException ex) {
throw setRow(ex, rowNumber, getSQL(values)); throw setRow(ex, rowNumber, getSQL(values));
} }
...@@ -240,6 +254,7 @@ public class Insert extends Prepared implements ResultTarget { ...@@ -240,6 +254,7 @@ public class Insert extends Prepared implements ResultTarget {
table.validateConvertUpdateSequence(session, newRow); table.validateConvertUpdateSequence(session, newRow);
boolean done = table.fireBeforeRow(session, null, newRow); boolean done = table.fireBeforeRow(session, null, newRow);
if (!done) { if (!done) {
addRow(exp);
table.addRow(session, newRow); table.addRow(session, newRow);
session.log(table, UndoLogRecord.INSERT, newRow); session.log(table, UndoLogRecord.INSERT, newRow);
table.fireAfterRow(session, null, newRow, false); table.fireAfterRow(session, null, newRow, false);
......
...@@ -39,3 +39,40 @@ SELECT * FROM TEST ORDER BY ID; ...@@ -39,3 +39,40 @@ SELECT * FROM TEST ORDER BY ID;
> 4 40 > 4 40
> 5 52 > 5 52
> rows (ordered): 5 > rows (ordered): 5
CREATE TABLE TESTREF(ID BIGINT PRIMARY KEY, VALUE INT NOT NULL);
> ok
INSERT INTO TESTREF VALUES (1, 11), (2, 21), (6, 61), (7, 71);
> update count: 4
INSERT INTO TEST (ID, VALUE) SELECT ID, VALUE FROM TESTREF;
> exception DUPLICATE_KEY_1
SELECT * FROM TEST ORDER BY ID;
> ID VALUE
> -- -----
> 1 10
> 2 20
> 3 30
> 4 40
> 5 52
> rows (ordered): 5
INSERT IGNORE INTO TEST (ID, VALUE) SELECT ID, VALUE FROM TESTREF;
> update count: 2
INSERT IGNORE INTO TEST (ID, VALUE) SELECT ID, VALUE FROM TESTREF;
> ok
SELECT * FROM TEST ORDER BY ID;
> ID VALUE
> -- -----
> 1 10
> 2 20
> 3 30
> 4 40
> 5 52
> 6 61
> 7 71
> rows (ordered): 7
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论