Skip to content

Commit

Permalink
Fix the case where trigger returns null to skip the row.
Browse files Browse the repository at this point in the history
Per report #41.
  • Loading branch information
umitanuki committed Nov 29, 2012
1 parent 42bf069 commit afb7f62
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 2 deletions.
58 changes: 58 additions & 0 deletions expected/plv8.out
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,64 @@ SELECT * FROM test_tbl;
4 | s4
(3 rows)

-- One more trigger
CREATE FUNCTION test_trigger2() RETURNS trigger AS
$$
var tuple;
switch (TG_OP) {
case "INSERT":
tuple = NEW;
break;
case "UPDATE":
tuple = OLD;
break;
case "DELETE":
tuple = OLD;
break;
default:
return;
}
if (tuple.subject == "skip") {
return null;
}
if (tuple.subject == "modify" && NEW) {
NEW.val = tuple.val * 2;
return NEW;
}
$$
LANGUAGE "plv8";
CREATE TABLE trig_table (subject text, val int);
INSERT INTO trig_table VALUES('skip', 1);
CREATE TRIGGER test_trigger2
BEFORE INSERT OR UPDATE OR DELETE
ON trig_table FOR EACH ROW
EXECUTE PROCEDURE test_trigger2();
INSERT INTO trig_table VALUES
('skip', 1), ('modify', 2), ('noop', 3);
SELECT * FROM trig_table;
subject | val
---------+-----
skip | 1
modify | 4
noop | 3
(3 rows)

UPDATE trig_table SET val = 10;
SELECT * FROM trig_table;
subject | val
---------+-----
skip | 1
modify | 8
noop | 10
(3 rows)

DELETE FROM trig_table;
SELECT * FROM trig_table;
subject | val
---------+-----
skip | 1
(1 row)

-- ERRORS
CREATE FUNCTION syntax_error() RETURNS text AS '@' LANGUAGE plv8;
ERROR: SyntaxError: Unexpected token ILLEGAL
Expand Down
12 changes: 10 additions & 2 deletions plv8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,16 @@ CallTrigger(PG_FUNCTION_ARGS, plv8_exec_env *xenv)
if (newtup.IsEmpty())
throw js_error(try_catch);

if (TRIGGER_FIRED_BY_UPDATE(event) &&
!(newtup->IsUndefined() || newtup->IsNull()))
/*
* If the function specifically returned null, return NULL to
* tell executor to skip the operation. Otherwise, the function
* result is the tuple to be returned.
*/
if (newtup->IsNull() || !TRIGGER_FIRED_FOR_ROW(event))
{
result = PointerGetDatum(NULL);
}
else if (!newtup->IsUndefined())
{
TupleDesc tupdesc = RelationGetDescr(rel);
Converter conv(tupdesc);
Expand Down
42 changes: 42 additions & 0 deletions sql/plv8.sql
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,48 @@ UPDATE test_tbl SET i = 101, s = 'DEF' WHERE i = 1;
DELETE FROM test_tbl WHERE i >= 100;
SELECT * FROM test_tbl;

-- One more trigger
CREATE FUNCTION test_trigger2() RETURNS trigger AS
$$
var tuple;
switch (TG_OP) {
case "INSERT":
tuple = NEW;
break;
case "UPDATE":
tuple = OLD;
break;
case "DELETE":
tuple = OLD;
break;
default:
return;
}
if (tuple.subject == "skip") {
return null;
}
if (tuple.subject == "modify" && NEW) {
NEW.val = tuple.val * 2;
return NEW;
}
$$
LANGUAGE "plv8";

CREATE TABLE trig_table (subject text, val int);
INSERT INTO trig_table VALUES('skip', 1);
CREATE TRIGGER test_trigger2
BEFORE INSERT OR UPDATE OR DELETE
ON trig_table FOR EACH ROW
EXECUTE PROCEDURE test_trigger2();

INSERT INTO trig_table VALUES
('skip', 1), ('modify', 2), ('noop', 3);
SELECT * FROM trig_table;
UPDATE trig_table SET val = 10;
SELECT * FROM trig_table;
DELETE FROM trig_table;
SELECT * FROM trig_table;

-- ERRORS
CREATE FUNCTION syntax_error() RETURNS text AS '@' LANGUAGE plv8;

Expand Down

0 comments on commit afb7f62

Please sign in to comment.