提交 eab40a6c authored 作者: Thomas Mueller's avatar Thomas Mueller

Non-row based triggers were called even if the action didn't match the declared action.

上级 5eca85f1
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.command.dml; package org.h2.command.dml;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.api.Trigger;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -46,7 +47,7 @@ public class Delete extends Prepared { ...@@ -46,7 +47,7 @@ public class Delete extends Prepared {
tableFilter.reset(); tableFilter.reset();
Table table = tableFilter.getTable(); Table table = tableFilter.getTable();
session.getUser().checkRight(table, Right.DELETE); session.getUser().checkRight(table, Right.DELETE);
table.fireBefore(session); table.fire(session, Trigger.DELETE, true);
table.lock(session, true, false); table.lock(session, true, false);
RowList rows = new RowList(session); RowList rows = new RowList(session);
try { try {
...@@ -76,7 +77,7 @@ public class Delete extends Prepared { ...@@ -76,7 +77,7 @@ public class Delete extends Prepared {
table.fireAfterRow(session, row, null); table.fireAfterRow(session, row, null);
} }
} }
table.fireAfter(session); table.fire(session, Trigger.DELETE, false);
return rows.size(); return rows.size();
} finally { } finally {
rows.close(); rows.close();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.command.dml; package org.h2.command.dml;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.api.Trigger;
import org.h2.command.Command; import org.h2.command.Command;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
...@@ -90,6 +91,7 @@ public class Insert extends Prepared { ...@@ -90,6 +91,7 @@ public class Insert extends Prepared {
int count; int count;
session.getUser().checkRight(table, Right.INSERT); session.getUser().checkRight(table, Right.INSERT);
setCurrentRowNumber(0); setCurrentRowNumber(0);
table.fire(session, Trigger.INSERT, true);
if (list.size() > 0) { if (list.size() > 0) {
count = 0; count = 0;
for (int x = 0; x < list.size(); x++) { for (int x = 0; x < list.size(); x++) {
...@@ -111,20 +113,17 @@ public class Insert extends Prepared { ...@@ -111,20 +113,17 @@ public class Insert extends Prepared {
} }
} }
} }
table.fireBefore(session);
table.validateConvertUpdateSequence(session, newRow); table.validateConvertUpdateSequence(session, newRow);
table.fireBeforeRow(session, null, newRow); table.fireBeforeRow(session, null, newRow);
table.lock(session, true, false); table.lock(session, true, false);
table.addRow(session, newRow); table.addRow(session, newRow);
session.log(table, UndoLogRecord.INSERT, newRow); session.log(table, UndoLogRecord.INSERT, newRow);
table.fireAfter(session);
table.fireAfterRow(session, null, newRow); table.fireAfterRow(session, null, newRow);
count++; count++;
} }
} else { } else {
ResultInterface rows = query.query(0); ResultInterface rows = query.query(0);
count = 0; count = 0;
table.fireBefore(session);
table.lock(session, true, false); table.lock(session, true, false);
while (rows.next()) { while (rows.next()) {
count++; count++;
...@@ -148,8 +147,8 @@ public class Insert extends Prepared { ...@@ -148,8 +147,8 @@ public class Insert extends Prepared {
table.fireAfterRow(session, null, newRow); table.fireAfterRow(session, null, newRow);
} }
rows.close(); rows.close();
table.fireAfter(session);
} }
table.fire(session, Trigger.INSERT, false);
return count; return count;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.command.dml; package org.h2.command.dml;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.api.Trigger;
import org.h2.command.Command; import org.h2.command.Command;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
...@@ -128,7 +129,7 @@ public class Merge extends Prepared { ...@@ -128,7 +129,7 @@ public class Merge extends Prepared {
} else { } else {
ResultInterface rows = query.query(0); ResultInterface rows = query.query(0);
count = 0; count = 0;
table.fireBefore(session); table.fire(session, Trigger.UPDATE | Trigger.INSERT, true);
table.lock(session, true, false); table.lock(session, true, false);
while (rows.next()) { while (rows.next()) {
count++; count++;
...@@ -148,7 +149,7 @@ public class Merge extends Prepared { ...@@ -148,7 +149,7 @@ public class Merge extends Prepared {
merge(newRow); merge(newRow);
} }
rows.close(); rows.close();
table.fireAfter(session); table.fire(session, Trigger.UPDATE | Trigger.INSERT, false);
} }
return count; return count;
} }
...@@ -173,13 +174,11 @@ public class Merge extends Prepared { ...@@ -173,13 +174,11 @@ public class Merge extends Prepared {
int count = update.update(); int count = update.update();
if (count == 0) { if (count == 0) {
try { try {
table.fireBefore(session);
table.validateConvertUpdateSequence(session, row); table.validateConvertUpdateSequence(session, row);
table.fireBeforeRow(session, null, row); table.fireBeforeRow(session, null, row);
table.lock(session, true, false); table.lock(session, true, false);
table.addRow(session, row); table.addRow(session, row);
session.log(table, UndoLogRecord.INSERT, row); session.log(table, UndoLogRecord.INSERT, row);
table.fireAfter(session);
table.fireAfterRow(session, null, row); table.fireAfterRow(session, null, row);
} catch (SQLException e) { } catch (SQLException e) {
if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) { if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.command.dml; package org.h2.command.dml;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.api.Trigger;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Right; import org.h2.engine.Right;
...@@ -77,7 +78,7 @@ public class Update extends Prepared { ...@@ -77,7 +78,7 @@ public class Update extends Prepared {
try { try {
Table table = tableFilter.getTable(); Table table = tableFilter.getTable();
session.getUser().checkRight(table, Right.UPDATE); session.getUser().checkRight(table, Right.UPDATE);
table.fireBefore(session); table.fire(session, Trigger.UPDATE, true);
table.lock(session, true, false); table.lock(session, true, false);
int columnCount = table.getColumns().length; int columnCount = table.getColumns().length;
// get the old rows, compute the new rows // get the old rows, compute the new rows
...@@ -128,7 +129,7 @@ public class Update extends Prepared { ...@@ -128,7 +129,7 @@ public class Update extends Prepared {
table.fireAfterRow(session, o, n); table.fireAfterRow(session, o, n);
} }
} }
table.fireAfter(session); table.fire(session, Trigger.UPDATE, false);
return count; return count;
} finally { } finally {
rows.close(); rows.close();
......
...@@ -718,29 +718,16 @@ public abstract class Table extends SchemaObjectBase { ...@@ -718,29 +718,16 @@ public abstract class Table extends SchemaObjectBase {
} }
/** /**
* Fire the before update triggers for this table. * Fire the triggers for this table.
* *
* @param session the session * @param session the session
* @param type the trigger type
* @param beforeAction whether 'before' triggers should be called
*/ */
public void fireBefore(Session session) throws SQLException { public void fire(Session session, int type, boolean beforeAction) throws SQLException {
// TODO trigger: for sql server compatibility,
// should send list of rows, not just 'the event'
fire(session, true);
}
/**
* Fire the after update triggers for this table.
*
* @param session the session
*/
public void fireAfter(Session session) throws SQLException {
fire(session, false);
}
private void fire(Session session, boolean beforeAction) throws SQLException {
if (triggers != null) { if (triggers != null) {
for (TriggerObject trigger : triggers) { for (TriggerObject trigger : triggers) {
trigger.fire(session, beforeAction); trigger.fire(session, type, beforeAction);
} }
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package org.h2.test.db; package org.h2.test.db;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
...@@ -36,12 +37,65 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -36,12 +37,65 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("trigger"); deleteDb("trigger");
testTriggerBeforeSelect();
testTriggerAlterTable(); testTriggerAlterTable();
testTriggers(); testTriggers();
testConstraints(); testConstraints();
deleteDb("trigger"); deleteDb("trigger");
} }
private void testTriggerBeforeSelect() throws SQLException {
Connection conn;
Statement stat;
conn = getConnection("trigger");
stat = conn.createStatement();
stat.execute("drop table if exists meta_tables");
stat.execute("create table meta_tables(name varchar)");
stat.execute("create trigger meta_tables_sel before select on meta_tables call \"" + TestSelect.class.getName() + "\"");
ResultSet rs;
rs = stat.executeQuery("select * from meta_tables");
assertTrue(rs.next());
assertFalse(rs.next());
stat.execute("create table test(id int)");
rs = stat.executeQuery("select * from meta_tables");
assertTrue(rs.next());
assertTrue(rs.next());
assertFalse(rs.next());
conn.close();
if (!config.memory) {
conn = getConnection("trigger");
stat = conn.createStatement();
stat.execute("create table test2(id int)");
rs = stat.executeQuery("select * from meta_tables");
assertTrue(rs.next());
assertTrue(rs.next());
assertTrue(rs.next());
assertFalse(rs.next());
conn.close();
}
}
/**
* A test trigger implementation.
*/
public static class TestSelect implements Trigger {
PreparedStatement prepMeta;
public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before,
int type) throws SQLException {
prepMeta = conn.prepareStatement("insert into meta_tables " +
"select table_name from information_schema.tables " +
"where table_schema='PUBLIC'");
}
public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException {
conn.createStatement().execute("delete from meta_tables");
prepMeta.execute();
}
}
/** /**
* A test trigger implementation. * A test trigger implementation.
*/ */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论