提交 b8e6dc27 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix update count for REPLACE and convert test into SQL script

上级 3b3c53f9
......@@ -79,13 +79,12 @@ public class Replace extends Prepared {
@Override
public int update() {
int count;
int count = 0;
session.getUser().checkRight(table, Right.INSERT);
session.getUser().checkRight(table, Right.UPDATE);
setCurrentRowNumber(0);
Mode mode = session.getDatabase().getMode();
if (!list.isEmpty()) {
count = 0;
for (int x = 0, size = list.size(); x < size; x++) {
setCurrentRowNumber(x + 1);
Expression[] expr = list.get(x);
......@@ -104,16 +103,13 @@ public class Replace extends Prepared {
}
}
}
replace(newRow);
count++;
count += replace(newRow);
}
} else {
ResultInterface rows = query.query(0);
count = 0;
table.fire(session, Trigger.UPDATE | Trigger.INSERT, true);
table.lock(session, true, false);
while (rows.next()) {
count++;
Value[] r = rows.currentRow();
Row newRow = table.getTemplateRow();
setCurrentRowNumber(count);
......@@ -127,7 +123,7 @@ public class Replace extends Prepared {
throw setRow(ex, count, getSQL(r));
}
}
replace(newRow);
count += replace(newRow);
}
rows.close();
table.fire(session, Trigger.UPDATE | Trigger.INSERT, false);
......@@ -135,7 +131,13 @@ public class Replace extends Prepared {
return count;
}
private void replace(Row row) {
/**
* Updates an existing row or inserts a new one.
*
* @param row row to replace
* @return 1 if row was inserted, 2 if row was updated
*/
private int replace(Row row) {
int count = update(row);
if (count == 0) {
try {
......@@ -147,6 +149,7 @@ public class Replace extends Prepared {
session.log(table, UndoLogRecord.INSERT, row);
table.fireAfterRow(session, null, row, false);
}
return 1;
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
// possibly a concurrent replace or insert
......@@ -170,9 +173,10 @@ public class Replace extends Prepared {
}
throw e;
}
} else if (count != 1) {
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, table.getSQL());
} else if (count == 1) {
return 2;
}
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, table.getSQL());
}
private int update(Row row) {
......
......@@ -62,7 +62,6 @@ import org.h2.test.db.TestPowerOff;
import org.h2.test.db.TestQueryCache;
import org.h2.test.db.TestReadOnly;
import org.h2.test.db.TestRecursiveQueries;
import org.h2.test.db.TestReplace;
import org.h2.test.db.TestRights;
import org.h2.test.db.TestRowFactory;
import org.h2.test.db.TestRunscript;
......@@ -793,7 +792,6 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestView());
addTest(new TestViewAlterTable());
addTest(new TestViewDropView());
addTest(new TestReplace());
addTest(new TestSynonymForTable());
addTest(new TestColumnNamer());
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: Cemo
*/
package org.h2.test.db;
import org.h2.test.TestBase;
import org.h2.test.TestDb;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Test the MySQL-compatibility REPLACE command.
*
* @author Cemo
*/
public class TestReplace extends TestDb {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws SQLException {
deleteDb("replace");
Connection conn = getConnection("replace");
testReplace(conn);
conn.close();
deleteDb("replace");
}
private void testReplace(Connection conn) throws SQLException {
Statement stat = conn.createStatement();
ResultSet rs;
stat.execute("CREATE TABLE TABLE_WORD (" +
" WORD_ID int(11) NOT NULL AUTO_INCREMENT," +
" WORD varchar(128) NOT NULL," +
" PRIMARY KEY (WORD_ID)" +
");");
stat.execute("REPLACE INTO TABLE_WORD " +
"( WORD ) VALUES ('aaaaaaaaaa')");
stat.execute("REPLACE INTO TABLE_WORD " +
"( WORD ) VALUES ('bbbbbbbbbb')");
stat.execute("REPLACE INTO TABLE_WORD " +
"( WORD_ID, WORD ) VALUES (3, 'cccccccccc')");
rs = stat.executeQuery("SELECT WORD " +
"FROM TABLE_WORD where WORD_ID = 1");
rs.next();
assertEquals("aaaaaaaaaa", rs.getNString(1));
stat.execute("REPLACE INTO TABLE_WORD " +
"( WORD_ID, WORD ) VALUES (1, 'REPLACED')");
rs = stat.executeQuery("SELECT WORD FROM TABLE_WORD where WORD_ID = 1");
rs.next();
assertEquals("REPLACED", rs.getNString(1));
}
}
......@@ -128,7 +128,7 @@ public class TestScript extends TestDb {
"dropDomain", "dropIndex", "dropSchema", "truncateTable" }) {
testScript("ddl/" + s + ".sql");
}
for (String s : new String[] { "error_reporting", "insertIgnore",
for (String s : new String[] { "error_reporting", "insertIgnore", "replace",
"mergeUsing", "script", "with" }) {
testScript("dml/" + s + ".sql");
}
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE TABLE TABLE_WORD (
WORD_ID int(11) NOT NULL AUTO_INCREMENT,
WORD varchar(128) NOT NULL,
PRIMARY KEY (WORD_ID)
);
> ok
REPLACE INTO TABLE_WORD(WORD) VALUES ('aaaaaaaaaa');
> update count: 1
REPLACE INTO TABLE_WORD(WORD) VALUES ('bbbbbbbbbb');
> update count: 1
REPLACE INTO TABLE_WORD(WORD_ID, WORD) VALUES (3, 'cccccccccc');
> update count: 1
SELECT WORD FROM TABLE_WORD where WORD_ID = 1;
>> aaaaaaaaaa
REPLACE INTO TABLE_WORD(WORD_ID, WORD) VALUES (1, 'REPLACED');
> update count: 2
SELECT WORD FROM TABLE_WORD where WORD_ID = 1;
>> REPLACED
DROP TABLE TABLE_WORD;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论