Unverified 提交 5fe7ec4c authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #1788 from grandinj/1787_merge_lock_timeout

issue#1787: Non-standard MERGE throws LOCK_TIMEOUT_1
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package org.h2.command.dml; package org.h2.command.dml;
import java.util.ArrayList; import java.util.ArrayList;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.Command; import org.h2.command.Command;
...@@ -21,9 +20,11 @@ import org.h2.expression.Expression; ...@@ -21,9 +20,11 @@ import org.h2.expression.Expression;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.db.MVPrimaryIndex;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -181,15 +182,25 @@ public class Merge extends CommandWithValues { ...@@ -181,15 +182,25 @@ public class Merge extends CommandWithValues {
Index index = (Index) e.getSource(); Index index = (Index) e.getSource();
if (index != null) { if (index != null) {
// verify the index columns match the key // verify the index columns match the key
Column[] indexColumns = index.getColumns(); Column[] indexColumns;
boolean indexMatchesKeys = true; if (index instanceof MVPrimaryIndex) {
MVPrimaryIndex foundMV = (MVPrimaryIndex) index;
indexColumns = new Column[] {
foundMV.getIndexColumns()[foundMV.getMainIndexColumn()].column };
} else {
indexColumns = index.getColumns();
}
boolean indexMatchesKeys;
if (indexColumns.length <= keys.length) { if (indexColumns.length <= keys.length) {
indexMatchesKeys = true;
for (int i = 0; i < indexColumns.length; i++) { for (int i = 0; i < indexColumns.length; i++) {
if (indexColumns[i] != keys[i]) { if (indexColumns[i] != keys[i]) {
indexMatchesKeys = false; indexMatchesKeys = false;
break; break;
} }
} }
} else {
indexMatchesKeys = false;
} }
if (indexMatchesKeys) { if (indexMatchesKeys) {
throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, targetTable.getName()); throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, targetTable.getName());
......
...@@ -46,13 +46,13 @@ EXPLAIN MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do'); ...@@ -46,13 +46,13 @@ EXPLAIN MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do');
>> MERGE INTO "PUBLIC"."TEST"("ID", "NAME") KEY("ID") VALUES (3, 'How do you do') >> MERGE INTO "PUBLIC"."TEST"("ID", "NAME") KEY("ID") VALUES (3, 'How do you do')
MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(3, 'Fine'); MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(3, 'Fine');
> exception LOCK_TIMEOUT_1 > exception DUPLICATE_KEY_1
MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine!'); MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine!');
> update count: 1 > update count: 1
MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine! And you'); MERGE INTO TEST(ID, NAME) KEY(NAME) VALUES(4, 'Fine! And you');
> exception LOCK_TIMEOUT_1 > exception DUPLICATE_KEY_1
MERGE INTO TEST(ID, NAME) KEY(NAME, ID) VALUES(5, 'I''m ok'); MERGE INTO TEST(ID, NAME) KEY(NAME, ID) VALUES(5, 'I''m ok');
> update count: 1 > update count: 1
...@@ -94,3 +94,14 @@ SELECT * FROM TEST; ...@@ -94,3 +94,14 @@ SELECT * FROM TEST;
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
-- Test for the index matching logic in org.h2.command.dml.Merge
CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE1 INT, VALUE2 INT, UNIQUE(VALUE1, VALUE2));
> ok
MERGE INTO TEST KEY (ID) VALUES (1, 2, 3), (2, 2, 3);
> exception DUPLICATE_KEY_1
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论