Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
841a5150
Commit
841a5150
authored
Jan 21, 2013
by
Robert Haas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ddl_command_end support for event triggers.
Dimitri Fontaine, with slight changes by me
parent
765cbfdc
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
390 additions
and
152 deletions
+390
-152
doc/src/sgml/event-trigger.sgml
doc/src/sgml/event-trigger.sgml
+91
-2
src/backend/commands/event_trigger.c
src/backend/commands/event_trigger.c
+135
-25
src/backend/tcop/utility.c
src/backend/tcop/utility.c
+150
-123
src/backend/utils/cache/evtcache.c
src/backend/utils/cache/evtcache.c
+2
-0
src/include/commands/event_trigger.h
src/include/commands/event_trigger.h
+1
-0
src/include/utils/evtcache.h
src/include/utils/evtcache.h
+2
-1
src/test/regress/expected/event_trigger.out
src/test/regress/expected/event_trigger.out
+5
-1
src/test/regress/sql/event_trigger.sql
src/test/regress/sql/event_trigger.sql
+4
-0
No files found.
doc/src/sgml/event-trigger.sgml
View file @
841a5150
...
@@ -27,8 +27,9 @@
...
@@ -27,8 +27,9 @@
<para>
<para>
An event trigger fires whenever the event with which it is associated
An event trigger fires whenever the event with which it is associated
occurs in the database in which it is defined. Currently, the only
occurs in the database in which it is defined. Currently, the only
supported event is <literal>ddl_command_start</>. Support for
supported events are <literal>ddl_command_start</>
additional events may be added in future releases.
and <literal>ddl_command_end</>. Support for additional events may be
added in future releases.
</para>
</para>
<para>
<para>
...
@@ -43,6 +44,13 @@
...
@@ -43,6 +44,13 @@
<literal>CREATE TABLE AS</literal>.
<literal>CREATE TABLE AS</literal>.
</para>
</para>
<para>
The <literal>ddl_command_end</> event occurs just before returning
control from the execution of a <literal>CREATE</>, <literal>ALTER</>,
or <literal>DROP</> commmand. It shares the same exceptions as
the <literal>ddl_command_start</> event.
</para>
<para>
<para>
For a complete list of commands supported by the event trigger mechanism,
For a complete list of commands supported by the event trigger mechanism,
see <xref linkend="event-trigger-matrix">.
see <xref linkend="event-trigger-matrix">.
...
@@ -84,328 +92,409 @@
...
@@ -84,328 +92,409 @@
<row>
<row>
<entry>command tag</entry>
<entry>command tag</entry>
<entry><literal>ddl_command_start</literal></entry>
<entry><literal>ddl_command_start</literal></entry>
<entry><literal>ddl_command_end</literal></entry>
</row>
</row>
</thead>
</thead>
<tbody>
<tbody>
<row>
<row>
<entry align="left"><literal>ALTER AGGREGATE</literal></entry>
<entry align="left"><literal>ALTER AGGREGATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER COLLATION</literal></entry>
<entry align="left"><literal>ALTER COLLATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER CONVERSION</literal></entry>
<entry align="left"><literal>ALTER CONVERSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER DOMAIN</literal></entry>
<entry align="left"><literal>ALTER DOMAIN</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER EXTENSION</literal></entry>
<entry align="left"><literal>ALTER EXTENSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER FOREIGN DATA WRAPPER</literal></entry>
<entry align="left"><literal>ALTER FOREIGN DATA WRAPPER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER FOREIGN TABLE</literal></entry>
<entry align="left"><literal>ALTER FOREIGN TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER FUNCTION</literal></entry>
<entry align="left"><literal>ALTER FUNCTION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER LANGUAGE</literal></entry>
<entry align="left"><literal>ALTER LANGUAGE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER OPERATOR</literal></entry>
<entry align="left"><literal>ALTER OPERATOR</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER OPERATOR CLASS</literal></entry>
<entry align="left"><literal>ALTER OPERATOR CLASS</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER OPERATOR FAMILY</literal></entry>
<entry align="left"><literal>ALTER OPERATOR FAMILY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER SCHEMA</literal></entry>
<entry align="left"><literal>ALTER SCHEMA</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER SEQUENCE</literal></entry>
<entry align="left"><literal>ALTER SEQUENCE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER SERVER</literal></entry>
<entry align="left"><literal>ALTER SERVER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TABLE</literal></entry>
<entry align="left"><literal>ALTER TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="left"><literal>ALTER TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TEXT SEARCH DICTIONARY</literal></entry>
<entry align="left"><literal>ALTER TEXT SEARCH DICTIONARY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TEXT SEARCH PARSER</literal></entry>
<entry align="left"><literal>ALTER TEXT SEARCH PARSER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TEXT SEARCH TEMPLATE</literal></entry>
<entry align="left"><literal>ALTER TEXT SEARCH TEMPLATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TRIGGER</literal></entry>
<entry align="left"><literal>ALTER TRIGGER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER TYPE</literal></entry>
<entry align="left"><literal>ALTER TYPE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER USER MAPPING</literal></entry>
<entry align="left"><literal>ALTER USER MAPPING</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>ALTER VIEW</literal></entry>
<entry align="left"><literal>ALTER VIEW</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE AGGREGATE</literal></entry>
<entry align="left"><literal>CREATE AGGREGATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE CAST</literal></entry>
<entry align="left"><literal>CREATE CAST</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE COLLATION</literal></entry>
<entry align="left"><literal>CREATE COLLATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE CONVERSION</literal></entry>
<entry align="left"><literal>CREATE CONVERSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE DOMAIN</literal></entry>
<entry align="left"><literal>CREATE DOMAIN</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE EXTENSION</literal></entry>
<entry align="left"><literal>CREATE EXTENSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE FOREIGN DATA WRAPPER</literal></entry>
<entry align="left"><literal>CREATE FOREIGN DATA WRAPPER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE FOREIGN TABLE</literal></entry>
<entry align="left"><literal>CREATE FOREIGN TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE FUNCTION</literal></entry>
<entry align="left"><literal>CREATE FUNCTION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE INDEX</literal></entry>
<entry align="left"><literal>CREATE INDEX</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE LANGUAGE</literal></entry>
<entry align="left"><literal>CREATE LANGUAGE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE OPERATOR</literal></entry>
<entry align="left"><literal>CREATE OPERATOR</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE OPERATOR CLASS</literal></entry>
<entry align="left"><literal>CREATE OPERATOR CLASS</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE OPERATOR FAMILY</literal></entry>
<entry align="left"><literal>CREATE OPERATOR FAMILY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE RULE</literal></entry>
<entry align="left"><literal>CREATE RULE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE SCHEMA</literal></entry>
<entry align="left"><literal>CREATE SCHEMA</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE SEQUENCE</literal></entry>
<entry align="left"><literal>CREATE SEQUENCE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE SERVER</literal></entry>
<entry align="left"><literal>CREATE SERVER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TABLE</literal></entry>
<entry align="left"><literal>CREATE TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TABLE AS</literal></entry>
<entry align="left"><literal>CREATE TABLE AS</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="left"><literal>CREATE TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TEXT SEARCH DICTIONARY</literal></entry>
<entry align="left"><literal>CREATE TEXT SEARCH DICTIONARY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TEXT SEARCH PARSER</literal></entry>
<entry align="left"><literal>CREATE TEXT SEARCH PARSER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TEXT SEARCH TEMPLATE</literal></entry>
<entry align="left"><literal>CREATE TEXT SEARCH TEMPLATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TRIGGER</literal></entry>
<entry align="left"><literal>CREATE TRIGGER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE TYPE</literal></entry>
<entry align="left"><literal>CREATE TYPE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE USER MAPPING</literal></entry>
<entry align="left"><literal>CREATE USER MAPPING</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>CREATE VIEW</literal></entry>
<entry align="left"><literal>CREATE VIEW</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP AGGREGATE</literal></entry>
<entry align="left"><literal>DROP AGGREGATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP CAST</literal></entry>
<entry align="left"><literal>DROP CAST</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP COLLATION</literal></entry>
<entry align="left"><literal>DROP COLLATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP CONVERSION</literal></entry>
<entry align="left"><literal>DROP CONVERSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP DOMAIN</literal></entry>
<entry align="left"><literal>DROP DOMAIN</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP EXTENSION</literal></entry>
<entry align="left"><literal>DROP EXTENSION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP FOREIGN DATA WRAPPER</literal></entry>
<entry align="left"><literal>DROP FOREIGN DATA WRAPPER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP FOREIGN TABLE</literal></entry>
<entry align="left"><literal>DROP FOREIGN TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP FUNCTION</literal></entry>
<entry align="left"><literal>DROP FUNCTION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP INDEX</literal></entry>
<entry align="left"><literal>DROP INDEX</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP LANGUAGE</literal></entry>
<entry align="left"><literal>DROP LANGUAGE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP OPERATOR</literal></entry>
<entry align="left"><literal>DROP OPERATOR</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP OPERATOR CLASS</literal></entry>
<entry align="left"><literal>DROP OPERATOR CLASS</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP OPERATOR FAMILY</literal></entry>
<entry align="left"><literal>DROP OPERATOR FAMILY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP RULE</literal></entry>
<entry align="left"><literal>DROP RULE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP SCHEMA</literal></entry>
<entry align="left"><literal>DROP SCHEMA</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP SEQUENCE</literal></entry>
<entry align="left"><literal>DROP SEQUENCE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP SERVER</literal></entry>
<entry align="left"><literal>DROP SERVER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TABLE</literal></entry>
<entry align="left"><literal>DROP TABLE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="left"><literal>DROP TEXT SEARCH CONFIGURATION</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TEXT SEARCH DICTIONARY</literal></entry>
<entry align="left"><literal>DROP TEXT SEARCH DICTIONARY</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TEXT SEARCH PARSER</literal></entry>
<entry align="left"><literal>DROP TEXT SEARCH PARSER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TEXT SEARCH TEMPLATE</literal></entry>
<entry align="left"><literal>DROP TEXT SEARCH TEMPLATE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TRIGGER</literal></entry>
<entry align="left"><literal>DROP TRIGGER</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP TYPE</literal></entry>
<entry align="left"><literal>DROP TYPE</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP USER MAPPING</literal></entry>
<entry align="left"><literal>DROP USER MAPPING</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>DROP VIEW</literal></entry>
<entry align="left"><literal>DROP VIEW</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
<row>
<row>
<entry align="left"><literal>SELECT INTO</literal></entry>
<entry align="left"><literal>SELECT INTO</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
<entry align="center"><literal>X</literal></entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
...
...
src/backend/commands/event_trigger.c
View file @
841a5150
...
@@ -125,7 +125,8 @@ CreateEventTrigger(CreateEventTrigStmt *stmt)
...
@@ -125,7 +125,8 @@ CreateEventTrigger(CreateEventTrigStmt *stmt)
errhint
(
"Must be superuser to create an event trigger."
)));
errhint
(
"Must be superuser to create an event trigger."
)));
/* Validate event name. */
/* Validate event name. */
if
(
strcmp
(
stmt
->
eventname
,
"ddl_command_start"
)
!=
0
)
if
(
strcmp
(
stmt
->
eventname
,
"ddl_command_start"
)
!=
0
&&
strcmp
(
stmt
->
eventname
,
"ddl_command_end"
)
!=
0
)
ereport
(
ERROR
,
ereport
(
ERROR
,
(
errcode
(
ERRCODE_SYNTAX_ERROR
),
(
errcode
(
ERRCODE_SYNTAX_ERROR
),
errmsg
(
"unrecognized event name
\"
%s
\"
"
,
errmsg
(
"unrecognized event name
\"
%s
\"
"
,
...
@@ -526,6 +527,39 @@ get_event_trigger_oid(const char *trigname, bool missing_ok)
...
@@ -526,6 +527,39 @@ get_event_trigger_oid(const char *trigname, bool missing_ok)
return
oid
;
return
oid
;
}
}
/*
* Return true when we want to fire given Event Trigger and false otherwise,
* filtering on the session replication role and the event trigger registered
* tags matching.
*/
static
bool
filter_event_trigger
(
const
char
**
tag
,
EventTriggerCacheItem
*
item
)
{
/*
* Filter by session replication role, knowing that we never see disabled
* items down here.
*/
if
(
SessionReplicationRole
==
SESSION_REPLICATION_ROLE_REPLICA
)
{
if
(
item
->
enabled
==
TRIGGER_FIRES_ON_ORIGIN
)
return
false
;
}
else
{
if
(
item
->
enabled
==
TRIGGER_FIRES_ON_REPLICA
)
return
false
;
}
/* Filter by tags, if any were specified. */
if
(
item
->
ntags
!=
0
&&
bsearch
(
&
tag
,
item
->
tag
,
item
->
ntags
,
sizeof
(
char
*
),
pg_qsort_strcmp
)
==
NULL
)
return
false
;
/* if we reach that point, we're not filtering out this item */
return
true
;
}
/*
/*
* Fire ddl_command_start triggers.
* Fire ddl_command_start triggers.
*/
*/
...
@@ -601,34 +635,105 @@ EventTriggerDDLCommandStart(Node *parsetree)
...
@@ -601,34 +635,105 @@ EventTriggerDDLCommandStart(Node *parsetree)
{
{
EventTriggerCacheItem
*
item
=
lfirst
(
lc
);
EventTriggerCacheItem
*
item
=
lfirst
(
lc
);
/* Filter by session replication role. */
if
(
filter_event_trigger
(
&
tag
,
item
))
if
(
SessionReplicationRole
==
SESSION_REPLICATION_ROLE_REPLICA
)
{
if
(
item
->
enabled
==
TRIGGER_FIRES_ON_ORIGIN
)
continue
;
}
else
{
{
if
(
item
->
enabled
==
TRIGGER_FIRES_ON_REPLICA
)
/* We must plan to fire this trigger. */
continue
;
runlist
=
lappend_oid
(
runlist
,
item
->
fnoid
)
;
}
}
}
/* Construct event trigger data. */
trigdata
.
type
=
T_EventTriggerData
;
trigdata
.
event
=
"ddl_command_start"
;
trigdata
.
parsetree
=
parsetree
;
trigdata
.
tag
=
tag
;
/* Run the triggers. */
EventTriggerInvoke
(
runlist
,
&
trigdata
);
/* Cleanup. */
list_free
(
runlist
);
/*
* Make sure anything the event triggers did will be visible to
* the main command.
*/
CommandCounterIncrement
();
}
/*
* Fire ddl_command_end triggers.
*/
void
EventTriggerDDLCommandEnd
(
Node
*
parsetree
)
{
List
*
cachelist
;
List
*
runlist
=
NIL
;
ListCell
*
lc
;
const
char
*
tag
;
EventTriggerData
trigdata
;
/*
* See EventTriggerDDLCommandStart for a discussion about why event
* triggers are disabled in single user mode.
*/
if
(
!
IsUnderPostmaster
)
return
;
/* Filter by tags, if any were specified. */
/*
if
(
item
->
ntags
!=
0
&&
bsearch
(
&
tag
,
item
->
tag
,
* See EventTriggerDDLCommandStart for a discussion about why this check is
item
->
ntags
,
sizeof
(
char
*
),
* important.
pg_qsort_strcmp
)
==
NULL
)
*
continue
;
*/
#ifdef USE_ASSERT_CHECKING
if
(
assert_enabled
)
{
const
char
*
dbgtag
;
/* We must plan to fire this trigger. */
dbgtag
=
CreateCommandTag
(
parsetree
);
runlist
=
lappend_oid
(
runlist
,
item
->
fnoid
);
if
(
check_ddl_tag
(
dbgtag
)
!=
EVENT_TRIGGER_COMMAND_TAG_OK
)
elog
(
ERROR
,
"unexpected command tag
\"
%s
\"
"
,
dbgtag
);
}
#endif
/* Use cache to find triggers for this event; fast exit if none. */
cachelist
=
EventCacheLookup
(
EVT_DDLCommandEnd
);
if
(
cachelist
==
NULL
)
return
;
/* Get the command tag. */
tag
=
CreateCommandTag
(
parsetree
);
/*
* Filter list of event triggers by command tag, and copy them into
* our memory context. Once we start running the command trigers, or
* indeed once we do anything at all that touches the catalogs, an
* invalidation might leave cachelist pointing at garbage, so we must
* do this before we can do much else.
*/
foreach
(
lc
,
cachelist
)
{
EventTriggerCacheItem
*
item
=
lfirst
(
lc
);
if
(
filter_event_trigger
(
&
tag
,
item
))
{
/* We must plan to fire this trigger. */
runlist
=
lappend_oid
(
runlist
,
item
->
fnoid
);
}
}
}
/* Construct event trigger data. */
/* Construct event trigger data. */
trigdata
.
type
=
T_EventTriggerData
;
trigdata
.
type
=
T_EventTriggerData
;
trigdata
.
event
=
"ddl_command_
start
"
;
trigdata
.
event
=
"ddl_command_
end
"
;
trigdata
.
parsetree
=
parsetree
;
trigdata
.
parsetree
=
parsetree
;
trigdata
.
tag
=
tag
;
trigdata
.
tag
=
tag
;
/*
* Make sure anything the main command did will be visible to the
* event triggers.
*/
CommandCounterIncrement
();
/* Run the triggers. */
/* Run the triggers. */
EventTriggerInvoke
(
runlist
,
&
trigdata
);
EventTriggerInvoke
(
runlist
,
&
trigdata
);
...
@@ -645,6 +750,7 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
...
@@ -645,6 +750,7 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
MemoryContext
context
;
MemoryContext
context
;
MemoryContext
oldcontext
;
MemoryContext
oldcontext
;
ListCell
*
lc
;
ListCell
*
lc
;
bool
first
=
true
;
/*
/*
* Let's evaluate event triggers in their own memory context, so
* Let's evaluate event triggers in their own memory context, so
...
@@ -665,6 +771,17 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
...
@@ -665,6 +771,17 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
FunctionCallInfoData
fcinfo
;
FunctionCallInfoData
fcinfo
;
PgStat_FunctionCallUsage
fcusage
;
PgStat_FunctionCallUsage
fcusage
;
/*
* We want each event trigger to be able to see the results of
* the previous event trigger's action. Caller is responsible
* for any command-counter increment that is needed between the
* event trigger and anything else in the transaction.
*/
if
(
first
)
first
=
false
;
else
CommandCounterIncrement
();
/* Look up the function */
/* Look up the function */
fmgr_info
(
fnoid
,
&
flinfo
);
fmgr_info
(
fnoid
,
&
flinfo
);
...
@@ -677,13 +794,6 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
...
@@ -677,13 +794,6 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata)
/* Reclaim memory. */
/* Reclaim memory. */
MemoryContextReset
(
context
);
MemoryContextReset
(
context
);
/*
* We want each event trigger to be able to see the results of
* the previous event trigger's action, and we want the main
* command to be able to see the results of all event triggers.
*/
CommandCounterIncrement
();
}
}
/* Restore old memory context and delete the temporary one. */
/* Restore old memory context and delete the temporary one. */
...
...
src/backend/tcop/utility.c
View file @
841a5150
...
@@ -340,6 +340,34 @@ ProcessUtility(Node *parsetree,
...
@@ -340,6 +340,34 @@ ProcessUtility(Node *parsetree,
dest
,
completionTag
,
context
);
dest
,
completionTag
,
context
);
}
}
#define InvokeDDLCommandEventTriggers(parsetree, fncall) \
do { \
if (isCompleteQuery) \
{ \
EventTriggerDDLCommandStart(parsetree); \
} \
fncall; \
if (isCompleteQuery) \
{ \
EventTriggerDDLCommandEnd(parsetree); \
} \
} while (0)
#define InvokeDDLCommandEventTriggersIfSupported(parsetree, fncall, objtype) \
do { \
bool _supported = EventTriggerSupportsObjectType(objtype); \
\
if (_supported) \
{ \
EventTriggerDDLCommandStart(parsetree); \
} \
fncall; \
if (_supported) \
{ \
EventTriggerDDLCommandEnd(parsetree); \
} \
} while (0)
void
void
standard_ProcessUtility
(
Node
*
parsetree
,
standard_ProcessUtility
(
Node
*
parsetree
,
const
char
*
queryString
,
const
char
*
queryString
,
...
@@ -507,10 +535,10 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -507,10 +535,10 @@ standard_ProcessUtility(Node *parsetree,
* relation and attribute manipulation
* relation and attribute manipulation
*/
*/
case
T_CreateSchemaStmt
:
case
T_CreateSchemaStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateSchemaCommand
((
CreateSchemaStmt
*
)
parsetree
,
CreateSchemaCommand
((
CreateSchemaStmt
*
)
parsetree
,
queryString
);
queryString
)
);
break
;
break
;
case
T_CreateStmt
:
case
T_CreateStmt
:
...
@@ -583,6 +611,9 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -583,6 +611,9 @@ standard_ProcessUtility(Node *parsetree,
if
(
lnext
(
l
)
!=
NULL
)
if
(
lnext
(
l
)
!=
NULL
)
CommandCounterIncrement
();
CommandCounterIncrement
();
}
}
if
(
isCompleteQuery
)
EventTriggerDDLCommandEnd
(
parsetree
);
}
}
break
;
break
;
...
@@ -604,63 +635,63 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -604,63 +635,63 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_CreateExtensionStmt
:
case
T_CreateExtensionStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateExtension
((
CreateExtensionStmt
*
)
parsetree
);
CreateExtension
((
CreateExtensionStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterExtensionStmt
:
case
T_AlterExtensionStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
ExecAlterExtensionStmt
((
AlterExtensionStmt
*
)
parsetree
);
ExecAlterExtensionStmt
((
AlterExtensionStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterExtensionContentsStmt
:
case
T_AlterExtensionContentsStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
ExecAlterExtensionContentsStmt
((
AlterExtensionContentsStmt
*
)
parsetree
);
ExecAlterExtensionContentsStmt
((
AlterExtensionContentsStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateFdwStmt
:
case
T_CreateFdwStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateForeignDataWrapper
((
CreateFdwStmt
*
)
parsetree
);
CreateForeignDataWrapper
((
CreateFdwStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterFdwStmt
:
case
T_AlterFdwStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterForeignDataWrapper
((
AlterFdwStmt
*
)
parsetree
);
AlterForeignDataWrapper
((
AlterFdwStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateForeignServerStmt
:
case
T_CreateForeignServerStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateForeignServer
((
CreateForeignServerStmt
*
)
parsetree
);
CreateForeignServer
((
CreateForeignServerStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterForeignServerStmt
:
case
T_AlterForeignServerStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterForeignServer
((
AlterForeignServerStmt
*
)
parsetree
);
AlterForeignServer
((
AlterForeignServerStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateUserMappingStmt
:
case
T_CreateUserMappingStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateUserMapping
((
CreateUserMappingStmt
*
)
parsetree
);
CreateUserMapping
((
CreateUserMappingStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterUserMappingStmt
:
case
T_AlterUserMappingStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterUserMapping
((
AlterUserMappingStmt
*
)
parsetree
);
AlterUserMapping
((
AlterUserMappingStmt
*
)
parsetree
)
);
break
;
break
;
case
T_DropUserMappingStmt
:
case
T_DropUserMappingStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
RemoveUserMapping
((
DropUserMappingStmt
*
)
parsetree
);
RemoveUserMapping
((
DropUserMappingStmt
*
)
parsetree
)
);
break
;
break
;
case
T_DropStmt
:
case
T_DropStmt
:
...
@@ -689,6 +720,11 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -689,6 +720,11 @@ standard_ProcessUtility(Node *parsetree,
RemoveObjects
((
DropStmt
*
)
parsetree
);
RemoveObjects
((
DropStmt
*
)
parsetree
);
break
;
break
;
}
}
if
(
isCompleteQuery
&&
EventTriggerSupportsObjectType
(
stmt
->
removeType
))
EventTriggerDDLCommandEnd
(
parsetree
);
break
;
break
;
}
}
...
@@ -736,37 +772,29 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -736,37 +772,29 @@ standard_ProcessUtility(Node *parsetree,
*/
*/
case
T_RenameStmt
:
case
T_RenameStmt
:
{
{
RenameStmt
*
stmt
;
RenameStmt
*
stmt
=
(
RenameStmt
*
)
parsetree
;
stmt
=
(
RenameStmt
*
)
parsetree
;
InvokeDDLCommandEventTriggersIfSupported
(
parsetree
,
if
(
isCompleteQuery
&&
ExecRenameStmt
(
stmt
),
EventTriggerSupportsObjectType
(
stmt
->
renameType
))
stmt
->
renameType
);
EventTriggerDDLCommandStart
(
parsetree
);
ExecRenameStmt
(
stmt
);
break
;
break
;
}
}
case
T_AlterObjectSchemaStmt
:
case
T_AlterObjectSchemaStmt
:
{
{
AlterObjectSchemaStmt
*
stmt
;
AlterObjectSchemaStmt
*
stmt
=
(
AlterObjectSchemaStmt
*
)
parsetree
;
InvokeDDLCommandEventTriggersIfSupported
(
parsetree
,
stmt
=
(
AlterObjectSchemaStmt
*
)
parsetree
;
ExecAlterObjectSchemaStmt
(
stmt
),
if
(
isCompleteQuery
&&
stmt
->
objectType
);
EventTriggerSupportsObjectType
(
stmt
->
objectType
))
EventTriggerDDLCommandStart
(
parsetree
);
ExecAlterObjectSchemaStmt
(
stmt
);
break
;
break
;
}
}
case
T_AlterOwnerStmt
:
case
T_AlterOwnerStmt
:
{
{
AlterOwnerStmt
*
stmt
;
AlterOwnerStmt
*
stmt
=
(
AlterOwnerStmt
*
)
parsetree
;
InvokeDDLCommandEventTriggersIfSupported
(
parsetree
,
stmt
=
(
AlterOwnerStmt
*
)
parsetree
;
ExecAlterOwnerStmt
(
stmt
),
if
(
isCompleteQuery
&&
stmt
->
objectType
);
EventTriggerSupportsObjectType
(
stmt
->
objectType
))
EventTriggerDDLCommandStart
(
parsetree
);
ExecAlterOwnerStmt
(
stmt
);
break
;
break
;
}
}
...
@@ -889,9 +917,9 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -889,9 +917,9 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_AlterDefaultPrivilegesStmt
:
case
T_AlterDefaultPrivilegesStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
ExecAlterDefaultPrivilegesStmt
((
AlterDefaultPrivilegesStmt
*
)
parsetree
);
ExecAlterDefaultPrivilegesStmt
((
AlterDefaultPrivilegesStmt
*
)
parsetree
)
);
break
;
break
;
/*
/*
...
@@ -950,47 +978,46 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -950,47 +978,46 @@ standard_ProcessUtility(Node *parsetree,
{
{
CompositeTypeStmt
*
stmt
=
(
CompositeTypeStmt
*
)
parsetree
;
CompositeTypeStmt
*
stmt
=
(
CompositeTypeStmt
*
)
parsetree
;
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineCompositeType
(
stmt
->
typevar
,
stmt
->
coldeflist
));
DefineCompositeType
(
stmt
->
typevar
,
stmt
->
coldeflist
);
}
}
break
;
break
;
case
T_CreateEnumStmt
:
/* CREATE TYPE AS ENUM */
case
T_CreateEnumStmt
:
/* CREATE TYPE AS ENUM */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineEnum
((
CreateEnumStmt
*
)
parsetree
);
DefineEnum
((
CreateEnumStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateRangeStmt
:
/* CREATE TYPE AS RANGE */
case
T_CreateRangeStmt
:
/* CREATE TYPE AS RANGE */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineRange
((
CreateRangeStmt
*
)
parsetree
);
DefineRange
((
CreateRangeStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterEnumStmt
:
/* ALTER TYPE (enum) */
case
T_AlterEnumStmt
:
/* ALTER TYPE (enum) */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterEnum
((
AlterEnumStmt
*
)
parsetree
,
isTopLevel
);
AlterEnum
((
AlterEnumStmt
*
)
parsetree
,
isTopLevel
)
);
break
;
break
;
case
T_ViewStmt
:
/* CREATE VIEW */
case
T_ViewStmt
:
/* CREATE VIEW */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineView
((
ViewStmt
*
)
parsetree
,
queryString
);
DefineView
((
ViewStmt
*
)
parsetree
,
queryString
)
);
break
;
break
;
case
T_CreateFunctionStmt
:
/* CREATE FUNCTION */
case
T_CreateFunctionStmt
:
/* CREATE FUNCTION */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateFunction
((
CreateFunctionStmt
*
)
parsetree
,
queryString
);
CreateFunction
((
CreateFunctionStmt
*
)
parsetree
,
queryString
)
);
break
;
break
;
case
T_AlterFunctionStmt
:
/* ALTER FUNCTION */
case
T_AlterFunctionStmt
:
/* ALTER FUNCTION */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterFunction
((
AlterFunctionStmt
*
)
parsetree
);
AlterFunction
((
AlterFunctionStmt
*
)
parsetree
)
);
break
;
break
;
case
T_IndexStmt
:
/* CREATE INDEX */
case
T_IndexStmt
:
/* CREATE INDEX */
...
@@ -1019,21 +1046,21 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -1019,21 +1046,21 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_RuleStmt
:
/* CREATE RULE */
case
T_RuleStmt
:
/* CREATE RULE */
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineRule
((
RuleStmt
*
)
parsetree
,
queryString
);
DefineRule
((
RuleStmt
*
)
parsetree
,
queryString
)
);
break
;
break
;
case
T_CreateSeqStmt
:
case
T_CreateSeqStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineSequence
((
CreateSeqStmt
*
)
parsetree
);
DefineSequence
((
CreateSeqStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterSeqStmt
:
case
T_AlterSeqStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterSequence
((
AlterSeqStmt
*
)
parsetree
);
AlterSequence
((
AlterSeqStmt
*
)
parsetree
)
);
break
;
break
;
case
T_DoStmt
:
case
T_DoStmt
:
...
@@ -1131,10 +1158,10 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -1131,10 +1158,10 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_CreateTableAsStmt
:
case
T_CreateTableAsStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
ExecCreateTableAs
((
CreateTableAsStmt
*
)
parsetree
,
ExecCreateTableAs
((
CreateTableAsStmt
*
)
parsetree
,
queryString
,
params
,
completionTag
);
queryString
,
params
,
completionTag
)
);
break
;
break
;
case
T_VariableSetStmt
:
case
T_VariableSetStmt
:
...
@@ -1156,10 +1183,10 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -1156,10 +1183,10 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_CreateTrigStmt
:
case
T_CreateTrigStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
(
void
)
CreateTrigger
((
CreateTrigStmt
*
)
parsetree
,
queryString
,
(
void
)
CreateTrigger
((
CreateTrigStmt
*
)
parsetree
,
queryString
,
InvalidOid
,
InvalidOid
,
false
);
InvalidOid
,
InvalidOid
,
false
)
);
break
;
break
;
case
T_CreateEventTrigStmt
:
case
T_CreateEventTrigStmt
:
...
@@ -1173,18 +1200,18 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -1173,18 +1200,18 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_CreatePLangStmt
:
case
T_CreatePLangStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateProceduralLanguage
((
CreatePLangStmt
*
)
parsetree
);
CreateProceduralLanguage
((
CreatePLangStmt
*
)
parsetree
)
);
break
;
break
;
/*
/*
* ******************************** DOMAIN statements ****
* ******************************** DOMAIN statements ****
*/
*/
case
T_CreateDomainStmt
:
case
T_CreateDomainStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineDomain
((
CreateDomainStmt
*
)
parsetree
);
DefineDomain
((
CreateDomainStmt
*
)
parsetree
)
);
break
;
break
;
/*
/*
...
@@ -1288,45 +1315,45 @@ standard_ProcessUtility(Node *parsetree,
...
@@ -1288,45 +1315,45 @@ standard_ProcessUtility(Node *parsetree,
break
;
break
;
case
T_CreateConversionStmt
:
case
T_CreateConversionStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateConversionCommand
((
CreateConversionStmt
*
)
parsetree
);
CreateConversionCommand
((
CreateConversionStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateCastStmt
:
case
T_CreateCastStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
CreateCast
((
CreateCastStmt
*
)
parsetree
);
CreateCast
((
CreateCastStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateOpClassStmt
:
case
T_CreateOpClassStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineOpClass
((
CreateOpClassStmt
*
)
parsetree
);
DefineOpClass
((
CreateOpClassStmt
*
)
parsetree
)
);
break
;
break
;
case
T_CreateOpFamilyStmt
:
case
T_CreateOpFamilyStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
DefineOpFamily
((
CreateOpFamilyStmt
*
)
parsetree
);
DefineOpFamily
((
CreateOpFamilyStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterOpFamilyStmt
:
case
T_AlterOpFamilyStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterOpFamily
((
AlterOpFamilyStmt
*
)
parsetree
);
AlterOpFamily
((
AlterOpFamilyStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterTSDictionaryStmt
:
case
T_AlterTSDictionaryStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterTSDictionary
((
AlterTSDictionaryStmt
*
)
parsetree
);
AlterTSDictionary
((
AlterTSDictionaryStmt
*
)
parsetree
)
);
break
;
break
;
case
T_AlterTSConfigurationStmt
:
case
T_AlterTSConfigurationStmt
:
if
(
isCompleteQuery
)
InvokeDDLCommandEventTriggers
(
EventTriggerDDLCommandStart
(
parsetree
);
parsetree
,
AlterTSConfiguration
((
AlterTSConfigurationStmt
*
)
parsetree
);
AlterTSConfiguration
((
AlterTSConfigurationStmt
*
)
parsetree
)
);
break
;
break
;
default:
default:
...
...
src/backend/utils/cache/evtcache.c
View file @
841a5150
...
@@ -167,6 +167,8 @@ BuildEventTriggerCache(void)
...
@@ -167,6 +167,8 @@ BuildEventTriggerCache(void)
evtevent
=
NameStr
(
form
->
evtevent
);
evtevent
=
NameStr
(
form
->
evtevent
);
if
(
strcmp
(
evtevent
,
"ddl_command_start"
)
==
0
)
if
(
strcmp
(
evtevent
,
"ddl_command_start"
)
==
0
)
event
=
EVT_DDLCommandStart
;
event
=
EVT_DDLCommandStart
;
else
if
(
strcmp
(
evtevent
,
"ddl_command_end"
)
==
0
)
event
=
EVT_DDLCommandEnd
;
else
else
continue
;
continue
;
...
...
src/include/commands/event_trigger.h
View file @
841a5150
...
@@ -41,5 +41,6 @@ extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId);
...
@@ -41,5 +41,6 @@ extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId);
extern
bool
EventTriggerSupportsObjectType
(
ObjectType
obtype
);
extern
bool
EventTriggerSupportsObjectType
(
ObjectType
obtype
);
extern
void
EventTriggerDDLCommandStart
(
Node
*
parsetree
);
extern
void
EventTriggerDDLCommandStart
(
Node
*
parsetree
);
extern
void
EventTriggerDDLCommandEnd
(
Node
*
parsetree
);
#endif
/* EVENT_TRIGGER_H */
#endif
/* EVENT_TRIGGER_H */
src/include/utils/evtcache.h
View file @
841a5150
...
@@ -18,7 +18,8 @@
...
@@ -18,7 +18,8 @@
typedef
enum
typedef
enum
{
{
EVT_DDLCommandStart
EVT_DDLCommandStart
,
EVT_DDLCommandEnd
}
EventTriggerEvent
;
}
EventTriggerEvent
;
typedef
struct
typedef
struct
...
...
src/test/regress/expected/event_trigger.out
View file @
841a5150
...
@@ -16,6 +16,8 @@ ERROR: unrecognized event name "elephant_bootstrap"
...
@@ -16,6 +16,8 @@ ERROR: unrecognized event name "elephant_bootstrap"
-- OK
-- OK
create event trigger regress_event_trigger on ddl_command_start
create event trigger regress_event_trigger on ddl_command_start
execute procedure test_event_trigger();
execute procedure test_event_trigger();
create event trigger regress_event_trigger_end on ddl_command_end
execute procedure test_event_trigger();
-- should fail, food is not a valid filter variable
-- should fail, food is not a valid filter variable
create event trigger regress_event_trigger2 on ddl_command_start
create event trigger regress_event_trigger2 on ddl_command_start
when food in ('sandwhich')
when food in ('sandwhich')
...
@@ -65,9 +67,10 @@ alter event trigger regress_event_trigger enable;
...
@@ -65,9 +67,10 @@ alter event trigger regress_event_trigger enable;
alter event trigger regress_event_trigger disable;
alter event trigger regress_event_trigger disable;
-- regress_event_trigger2 should fire, but not regress_event_trigger
-- regress_event_trigger2 should fire, but not regress_event_trigger
create table event_trigger_fire1 (a int);
create table event_trigger_fire1 (a int);
NOTICE: test_event_trigger: ddl_command_
start
CREATE TABLE
NOTICE: test_event_trigger: ddl_command_
end
CREATE TABLE
-- but nothing should fire here
-- but nothing should fire here
drop table event_trigger_fire1;
drop table event_trigger_fire1;
NOTICE: test_event_trigger: ddl_command_end DROP TABLE
-- alter owner to non-superuser should fail
-- alter owner to non-superuser should fail
alter event trigger regress_event_trigger owner to regression_bob;
alter event trigger regress_event_trigger owner to regression_bob;
ERROR: permission denied to change owner of event trigger "regress_event_trigger"
ERROR: permission denied to change owner of event trigger "regress_event_trigger"
...
@@ -92,5 +95,6 @@ drop event trigger if exists regress_event_trigger2;
...
@@ -92,5 +95,6 @@ drop event trigger if exists regress_event_trigger2;
drop event trigger if exists regress_event_trigger2;
drop event trigger if exists regress_event_trigger2;
NOTICE: event trigger "regress_event_trigger2" does not exist, skipping
NOTICE: event trigger "regress_event_trigger2" does not exist, skipping
drop event trigger regress_event_trigger3;
drop event trigger regress_event_trigger3;
drop event trigger regress_event_trigger_end;
drop function test_event_trigger();
drop function test_event_trigger();
drop role regression_bob;
drop role regression_bob;
src/test/regress/sql/event_trigger.sql
View file @
841a5150
...
@@ -18,6 +18,9 @@ create event trigger regress_event_trigger on elephant_bootstrap
...
@@ -18,6 +18,9 @@ create event trigger regress_event_trigger on elephant_bootstrap
create
event
trigger
regress_event_trigger
on
ddl_command_start
create
event
trigger
regress_event_trigger
on
ddl_command_start
execute
procedure
test_event_trigger
();
execute
procedure
test_event_trigger
();
create
event
trigger
regress_event_trigger_end
on
ddl_command_end
execute
procedure
test_event_trigger
();
-- should fail, food is not a valid filter variable
-- should fail, food is not a valid filter variable
create
event
trigger
regress_event_trigger2
on
ddl_command_start
create
event
trigger
regress_event_trigger2
on
ddl_command_start
when
food
in
(
'sandwhich'
)
when
food
in
(
'sandwhich'
)
...
@@ -96,5 +99,6 @@ drop role regression_bob;
...
@@ -96,5 +99,6 @@ drop role regression_bob;
drop
event
trigger
if
exists
regress_event_trigger2
;
drop
event
trigger
if
exists
regress_event_trigger2
;
drop
event
trigger
if
exists
regress_event_trigger2
;
drop
event
trigger
if
exists
regress_event_trigger2
;
drop
event
trigger
regress_event_trigger3
;
drop
event
trigger
regress_event_trigger3
;
drop
event
trigger
regress_event_trigger_end
;
drop
function
test_event_trigger
();
drop
function
test_event_trigger
();
drop
role
regression_bob
;
drop
role
regression_bob
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment