# Test basic syntax with BEFORE and UPDATE.
# NOTE: FOR EACH STATEMENT is the default.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test OR REPLACE syntax.
parse
CREATE OR REPLACE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo();
----
CREATE OR REPLACE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE OR REPLACE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE OR REPLACE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE OR REPLACE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test AFTER, INSERT, and PROCEDURE.
# NOTE: PROCEDURE is a synonym for FUNCTION, and is deprecated.
parse
CREATE TRIGGER foo AFTER INSERT ON abc EXECUTE PROCEDURE foo();
----
CREATE TRIGGER foo AFTER INSERT ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo AFTER INSERT ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo AFTER INSERT ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ AFTER INSERT ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test multiple operators.
parse
CREATE TRIGGER foo BEFORE UPDATE OR INSERT OR DELETE ON abc EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE OR INSERT OR DELETE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE OR INSERT OR DELETE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE OR INSERT OR DELETE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE OR INSERT OR DELETE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test update with target columns
parse
CREATE TRIGGER foo BEFORE UPDATE OF a, b ON abc EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE OF a, b ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE OF a, b ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE OF a, b ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE OF _, _ ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test INSTEAD OF timing.
parse
CREATE TRIGGER foo INSTEAD OF UPDATE ON abc EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo INSTEAD OF UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo INSTEAD OF UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo INSTEAD OF UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ INSTEAD OF UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test TRUNCATE timing.
parse
CREATE TRIGGER foo BEFORE TRUNCATE ON abc EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE TRUNCATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE TRUNCATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE TRUNCATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE TRUNCATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test FOR EACH ROW.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH ROW EXECUTE FUNCTION _() -- identifiers removed

# Test FOR EACH STATEMENT.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test REFERENCING syntax.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc REFERENCING OLD TABLE AS bar EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE ON abc REFERENCING OLD TABLE AS bar FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc REFERENCING OLD TABLE AS bar FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc REFERENCING OLD TABLE AS bar FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ REFERENCING OLD TABLE AS _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test REFERENCING with multiple tables.
parse
CREATE TRIGGER foo AFTER UPDATE ON abc REFERENCING NEW TABLE bar OLD TABLE AS baz
FOR EACH ROW EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo AFTER UPDATE ON abc REFERENCING NEW TABLE AS bar OLD TABLE AS baz FOR EACH ROW EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo AFTER UPDATE ON abc REFERENCING NEW TABLE AS bar OLD TABLE AS baz FOR EACH ROW EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo AFTER UPDATE ON abc REFERENCING NEW TABLE AS bar OLD TABLE AS baz FOR EACH ROW EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ AFTER UPDATE ON _ REFERENCING NEW TABLE AS _ OLD TABLE AS _ FOR EACH ROW EXECUTE FUNCTION _() -- identifiers removed

# Test REFERENCING with OLD ROW.
parse
CREATE TRIGGER foo AFTER DELETE ON abc REFERENCING OLD ROW AS bar EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo AFTER DELETE ON abc REFERENCING OLD ROW AS bar FOR EACH STATEMENT EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo AFTER DELETE ON abc REFERENCING OLD ROW AS bar FOR EACH STATEMENT EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo AFTER DELETE ON abc REFERENCING OLD ROW AS bar FOR EACH STATEMENT EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ AFTER DELETE ON _ REFERENCING OLD ROW AS _ FOR EACH STATEMENT EXECUTE FUNCTION _() -- identifiers removed

# Test the WHEN clause.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT WHEN (1 = 2) EXECUTE FUNCTION foo();
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT WHEN (1 = 2) EXECUTE FUNCTION foo() -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT WHEN ((((1) = (2)))) EXECUTE FUNCTION (foo)() -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT WHEN (_ = _) EXECUTE FUNCTION foo() -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT WHEN (1 = 2) EXECUTE FUNCTION _() -- identifiers removed

# Test function args.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo(1, 2.01, 'foo', "xyz");
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo('1', '2.01', 'foo', 'xyz') -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)('1', '2.01', 'foo', 'xyz') -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo('_', '_', '_', '_') -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _('1', '2.01', 'foo', 'xyz') -- identifiers removed

# Postgres also doesn't allow negative numerical constants.
error
CREATE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo(-1);
----
at or near "-": syntax error
DETAIL: source SQL:
CREATE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo(-1)
                                                             ^
HINT: try \h CREATE TRIGGER

# It's still possible to pass a negative number as a string.
parse
CREATE TRIGGER foo BEFORE UPDATE ON abc EXECUTE FUNCTION foo('-1');
----
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo('-1') -- normalized!
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION (foo)('-1') -- fully parenthesized
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH STATEMENT EXECUTE FUNCTION foo('_') -- literals removed
CREATE TRIGGER _ BEFORE UPDATE ON _ FOR EACH STATEMENT EXECUTE FUNCTION _('-1') -- identifiers removed

# Missing FUNCTION/PROCEDURE keyword.
error
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE foo();
----
at or near "foo": syntax error
DETAIL: source SQL:
CREATE TRIGGER foo BEFORE UPDATE ON abc FOR EACH ROW EXECUTE foo()
                                                             ^
HINT: try \h CREATE TRIGGER

# FOR EACH ROW is in the wrong location.
error
CREATE TRIGGER foo BEFORE UPDATE FOR EACH ROW ON abc EXECUTE FUNCTION foo();
----
at or near "for": syntax error
DETAIL: source SQL:
CREATE TRIGGER foo BEFORE UPDATE FOR EACH ROW ON abc EXECUTE FUNCTION foo()
                                 ^
HINT: try \h CREATE TRIGGER

# Constraint triggers are not supported.
error
CREATE CONSTRAINT TRIGGER AFTER UPDATE ON foo FOR EACH ROW EXECUTE FUNCTION foo();
----
at or near "after": syntax error: unimplemented: this syntax
DETAIL: source SQL:
CREATE CONSTRAINT TRIGGER AFTER UPDATE ON foo FOR EACH ROW EXECUTE FUNCTION foo()
                          ^
HINT: You have attempted to use a feature that is not yet implemented.
See: https://go.crdb.dev/issue-v/28296/
