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

Trigger can now be called on rollback.

上级 17dfbe4f
...@@ -3697,6 +3697,7 @@ public class Parser { ...@@ -3697,6 +3697,7 @@ public class Parser {
isBefore = false; isBefore = false;
} }
int typeMask = 0; int typeMask = 0;
boolean onRollback = false;
do { do {
if (readIf("INSERT")) { if (readIf("INSERT")) {
typeMask |= Trigger.INSERT; typeMask |= Trigger.INSERT;
...@@ -3706,6 +3707,8 @@ public class Parser { ...@@ -3706,6 +3707,8 @@ public class Parser {
typeMask |= Trigger.DELETE; typeMask |= Trigger.DELETE;
} else if (readIf("SELECT")) { } else if (readIf("SELECT")) {
typeMask |= Trigger.SELECT; typeMask |= Trigger.SELECT;
} else if (readIf("ROLLBACK")) {
onRollback = true;
} else { } else {
throw getSyntaxError(); throw getSyntaxError();
} }
...@@ -3718,6 +3721,7 @@ public class Parser { ...@@ -3718,6 +3721,7 @@ public class Parser {
command.setTriggerName(triggerName); command.setTriggerName(triggerName);
command.setIfNotExists(ifNotExists); command.setIfNotExists(ifNotExists);
command.setBefore(isBefore); command.setBefore(isBefore);
command.setOnRollback(onRollback);
command.setTypeMask(typeMask); command.setTypeMask(typeMask);
command.setTableName(tableName); command.setTableName(tableName);
if (readIf("FOR")) { if (readIf("FOR")) {
......
...@@ -33,6 +33,7 @@ public class CreateTrigger extends SchemaCommand { ...@@ -33,6 +33,7 @@ public class CreateTrigger extends SchemaCommand {
private String tableName; private String tableName;
private String triggerClassName; private String triggerClassName;
private boolean force; private boolean force;
private boolean onRollback;
public CreateTrigger(Session session, Schema schema) { public CreateTrigger(Session session, Schema schema) {
super(session, schema); super(session, schema);
...@@ -91,6 +92,7 @@ public class CreateTrigger extends SchemaCommand { ...@@ -91,6 +92,7 @@ public class CreateTrigger extends SchemaCommand {
trigger.setQueueSize(queueSize); trigger.setQueueSize(queueSize);
trigger.setRowBased(rowBased); trigger.setRowBased(rowBased);
trigger.setTypeMask(typeMask); trigger.setTypeMask(typeMask);
trigger.setOnRollback(onRollback);
trigger.setTriggerClassName(session, triggerClassName, force); trigger.setTriggerClassName(session, triggerClassName, force);
db.addSchemaObject(session, trigger); db.addSchemaObject(session, trigger);
table.addTrigger(trigger); table.addTrigger(trigger);
...@@ -101,4 +103,8 @@ public class CreateTrigger extends SchemaCommand { ...@@ -101,4 +103,8 @@ public class CreateTrigger extends SchemaCommand {
this.force = force; this.force = force;
} }
public void setOnRollback(boolean onRollback) {
this.onRollback = onRollback;
}
} }
...@@ -74,7 +74,7 @@ public class Delete extends Prepared { ...@@ -74,7 +74,7 @@ public class Delete extends Prepared {
if (table.fireRow()) { if (table.fireRow()) {
for (rows.reset(); rows.hasNext();) { for (rows.reset(); rows.hasNext();) {
Row row = rows.next(); Row row = rows.next();
table.fireAfterRow(session, row, null); table.fireAfterRow(session, row, null, false);
} }
} }
table.fire(session, Trigger.DELETE, false); table.fire(session, Trigger.DELETE, false);
......
...@@ -118,7 +118,7 @@ public class Insert extends Prepared { ...@@ -118,7 +118,7 @@ public class Insert extends Prepared {
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.fireAfterRow(session, null, newRow); table.fireAfterRow(session, null, newRow, false);
count++; count++;
} }
} else { } else {
...@@ -144,7 +144,7 @@ public class Insert extends Prepared { ...@@ -144,7 +144,7 @@ public class Insert extends Prepared {
table.fireBeforeRow(session, null, newRow); table.fireBeforeRow(session, null, newRow);
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); table.fireAfterRow(session, null, newRow, false);
} }
rows.close(); rows.close();
} }
......
...@@ -179,7 +179,7 @@ public class Merge extends Prepared { ...@@ -179,7 +179,7 @@ public class Merge extends Prepared {
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.fireAfterRow(session, null, row); table.fireAfterRow(session, null, row, false);
} catch (SQLException e) { } catch (SQLException e) {
if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) { if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
// concurrent merge or insert // concurrent merge or insert
......
...@@ -126,7 +126,7 @@ public class Update extends Prepared { ...@@ -126,7 +126,7 @@ public class Update extends Prepared {
for (rows.reset(); rows.hasNext();) { for (rows.reset(); rows.hasNext();) {
Row o = rows.next(); Row o = rows.next();
Row n = rows.next(); Row n = rows.next();
table.fireAfterRow(session, o, n); table.fireAfterRow(session, o, n, false);
} }
} }
table.fire(session, Trigger.UPDATE, false); table.fire(session, Trigger.UPDATE, false);
......
...@@ -107,6 +107,7 @@ public class UndoLogRecord { ...@@ -107,6 +107,7 @@ public class UndoLogRecord {
try { try {
row.setDeleted(false); row.setDeleted(false);
table.removeRow(session, row); table.removeRow(session, row);
table.fireAfterRow(session, row, null, true);
} catch (SQLException e) { } catch (SQLException e) {
if (session.getDatabase().getLockMode() == Constants.LOCK_MODE_OFF if (session.getDatabase().getLockMode() == Constants.LOCK_MODE_OFF
&& e.getErrorCode() == ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) { && e.getErrorCode() == ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) {
...@@ -123,6 +124,7 @@ public class UndoLogRecord { ...@@ -123,6 +124,7 @@ public class UndoLogRecord {
row.setKey(0); row.setKey(0);
} }
table.addRow(session, row); table.addRow(session, row);
table.fireAfterRow(session, null, row, true);
// reset session id, otherwise other session think // reset session id, otherwise other session think
// that this row was inserted by this session // that this row was inserted by this session
row.commit(); row.commit();
......
...@@ -38,6 +38,7 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -38,6 +38,7 @@ public class TriggerObject extends SchemaObjectBase {
private boolean before; private boolean before;
private int typeMask; private int typeMask;
private boolean rowBased; private boolean rowBased;
private boolean onRollback;
// TODO trigger: support queue and noWait = false as well // TODO trigger: support queue and noWait = false as well
private int queueSize = DEFAULT_QUEUE_SIZE; private int queueSize = DEFAULT_QUEUE_SIZE;
private boolean noWait; private boolean noWait;
...@@ -147,11 +148,15 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -147,11 +148,15 @@ public class TriggerObject extends SchemaObjectBase {
* @param newRow the new row * @param newRow the new row
* @param beforeAction true if this method is called before the operation is * @param beforeAction true if this method is called before the operation is
* applied * applied
* @param rollback when the operation occurred within a rollback
*/ */
public void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction) throws SQLException { public void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException {
if (!rowBased || before != beforeAction) { if (!rowBased || before != beforeAction) {
return; return;
} }
if (rollback && !onRollback) {
return;
}
load(session); load(session);
Object[] oldList; Object[] oldList;
Object[] newList; Object[] newList;
...@@ -201,6 +206,12 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -201,6 +206,12 @@ public class TriggerObject extends SchemaObjectBase {
} }
} }
} }
} catch (SQLException e) {
if (onRollback) {
// ignore
} else {
throw e;
}
} finally { } finally {
session.setScopeIdentity(identity); session.setScopeIdentity(identity);
session.setCommitOrRollbackDisabled(oldDisabled); session.setCommitOrRollbackDisabled(oldDisabled);
...@@ -237,6 +248,10 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -237,6 +248,10 @@ public class TriggerObject extends SchemaObjectBase {
return noWait; return noWait;
} }
public void setOnRollback(boolean onRollback) {
this.onRollback = onRollback;
}
public String getDropSQL() { public String getDropSQL() {
return null; return null;
} }
...@@ -249,7 +264,8 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -249,7 +264,8 @@ public class TriggerObject extends SchemaObjectBase {
} else { } else {
buff.append(" AFTER "); buff.append(" AFTER ");
} }
buff.append(getTypeNameList()).append(" ON ").append(table.getSQL()); buff.append(getTypeNameList());
buff.append(" ON ").append(table.getSQL());
if (rowBased) { if (rowBased) {
buff.append(" FOR EACH ROW"); buff.append(" FOR EACH ROW");
} }
...@@ -280,6 +296,10 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -280,6 +296,10 @@ public class TriggerObject extends SchemaObjectBase {
buff.appendExceptFirst(", "); buff.appendExceptFirst(", ");
buff.append("SELECT"); buff.append("SELECT");
} }
if (onRollback) {
buff.appendExceptFirst(", ");
buff.append("ROLLBACK");
}
return buff.toString(); return buff.toString();
} }
......
...@@ -750,7 +750,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -750,7 +750,7 @@ public abstract class Table extends SchemaObjectBase {
* @param newRow the new data or null for a delete * @param newRow the new data or null for a delete
*/ */
public void fireBeforeRow(Session session, Row oldRow, Row newRow) throws SQLException { public void fireBeforeRow(Session session, Row oldRow, Row newRow) throws SQLException {
fireRow(session, oldRow, newRow, true); fireRow(session, oldRow, newRow, true, false);
fireConstraints(session, oldRow, newRow, true); fireConstraints(session, oldRow, newRow, true);
} }
...@@ -770,16 +770,19 @@ public abstract class Table extends SchemaObjectBase { ...@@ -770,16 +770,19 @@ public abstract class Table extends SchemaObjectBase {
* @param session the session * @param session the session
* @param oldRow the old data or null for an insert * @param oldRow the old data or null for an insert
* @param newRow the new data or null for a delete * @param newRow the new data or null for a delete
* @param rollback when the operation occurred within a rollback
*/ */
public void fireAfterRow(Session session, Row oldRow, Row newRow) throws SQLException { public void fireAfterRow(Session session, Row oldRow, Row newRow, boolean rollback) throws SQLException {
fireRow(session, oldRow, newRow, false); fireRow(session, oldRow, newRow, false, rollback);
fireConstraints(session, oldRow, newRow, false); if (!rollback) {
fireConstraints(session, oldRow, newRow, false);
}
} }
private void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction) throws SQLException { private void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException {
if (triggers != null) { if (triggers != null) {
for (TriggerObject trigger : triggers) { for (TriggerObject trigger : triggers) {
trigger.fireRow(session, oldRow, newRow, beforeAction); trigger.fireRow(session, oldRow, newRow, beforeAction, rollback);
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论